use of android.view.KeyCharacterMap in project android_frameworks_base by ParanoidAndroid.
the class PhoneWindowManager method interceptKeyBeforeDispatching.
/** {@inheritDoc} */
@Override
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final boolean longPress = (flags & KeyEvent.FLAG_LONG_PRESS) != 0;
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" + repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
}
// try again later before dispatching.
if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
final long now = SystemClock.uptimeMillis();
final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
if (now < timeoutTime) {
return timeoutTime - now;
}
}
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeDownKeyConsumedByScreenshotChord) {
if (!down) {
mVolumeDownKeyConsumedByScreenshotChord = false;
}
return -1;
}
}
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
// while it was pressed, then it is time to go home!
if (!down) {
final boolean homeWasLongPressed = mHomeLongPressed;
mHomeLongPressed = false;
if (!homeWasLongPressed) {
if (mRecentAppsPreloaded) {
cancelPreloadRecentApps();
}
if (!canceled) {
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.)
boolean incomingRinging = false;
try {
ITelephony telephonyService = getTelephonyService();
if (telephonyService != null) {
incomingRinging = telephonyService.isRinging();
}
} catch (RemoteException ex) {
Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
}
if (incomingRinging) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
} else {
launchHomeFromHotKey();
}
} else {
Log.i(TAG, "Ignoring HOME; event canceled.");
}
return -1;
}
}
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
if (type == WindowManager.LayoutParams.TYPE_KEYGUARD || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
// the "app" is keyguard, so give it the key
return 0;
}
final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for (int i = 0; i < typeCount; i++) {
if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
// don't do anything, but also don't pass it to the app
return -1;
}
}
}
if (down) {
if (!mRecentAppsPreloaded && mLongPressOnHomeBehavior == KEY_ACTION_APP_SWITCH) {
preloadRecentApps();
}
if (longPress) {
if (!keyguardOn && mLongPressOnHomeBehavior != KEY_ACTION_NOTHING) {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performKeyAction(mLongPressOnHomeBehavior);
// Eat the long-press so it won't take us home when the key is released
mHomeLongPressed = true;
}
}
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
if (down) {
if (!mRecentAppsPreloaded && (mPressOnMenuBehavior == KEY_ACTION_APP_SWITCH || mLongPressOnMenuBehavior == KEY_ACTION_APP_SWITCH)) {
preloadRecentApps();
}
if (repeatCount == 0) {
if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcast(intent, null);
return -1;
} else if (SHOW_PROCESSES_ON_ALT_MENU && (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
Intent service = new Intent();
service.setClassName(mContext, "com.android.server.LoadAverageService");
ContentResolver res = mContext.getContentResolver();
boolean shown = Settings.System.getInt(res, Settings.System.SHOW_PROCESSES, 0) != 0;
if (!shown) {
mContext.startService(service);
} else {
mContext.stopService(service);
}
Settings.System.putInt(res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
return -1;
} else if (mPressOnMenuBehavior != KEY_ACTION_MENU && !mIsVirtualKeypress) {
mMenuDoCustomAction = true;
return -1;
}
} else if (longPress) {
if (mRecentAppsPreloaded && mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (!keyguardOn && mLongPressOnMenuBehavior != KEY_ACTION_NOTHING) {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performKeyAction(mLongPressOnMenuBehavior);
// Do not perform action when key is released
mMenuDoCustomAction = false;
return -1;
}
}
} else {
if (mRecentAppsPreloaded && mPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (mMenuDoCustomAction) {
mMenuDoCustomAction = false;
if (!canceled && !keyguardOn) {
performKeyAction(mPressOnMenuBehavior);
return -1;
}
}
}
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (down) {
if (repeatCount == 0) {
mSearchKeyShortcutPending = true;
mConsumeSearchKeyUp = false;
}
} else {
mSearchKeyShortcutPending = false;
if (mConsumeSearchKeyUp) {
mConsumeSearchKeyUp = false;
return -1;
}
}
return 0;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
if (down) {
if (!mRecentAppsPreloaded && (mPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH || mLongPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH)) {
preloadRecentApps();
}
if (repeatCount == 0) {
mAppSwitchLongPressed = false;
} else if (longPress) {
if (mRecentAppsPreloaded && mLongPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (!keyguardOn && mLongPressOnAppSwitchBehavior != KEY_ACTION_NOTHING) {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performKeyAction(mLongPressOnAppSwitchBehavior);
mAppSwitchLongPressed = true;
}
}
} else {
if (mAppSwitchLongPressed) {
mAppSwitchLongPressed = false;
} else {
if (mRecentAppsPreloaded && mPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (!canceled && !keyguardOn) {
performKeyAction(mPressOnAppSwitchBehavior);
}
return -1;
}
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
if (down) {
if (!mRecentAppsPreloaded && (mPressOnAssistBehavior == KEY_ACTION_APP_SWITCH || mLongPressOnAssistBehavior == KEY_ACTION_APP_SWITCH)) {
preloadRecentApps();
}
if (repeatCount == 0) {
mAssistKeyLongPressed = false;
} else if (longPress) {
if (mRecentAppsPreloaded && mLongPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (!keyguardOn && mLongPressOnAssistBehavior != KEY_ACTION_NOTHING) {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performKeyAction(mLongPressOnAssistBehavior);
mAssistKeyLongPressed = true;
}
}
} else {
if (mAssistKeyLongPressed) {
mAssistKeyLongPressed = false;
} else {
if (mRecentAppsPreloaded && mPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
cancelPreloadRecentApps();
}
if (!keyguardOn) {
performKeyAction(mPressOnAssistBehavior);
}
}
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_SYSRQ) {
if (down && repeatCount == 0) {
mHandler.post(mScreenshotRunnable);
}
return -1;
}
// shortcut keys (that emit Search+x) and some of them are not registered.
if (mSearchKeyShortcutPending) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
if (kcm.isPrintingKey(keyCode)) {
mConsumeSearchKeyUp = true;
mSearchKeyShortcutPending = false;
if (down && repeatCount == 0 && !keyguardOn) {
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
if (shortcutIntent != null) {
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
mContext.startActivity(shortcutIntent);
} catch (ActivityNotFoundException ex) {
Slog.w(TAG, "Dropping shortcut key combination because " + "the activity to which it is registered was not found: " + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex);
}
} else {
Slog.i(TAG, "Dropping unregistered shortcut key combination: " + "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
}
}
return -1;
}
}
// Invoke shortcuts using Meta.
if (down && repeatCount == 0 && !keyguardOn && (metaState & KeyEvent.META_META_ON) != 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
if (kcm.isPrintingKey(keyCode)) {
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState & ~(KeyEvent.META_META_ON | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
if (shortcutIntent != null) {
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
mContext.startActivity(shortcutIntent);
} catch (ActivityNotFoundException ex) {
Slog.w(TAG, "Dropping shortcut key combination because " + "the activity to which it is registered was not found: " + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
}
return -1;
}
}
}
// Handle application launch keys.
if (down && repeatCount == 0 && !keyguardOn) {
String category = sApplicationLaunchKeyCategories.get(keyCode);
if (category != null) {
Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
mContext.startActivity(intent);
} catch (ActivityNotFoundException ex) {
Slog.w(TAG, "Dropping application launch key because " + "the activity to which it is registered was not found: " + "keyCode=" + keyCode + ", category=" + category, ex);
}
return -1;
}
}
// Display task switcher for ALT-TAB or Meta-TAB.
if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
if (mRecentAppsDialogHeldModifiers == 0 && !keyguardOn) {
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON) || KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_META_ON)) {
mRecentAppsDialogHeldModifiers = shiftlessModifiers;
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
return -1;
}
}
} else if (!down && mRecentAppsDialogHeldModifiers != 0 && (metaState & mRecentAppsDialogHeldModifiers) == 0) {
mRecentAppsDialogHeldModifiers = 0;
showOrHideRecentAppsDialog(keyguardOn ? RECENT_APPS_BEHAVIOR_DISMISS : RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
}
// Handle keyboard language switching.
if (down && repeatCount == 0 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH || (keyCode == KeyEvent.KEYCODE_SPACE && (metaState & KeyEvent.META_CTRL_MASK) != 0))) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
return -1;
}
if (mLanguageSwitchKeyPressed && !down && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH || keyCode == KeyEvent.KEYCODE_SPACE)) {
mLanguageSwitchKeyPressed = false;
return -1;
}
if (mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
return -1;
}
// Let the application handle the key.
return 0;
}
use of android.view.KeyCharacterMap in project android_frameworks_base by ParanoidAndroid.
the class PhoneWindowManager method dispatchUnhandledKey.
/** {@inheritDoc} */
@Override
public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
// Note: This method is only called if the initial down was unhandled.
if (DEBUG_INPUT) {
Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction() + ", flags=" + event.getFlags() + ", keyCode=" + event.getKeyCode() + ", scanCode=" + event.getScanCode() + ", metaState=" + event.getMetaState() + ", repeatCount=" + event.getRepeatCount() + ", policyFlags=" + policyFlags);
}
KeyEvent fallbackEvent = null;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
final int keyCode = event.getKeyCode();
final int metaState = event.getMetaState();
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0;
// Check for fallback actions specified by the key character map.
final FallbackAction fallbackAction;
if (initialDown) {
fallbackAction = kcm.getFallbackAction(keyCode, metaState);
} else {
fallbackAction = mFallbackActions.get(keyCode);
}
if (fallbackAction != null) {
if (DEBUG_INPUT) {
Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode + " metaState=" + Integer.toHexString(fallbackAction.metaState));
}
final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
fallbackEvent = KeyEvent.obtain(event.getDownTime(), event.getEventTime(), event.getAction(), fallbackAction.keyCode, event.getRepeatCount(), fallbackAction.metaState, event.getDeviceId(), event.getScanCode(), flags, event.getSource(), null);
if (!interceptFallback(win, fallbackEvent, policyFlags)) {
fallbackEvent.recycle();
fallbackEvent = null;
}
if (initialDown) {
mFallbackActions.put(keyCode, fallbackAction);
} else if (event.getAction() == KeyEvent.ACTION_UP) {
mFallbackActions.remove(keyCode);
fallbackAction.recycle();
}
}
}
if (DEBUG_INPUT) {
if (fallbackEvent == null) {
Slog.d(TAG, "No fallback.");
} else {
Slog.d(TAG, "Performing fallback: " + fallbackEvent);
}
}
return fallbackEvent;
}
use of android.view.KeyCharacterMap in project android_frameworks_base by ParanoidAndroid.
the class Input method sendText.
/**
* Convert the characters of string text into key event's and send to
* device.
*
* @param text is a string of characters you want to input to the device.
*/
private void sendText(String text) {
StringBuffer buff = new StringBuffer(text);
boolean escapeFlag = false;
for (int i = 0; i < buff.length(); i++) {
if (escapeFlag) {
escapeFlag = false;
if (buff.charAt(i) == 's') {
buff.setCharAt(i, ' ');
buff.deleteCharAt(--i);
}
}
if (buff.charAt(i) == '%') {
escapeFlag = true;
}
}
char[] chars = buff.toString().toCharArray();
KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
KeyEvent[] events = kcm.getEvents(chars);
for (int i = 0; i < events.length; i++) {
injectKeyEvent(events[i]);
}
}
use of android.view.KeyCharacterMap in project android_frameworks_base by ParanoidAndroid.
the class KeyUtils method chordMenuKey.
/**
* Simulates chording the menu key.
*
* @param test The test case that is being run.
* @param shortcutKey The shortcut key to tap while chording the menu key.
*/
public static void chordMenuKey(ActivityInstrumentationTestCase test, char shortcutKey) {
final Instrumentation inst = test.getInstrumentation();
final KeyEvent pushMenuKey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
final KeyCharacterMap keyCharMap = KeyCharacterMap.load(pushMenuKey.getDeviceId());
final KeyEvent shortcutKeyEvent = keyCharMap.getEvents(new char[] { shortcutKey })[0];
final int shortcutKeyCode = shortcutKeyEvent.getKeyCode();
inst.sendKeySync(pushMenuKey);
inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, shortcutKeyCode));
inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, shortcutKeyCode));
inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));
}
use of android.view.KeyCharacterMap in project AndroidTraining by mixi-inc.
the class ActionBarSherlockCompat method preparePanel.
///////////////////////////////////////////////////////////////////////////
// Menu callback lifecycle and creation
///////////////////////////////////////////////////////////////////////////
private boolean preparePanel() {
// Already prepared (isPrepared will be reset to false later)
if (mMenuIsPrepared) {
return true;
}
// Init the panel state's menu--return false if init failed
if (mMenu == null || mMenuRefreshContent) {
if (mMenu == null) {
if (!initializePanelMenu() || (mMenu == null)) {
return false;
}
}
if (wActionBar != null) {
wActionBar.setMenu(mMenu, this);
}
// Call callback, and return if it doesn't want to display menu.
// Creating the panel menu will involve a lot of manipulation;
// don't dispatch change events to presenters until we're done.
mMenu.stopDispatchingItemsChanged();
if (!callbackCreateOptionsMenu(mMenu)) {
// Ditch the menu created above
mMenu = null;
if (wActionBar != null) {
// Don't show it in the action bar either
wActionBar.setMenu(null, this);
}
return false;
}
mMenuRefreshContent = false;
}
// Callback and return if the callback does not want to show the menu
// Preparing the panel menu can involve a lot of manipulation;
// don't dispatch change events to presenters until we're done.
mMenu.stopDispatchingItemsChanged();
// an opportunity to override frozen/restored state in onPrepare.
if (mMenuFrozenActionViewState != null) {
mMenu.restoreActionViewStates(mMenuFrozenActionViewState);
mMenuFrozenActionViewState = null;
}
if (!callbackPrepareOptionsMenu(mMenu)) {
if (wActionBar != null) {
// The app didn't want to show the menu for now but it still exists.
// Clear it out of the action bar.
wActionBar.setMenu(null, this);
}
mMenu.startDispatchingItemsChanged();
return false;
}
// Set the proper keymap
KeyCharacterMap kmap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
mMenu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
mMenu.startDispatchingItemsChanged();
// Set other state
mMenuIsPrepared = true;
return true;
}
Aggregations