private boolean processKey(int keyCode, KeyEvent event, boolean down) { if (GamepadUtils.isSonyXperiaGamepadKeyEvent(event)) { event = GamepadUtils.translateSonyXperiaGamepadKeys(keyCode, event); keyCode = event.getKeyCode(); } if (keyCode > KeyEvent.getMaxKeyCode() || !shouldProcessKey(keyCode, event)) { return false; } event = translateKey(keyCode, event); keyCode = event.getKeyCode(); View view = getView(); if (view == null) { InputThreadUtils.sInstance.sendEventFromUiThread( ThreadUtils.getUiHandler(), mEditableClient, GoannaEvent.createKeyEvent(event, 0)); return true; } // KeyListener returns true if it handled the event for us. KeyListener is only // safe to use on the UI thread; therefore we need to pass a proxy Editable to it KeyListener keyListener = TextKeyListener.getInstance(); Handler uiHandler = view.getRootView().getHandler(); Editable uiEditable = InputThreadUtils.sInstance.getEditableForUiThread(uiHandler, mEditableClient); boolean skip = shouldSkipKeyListener(keyCode, event); if (down) { mEditableClient.setSuppressKeyUp(true); } if (skip || (down && !keyListener.onKeyDown(view, uiEditable, keyCode, event)) || (!down && !keyListener.onKeyUp(view, uiEditable, keyCode, event))) { InputThreadUtils.sInstance.sendEventFromUiThread( uiHandler, mEditableClient, GoannaEvent.createKeyEvent(event, TextKeyListener.getMetaState(uiEditable))); if (skip && down) { // Usually, the down key listener call above adjusts meta states for us. // However, if we skip that call above, we have to manually adjust meta // states so the meta states remain consistent TextKeyListener.adjustMetaAfterKeypress(uiEditable); } } if (down) { mEditableClient.setSuppressKeyUp(false); } return true; }
private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) { if (DEBUG) { Log.d( LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", " + isPreIme + ")"); } switch (keyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_SEARCH: case KeyEvent.KEYCODE_MENU: return false; default: break; } if (isPreIme && mIMEState != IME_STATE_DISABLED && (event.getMetaState() & KeyEvent.META_ALT_ON) != 0) // Let active IME process pre-IME key events return false; View view = GeckoApp.mAppContext.getLayerController().getView(); KeyListener keyListener = TextKeyListener.getInstance(); if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DEL || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || !keyListener.onKeyUp(view, mEditable, keyCode, event)) { GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event)); } return true; }
public void handleKeyboardType(int type, boolean autocorrect) { // Switched the keyboard handler to use the inputType rather than the rawInputType // This is kinda brute-force but more effective for most use-cases switch (type) { case KEYBOARD_ASCII: tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); break; case KEYBOARD_NUMBERS_PUNCTUATION: tv.setInputType(InputType.TYPE_CLASS_NUMBER); // tv.setKeyListener(DigitsKeyListener.getInstance()); break; case KEYBOARD_URL: Log.i(LCAT, "Setting keyboard type URL-3"); // tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setImeOptions(EditorInfo.IME_ACTION_GO); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); break; case KEYBOARD_NUMBER_PAD: tv.setKeyListener(DigitsKeyListener.getInstance(true, true)); // tv.setRawInputType(InputType.TYPE_CLASS_NUMBER); tv.setInputType(InputType.TYPE_CLASS_NUMBER); break; case KEYBOARD_PHONE_PAD: tv.setKeyListener(DialerKeyListener.getInstance()); // tv.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_PHONE); tv.setInputType(InputType.TYPE_CLASS_PHONE); break; case KEYBOARD_EMAIL_ADDRESS: // tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); break; case KEYBOARD_DEFAULT: tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); break; case KEYBOARD_PASSWORD: tv.setKeyListener(TextKeyListener.getInstance(false, Capitalize.NONE)); // tv.setRawInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); break; } }
private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) { if (DEBUG) { Log.d( LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", " + isPreIme + ")"); } clampSelection(); switch (keyCode) { case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_SEARCH: return false; case KeyEvent.KEYCODE_DEL: // See comments in GeckoInputConnection.onKeyDel if (onKeyDel()) { return true; } break; case KeyEvent.KEYCODE_ENTER: if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 && mIMEActionHint.equalsIgnoreCase("next")) event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB); break; default: break; } if (isPreIme && mIMEState != IME_STATE_DISABLED && (event.getMetaState() & KeyEvent.META_ALT_ON) != 0) // Let active IME process pre-IME key events return false; View view = GeckoApp.mAppContext.getLayerController().getView(); KeyListener keyListener = TextKeyListener.getInstance(); // KeyListener returns true if it handled the event for us. if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_TAB || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || !keyListener.onKeyDown(view, mEditable, keyCode, event)) { // Make sure selection in Gecko is up-to-date final Editable content = getEditable(); int a = Selection.getSelectionStart(content); int b = Selection.getSelectionEnd(content); GeckoAppShell.sendEventToGecko( GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, a, b - a)); GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event)); } return true; }
public PasswordUnlockScreen( Context context, Configuration configuration, LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback) { super(context); mCreationHardKeyboardHidden = configuration.hardKeyboardHidden; mCreationOrientation = configuration.orientation; mUpdateMonitor = updateMonitor; mCallback = callback; mLockPatternUtils = lockPatternUtils; LayoutInflater layoutInflater = LayoutInflater.from(context); if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { layoutInflater.inflate(R.layout.keyguard_screen_password_portrait, this, true); } else { layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true); } LockScreen.setBackground(context, (ViewGroup) findViewById(R.id.root)); mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils, mCallback, true); final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality; mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); mPasswordEntry = (EditText) findViewById(R.id.passwordEntry); mPasswordEntry.setOnEditorActionListener(this); mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false); mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled()); boolean imeOrDeleteButtonVisible = false; if (mIsAlpha) { // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); mKeyboardView.setVisibility(View.GONE); } else { // Use lockscreen's numeric keyboard if the physical keyboard isn't showing mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); mKeyboardView.setVisibility( mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO ? View.INVISIBLE : View.VISIBLE); // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts, // not a separate view View pinDelete = findViewById(R.id.pinDel); if (pinDelete != null) { pinDelete.setVisibility(View.VISIBLE); imeOrDeleteButtonVisible = true; pinDelete.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { mKeyboardHelper.handleBackspace(); } }); } } mPasswordEntry.requestFocus(); // This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys. if (mIsAlpha) { mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); mPasswordEntry.setInputType( InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); // mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_password_code, // KeyguardStatusViewManager.LOCK_ICON); } else { mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); mPasswordEntry.setInputType( InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD); // mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_pin_code, // KeyguardStatusViewManager.LOCK_ICON); } // Poke the wakelock any time the text is selected or modified mPasswordEntry.setOnClickListener( new OnClickListener() { public void onClick(View v) { mCallback.pokeWakelock(); } }); mQuickUnlock = (Settings.System.getInt( mContext.getContentResolver(), Settings.System.LOCKSCREEN_QUICK_UNLOCK_CONTROL, 0) == 1); mPasswordEntry.addTextChangedListener( new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void afterTextChanged(Editable s) { if (!mResuming) { mCallback.pokeWakelock(); } if (mQuickUnlock) { String entry = mPasswordEntry.getText().toString(); if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT && mLockPatternUtils.checkPassword(entry)) { mCallback.keyguardDone(true); mCallback.reportSuccessfulUnlockAttempt(); KeyStore.getInstance().password(entry); } } } }); // If there's more than one IME, enable the IME switcher button View switchImeButton = findViewById(R.id.switch_ime_button); final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) { switchImeButton.setVisibility(View.VISIBLE); imeOrDeleteButtonVisible = true; switchImeButton.setOnClickListener( new OnClickListener() { public void onClick(View v) { mCallback.pokeWakelock(); // Leave the screen on a bit longer imm.showInputMethodPicker(); } }); } // If no icon is visible, reset the left margin on the password field so the text is // still centered. if (!imeOrDeleteButtonVisible) { android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams(); if (params instanceof MarginLayoutParams) { ((MarginLayoutParams) params).leftMargin = 0; mPasswordEntry.setLayoutParams(params); } } }
@Override public void processProperties(TiDict d) { super.processProperties(d); if (d.containsKey("enabled")) { tv.setEnabled(d.getBoolean("enabled")); } if (d.containsKey("value")) { tv.setText(d.getString("value")); } if (d.containsKey("color")) { tv.setTextColor(TiConvert.toColor(d, "color")); } if (d.containsKey("hintText")) { tv.setHint(d.getString("hintText")); } if (d.containsKey("font")) { TiUIHelper.styleText(tv, d.getTiDict("font")); } if (d.containsKey("textAlign") || d.containsKey("verticalAlign")) { String textAlign = null; String verticalAlign = null; if (d.containsKey("textAlign")) { textAlign = d.getString("textAlign"); } if (d.containsKey("verticalAlign")) { verticalAlign = d.getString("verticalAlign"); } handleTextAlign(textAlign, verticalAlign); } if (d.containsKey("returnKeyType")) { handleReturnKeyType(d.getInt("returnKeyType")); } if (d.containsKey("keyboardType")) { boolean autocorrect = true; if (d.containsKey("autocorrect")) { autocorrect = d.getBoolean("autocorrect"); } handleKeyboardType(d.getInt("keyboardType"), autocorrect); } if (d.containsKey("autocapitalization")) { Capitalize autoCapValue = null; switch (d.getInt("autocapitalization")) { case TEXT_AUTOCAPITALIZATION_NONE: autoCapValue = Capitalize.NONE; break; case TEXT_AUTOCAPITALIZATION_ALL: autoCapValue = Capitalize.CHARACTERS; break; case TEXT_AUTOCAPITALIZATION_SENTENCES: autoCapValue = Capitalize.SENTENCES; break; case TEXT_AUTOCAPITALIZATION_WORDS: autoCapValue = Capitalize.WORDS; break; default: Log.w( LCAT, "Unknown AutoCapitalization Value [" + d.getString("autocapitalization") + "]"); break; } if (null != autoCapValue) { tv.setKeyListener(TextKeyListener.getInstance(false, autoCapValue)); } } if (d.containsKey("passwordMask")) { if (TiConvert.toBoolean(d.get("passwordMask"))) { // This shouldn't be needed but it's belts & braces tv.setKeyListener(TextKeyListener.getInstance(false, Capitalize.NONE)); // Both setTransform & keyboard type are required tv.setTransformationMethod(PasswordTransformationMethod.getInstance()); // We also need to set the keyboard type - otherwise the password mask won't be applied handleKeyboardType(KEYBOARD_PASSWORD, false); } } }
@Override public void propertyChanged(String key, Object oldValue, Object newValue, TiProxy proxy) { if (DBG) { Log.d(LCAT, "Property: " + key + " old: " + oldValue + " new: " + newValue); } if (key.equals("enabled")) { tv.setEnabled(TiConvert.toBoolean(newValue)); } else if (key.equals("value")) { tv.setText((String) newValue); } else if (key.equals("color")) { tv.setTextColor(TiConvert.toColor((String) newValue)); } else if (key.equals("passwordMask")) { if (TiConvert.toBoolean(newValue) == true) { // This shouldn't be needed but it's belts & braces tv.setKeyListener(TextKeyListener.getInstance(false, Capitalize.NONE)); // Both setTransform & keyboard type are required tv.setTransformationMethod(PasswordTransformationMethod.getInstance()); // We also need to set the keyboard type - otherwise the password mask won't be applied handleKeyboardType(KEYBOARD_PASSWORD, false); } else { handleKeyboardType(KEYBOARD_DEFAULT, false); } } else if (key.equals("hintText")) { tv.setHint((String) newValue); } else if (key.equals("textAlign") || key.equals("verticalAlign")) { String textAlign = null; String verticalAlign = null; if (key.equals("textAlign")) { textAlign = TiConvert.toString(newValue); } if (key.equals("verticalAlign")) { verticalAlign = TiConvert.toString(newValue); } handleTextAlign(textAlign, verticalAlign); } else if (key.equals("autocapitalization")) { // TODO Missing Capitalize autoCapValue = null; switch (TiConvert.toInt(newValue)) { case TEXT_AUTOCAPITALIZATION_NONE: autoCapValue = Capitalize.NONE; break; case TEXT_AUTOCAPITALIZATION_ALL: autoCapValue = Capitalize.CHARACTERS; break; case TEXT_AUTOCAPITALIZATION_SENTENCES: autoCapValue = Capitalize.SENTENCES; break; case TEXT_AUTOCAPITALIZATION_WORDS: autoCapValue = Capitalize.WORDS; break; default: Log.w(LCAT, "Unknown AutoCapitalization Value [" + TiConvert.toString(newValue) + "]"); break; } if (null != autoCapValue) { tv.setKeyListener(TextKeyListener.getInstance(false, autoCapValue)); } } else if (key.equals("keyboardType") || (key.equals("autocorrect"))) { TiDict d = proxy.getDynamicProperties(); boolean autocorrect = false; if (d.containsKey("autocorrect")) { autocorrect = d.getBoolean("autocorrect"); } handleKeyboardType(TiConvert.toInt(d, "keyboardType"), autocorrect); } else if (key.equals("returnKeyType")) { handleReturnKeyType(TiConvert.toInt(newValue)); } else if (key.equals("font")) { TiUIHelper.styleText(tv, (TiDict) newValue); } else { super.propertyChanged(key, oldValue, newValue, proxy); } }