Skip to content

Commit

Permalink
- add support for bb keyboard
Browse files Browse the repository at this point in the history
  • Loading branch information
vanhoavn committed Jun 1, 2020
1 parent ec6f3eb commit 15386c0
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 14 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/vn/vhn/vhscode/CodeServerService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class CodeServerService : Service() {
},100);
}
});
})()
})();
""".trimIndent() + String(data)
}
}
Expand Down
42 changes: 30 additions & 12 deletions app/src/main/java/vn/vhn/vhscode/VSCodeActivity.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
package vn.vhn.vhscode

import android.annotation.SuppressLint
import android.graphics.Color
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.Window
import android.view.*
import android.webkit.JavascriptInterface
import android.webkit.WebView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_vscode.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import vn.vhn.vhscode.chromebrowser.webclient.VSCodeWebChromeClient
import vn.vhn.vhscode.chromebrowser.webclient.VSCodeWebClient
import vn.vhn.vhscode.generic_dispatcher.BBKeyboardEventDispatcher
import vn.vhn.vhscode.generic_dispatcher.IGenericEventDispatcher

class VSCodeActivity : AppCompatActivity() {
companion object {
val kConfigUseHardKeyboard = "use_hardkb";
val kConfigUrl = "url";
val TAG = "VSCodeActivity"
}

class WebInterface {
}

var useHardKeyboard = false
var genericMotionEventDispatcher: IGenericEventDispatcher? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -34,7 +39,13 @@ class VSCodeActivity : AppCompatActivity() {
setContentView(R.layout.activity_vscode)
configureWebView(webView)
CoroutineScope(Dispatchers.Main).launch {

Log.d(TAG, "Started on model ${android.os.Build.MODEL}")
}
if (android.os.Build.MODEL.matches(Regex("BB[FB]100-[0-9]+"))) { //Key1,2
genericMotionEventDispatcher = BBKeyboardEventDispatcher()
}
if (genericMotionEventDispatcher != null) {
genericMotionEventDispatcher!!.initializeForTarget(this, webView)
}
}

Expand Down Expand Up @@ -62,13 +73,20 @@ class VSCodeActivity : AppCompatActivity() {
webView.loadUrl(url)
}

override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if (webView.dispatchKeyEvent(event)) return true
return super.dispatchKeyEvent(event)
override fun dispatchKeyEvent(ev: KeyEvent?): Boolean {
if (genericMotionEventDispatcher != null && ev != null) {
if (genericMotionEventDispatcher!!.dispatchKeyEvent(ev!!))
return true
}
if (webView.dispatchKeyEvent(ev)) return true
return super.dispatchKeyEvent(ev)
}

override fun onTouchEvent(event: MotionEvent?): Boolean {
if (webView.onTouchEvent(event)) return true
return super.onTouchEvent(event)
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
if (genericMotionEventDispatcher != null && ev != null) {
if (genericMotionEventDispatcher!!.dispatchGenericMotionEvent(ev!!))
return true
}
return super.dispatchGenericMotionEvent(ev)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package vn.vhn.vhscode.generic_dispatcher

import android.app.Activity
import android.content.Context
import android.os.SystemClock
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.BaseInputConnection
import android.view.inputmethod.InputMethodManager
import android.webkit.WebView
import androidx.core.content.ContextCompat.getSystemService


class BBKeyboardEventDispatcher : IGenericEventDispatcher {
companion object {
val TAG = "BBKeyboardEventDispatcher"
private val KEYBOARD_WIDTH = 1080.0
private val KEYBOARD_HEIGHT = 525.0
private val KB_BTN_WIDTH = KEYBOARD_WIDTH / 10.0
private val KB_BTN_HEIGHT = KEYBOARD_HEIGHT / 4.0

private const val LEFT_MODIFICATION_OFFSET = 80.0
private const val TOP_LEFT_SLIDE_START = 80.0
private const val BOTTOM_LEFT_SLIDE_END = 200.0

}

var mContext: Context? = null
var mWebView: WebView? = null
var mInputConnection: BaseInputConnection? = null

var mAccumulateX = 0.0
var mAccumulateY = 0.0

private enum class SpecialHandlingState {
STATE_NONE,
STATE_FIRST_TAP,
STATE_ENABLED
}

private var mHandlingState: SpecialHandlingState = SpecialHandlingState.STATE_NONE
private var mFirstTapDeadline: Long = 0
private var mMeta: Int = 0

override fun initializeForTarget(ctx: Context, webView: WebView) {
this.mContext = ctx
this.mWebView = webView
this.mInputConnection = BaseInputConnection(webView, true)
}

private fun setHandlingState(newState: SpecialHandlingState, ev: MotionEvent) {
if (newState == SpecialHandlingState.STATE_FIRST_TAP) {
mFirstTapDeadline = ev.eventTime + 600
}
if (newState != mHandlingState) {
Log.d(TAG, "change state " + mHandlingState + " -> " + newState)
mHandlingState = newState
}
}

override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
return false
}

override fun dispatchGenericMotionEvent(ev: MotionEvent): Boolean {
if (this.mInputConnection == null) return false
if (mHandlingState == SpecialHandlingState.STATE_FIRST_TAP && (
ev.eventTime > mFirstTapDeadline
|| ev.action == MotionEvent.ACTION_DOWN)
) {
setHandlingState(SpecialHandlingState.STATE_NONE, ev)
}
// Log.d(TAG, "ev: " + mHandlingState + " ; " + ev.toString());
when (mHandlingState) {
SpecialHandlingState.STATE_NONE ->
if (ev.action == MotionEvent.ACTION_DOWN && ev.pointerCount == 1
&& ev.getX() < LEFT_MODIFICATION_OFFSET
&& ev.getY() < TOP_LEFT_SLIDE_START
) {
setHandlingState(SpecialHandlingState.STATE_FIRST_TAP, ev)
}
SpecialHandlingState.STATE_FIRST_TAP ->
if (ev.action == MotionEvent.ACTION_MOVE && ev.pointerCount == 1
&& ev.getX() < LEFT_MODIFICATION_OFFSET
&& ev.getY() > BOTTOM_LEFT_SLIDE_END
) {
setHandlingState(SpecialHandlingState.STATE_ENABLED, ev)
} else if (ev.action == MotionEvent.ACTION_UP) {
setHandlingState(SpecialHandlingState.STATE_NONE, ev)
}
SpecialHandlingState.STATE_ENABLED ->
when (true) {
ev.action == MotionEvent.ACTION_UP && ev.pointerCount == 1 ->
setHandlingState(SpecialHandlingState.STATE_NONE, ev)
ev.action == MotionEvent.ACTION_MOVE && ev.pointerCount > 1 && ev.historySize > 0 -> {
var dx = 0.0
var dy = 0.0
for (pointerId in 0 until ev.pointerCount) {
dx += ev.getX(pointerId) - ev.getHistoricalX(pointerId, 0)
dy += ev.getY(pointerId) - ev.getHistoricalY(pointerId, 0)
}
if (Math.abs(dx) > Math.abs(dy)) {
var minY = ev.getY(0)
for (pointerId in 1 until ev.pointerCount) {
minY = Math.min(minY, ev.getY(pointerId))
}
val speedMultiplier = (Math.max(minY / KEYBOARD_HEIGHT * 8, 1.0))
mAccumulateY = 0.0
mAccumulateX += dx * speedMultiplier
val nSteps = (mAccumulateX / KB_BTN_WIDTH).toInt()
if (nSteps != 0) {
if (nSteps > 0) {
for (i in 1..nSteps) sendDownUpKeyEvent(
KeyEvent.KEYCODE_DPAD_RIGHT,
mMeta
)
} else {
for (i in 1..-nSteps) sendDownUpKeyEvent(
KeyEvent.KEYCODE_DPAD_LEFT,
mMeta
)
}
mAccumulateX = 0.0
}
} else {
var maxX = ev.getX(0)
for (pointerId in 1 until ev.pointerCount) {
maxX = Math.max(maxX, ev.getX(pointerId))
}
val speedMultiplier =
(.5 * (1.0 + Math.max(0.0, maxX - KEYBOARD_WIDTH / 3)
/ KEYBOARD_WIDTH * 12))
mAccumulateX = 0.0
mAccumulateY += dy * speedMultiplier
val nSteps = (mAccumulateY / KB_BTN_HEIGHT).toInt()
if (nSteps != 0) {
if (nSteps > 0) {
for (i in 1..nSteps) sendDownUpKeyEvent(
KeyEvent.KEYCODE_DPAD_DOWN,
mMeta
)
} else {
for (i in 1..-nSteps) sendDownUpKeyEvent(
KeyEvent.KEYCODE_DPAD_UP,
mMeta
)
}
mAccumulateY = 0.0
}
}
}
}
}

return true
}

private fun sendDownUpKeyEvent(keyCode: Int, metaState: Int) {
if (this.mInputConnection != null) {
val eventTime = SystemClock.uptimeMillis()
this.mInputConnection!!.sendKeyEvent(
KeyEvent(eventTime, eventTime, 0, keyCode, 0, metaState, -1, 0, 6)
)
this.mInputConnection!!.sendKeyEvent(
KeyEvent(SystemClock.uptimeMillis(), eventTime, 1, keyCode, 0, metaState, -1, 0, 6)
)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package vn.vhn.vhscode.generic_dispatcher

import android.content.Context
import android.view.KeyEvent
import android.view.MotionEvent
import android.webkit.WebView

interface IGenericEventDispatcher {
fun initializeForTarget(ctx: Context, webView: WebView)

fun dispatchKeyEvent(ev: KeyEvent): Boolean
fun dispatchGenericMotionEvent(ev: MotionEvent): Boolean
}
3 changes: 2 additions & 1 deletion app/src/main/res/raw/vsboot.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
if(this._vscode_modded) return;
this._vscode_modded = true;
var orig = codeGetter.apply(this);
console.log(this, orig);
if (this.key == 'Alt') {
this._vscodeCode = "";
} else if (this.key === 'Shift') {
this._vscodeCode = "ShiftLeft";
} else if (this.which in customMapper) {
this._vscodeCode = customMapper[this.which];
} else if (orig === "" && typeof this.key === "string" && this.key.length) {
Expand Down

0 comments on commit 15386c0

Please sign in to comment.