summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-12-06 17:13:33 -0800
committerJeff Brown <jeffbrown@google.com>2010-12-07 17:35:26 -0800
commit49ed71db425c5054e3ad9526496a7e116c89556b (patch)
tree3d3b28bdaf76d5cc531fd3b52fcbb0efb32a05ba /policy
parentf30c8287525ac049d4d7589a330be5713256046b (diff)
downloadframeworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.zip
frameworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.tar.gz
frameworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.tar.bz2
Add support for fallback keycodes.
This change enables the framework to synthesize key events to implement default behavior when an application does not handle a key. For example, this change enables numeric keypad keys to perform their associated special function when numlock is off. The application is informed that it is processing a fallback keypress so it can choose to ignore it. Added a new keycode for switching applications. Added ALT key deadkeys. New default key mappings: - ESC -> BACK - Meta+ESC -> HOME - Alt+ESC -> MENU - Meta+Space -> SEARCH - Meta+Tab -> APP_SWITCH Fixed some comments. Fixed some tests. Change-Id: Id7f3b6645f3a350275e624547822f72652f3defe
Diffstat (limited to 'policy')
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java145
1 files changed, 90 insertions, 55 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c3112d8..e61dd6c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -133,6 +133,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final boolean DEBUG = false;
static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
static final boolean DEBUG_LAYOUT = false;
+ static final boolean DEBUG_FALLBACK = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
@@ -315,8 +316,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Intent mHomeIntent;
Intent mCarDockIntent;
Intent mDeskDockIntent;
- boolean mSearchKeyPressed;
- boolean mConsumeSearchKeyUp;
+ int mShortcutKeyPressed = -1;
+ boolean mConsumeShortcutKeyUp;
boolean mShowMenuKey = false; // track FLAG_NEEDS_MENU_KEY on frontmost window
// support for activating the lock screen while the screen is on
@@ -345,6 +346,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
+ final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
+
class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
@@ -1228,56 +1231,44 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
}
- // Clear a pending HOME longpress if the user releases Home
- // TODO: This could probably be inside the next bit of logic, but that code
- // turned out to be a bit fragile so I'm doing it here explicitly, for now.
- if ((keyCode == KeyEvent.KEYCODE_HOME) && !down) {
- mHandler.removeCallbacks(mHomeLongPress);
- }
+ // First we always handle the home key here, so applications
+ // can never break it, although if keyguard is on, we do let
+ // it handle it, because that gives us the correct 5 second
+ // timeout.
+ if (keyCode == KeyEvent.KEYCODE_HOME) {
+ // Clear a pending HOME longpress if the user releases Home
+ if (!down) {
+ mHandler.removeCallbacks(mHomeLongPress);
+ }
- // If the HOME button is currently being held, then we do special
- // chording with it.
- if (mHomePressed) {
-
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
- if (keyCode == KeyEvent.KEYCODE_HOME) {
- if (!down) {
- mHomePressed = false;
-
- 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();
+ if (mHomePressed && !down) {
+ mHomePressed = false;
+ 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 {
- Log.i(TAG, "Ignoring HOME; event canceled.");
+ launchHomeFromHotKey();
}
+ } else {
+ Log.i(TAG, "Ignoring HOME; event canceled.");
}
+ return true;
}
-
- return true;
- }
-
- // First we always handle the home key here, so applications
- // can never break it, although if keyguard is on, we do let
- // it handle it, because that gives us the correct 5 second
- // timeout.
- if (keyCode == KeyEvent.KEYCODE_HOME) {
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
@@ -1334,21 +1325,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (down) {
if (repeatCount == 0) {
- mSearchKeyPressed = true;
+ mShortcutKeyPressed = keyCode;
+ mConsumeShortcutKeyUp = false;
}
- } else {
- mSearchKeyPressed = false;
+ } else if (keyCode == mShortcutKeyPressed) {
+ mShortcutKeyPressed = -1;
- if (mConsumeSearchKeyUp) {
+ if (mConsumeShortcutKeyUp) {
// Consume the up-event
- mConsumeSearchKeyUp = false;
+ mConsumeShortcutKeyUp = false;
return true;
}
}
+ } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
+ if (!down) {
+ showRecentAppsDialog();
+ }
+ return true;
}
- // Shortcuts are invoked through Search+key, so intercept those here
- if (mSearchKeyPressed) {
+ // Shortcuts are invoked through Search+key or Meta+key, so intercept those here
+ if ((mShortcutKeyPressed != -1 && !mConsumeShortcutKeyUp)
+ || (metaState & KeyEvent.META_META_ON) != 0) {
if (down && repeatCount == 0 && !keyguardOn) {
Intent shortcutIntent = mShortcutManager.getIntent(event);
if (shortcutIntent != null) {
@@ -1359,7 +1357,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* We launched an app, so the up-event of the search key
* should be consumed
*/
- mConsumeSearchKeyUp = true;
+ if (mShortcutKeyPressed != -1) {
+ mConsumeShortcutKeyUp = true;
+ }
return true;
}
}
@@ -1370,8 +1370,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
@Override
- public boolean dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
- if (false) {
+ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
+ if (DEBUG_FALLBACK) {
Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
+ ", flags=" + event.getFlags()
+ ", keyCode=" + event.getKeyCode()
@@ -1380,7 +1380,42 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ ", repeatCount=" + event.getRepeatCount()
+ ", policyFlags=" + policyFlags);
}
- return false;
+
+ if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ final KeyCharacterMap kcm = event.getKeyCharacterMap();
+ boolean fallback = kcm.getFallbackAction(event.getKeyCode(), event.getMetaState(),
+ mFallbackAction);
+
+ if (fallback) {
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
+ + " metaState=" + Integer.toHexString(mFallbackAction.metaState));
+ }
+
+ int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+ KeyEvent fallbackEvent = KeyEvent.obtain(
+ event.getDownTime(), event.getEventTime(),
+ event.getAction(), mFallbackAction.keyCode,
+ event.getRepeatCount(), mFallbackAction.metaState,
+ event.getDeviceId(), event.getScanCode(),
+ flags, event.getSource(), null);
+ int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
+ if ((actions & ACTION_PASS_TO_USER) != 0) {
+ if (!interceptKeyBeforeDispatching(win, fallbackEvent, policyFlags)) {
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "Performing fallback.");
+ }
+ return fallbackEvent;
+ }
+ }
+ fallbackEvent.recycle();
+ }
+ }
+
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "No fallback.");
+ }
+ return null;
}
/**