Follow key event API changes.
We now use the new tracking and long press dispatching in the framework
to greatly simplify this code.
Change-Id: I4c0ed51dc2d07ed3bb20c64c67eede83bdb123b9
diff --git a/policy/com/android/internal/policy/impl/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java
index 72dec29..fac4182 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindow.java
@@ -124,6 +124,7 @@
* this is 0, there is no key held down.
*/
private int mPanelChordingKey;
+ private boolean mPanelMayLongPress;
private ImageView mLeftIconView;
@@ -155,121 +156,6 @@
private TelephonyManager mTelephonyManager = null;
- private boolean mSearchKeyDownReceived;
-
- private boolean mKeycodeCallTimeoutActive = false;
-
- private boolean mKeycodeCameraTimeoutActive = false;
-
- static final int MSG_MENU_LONG_PRESS = 1;
- static final int MSG_MENU_LONG_PRESS_COMPLETE = 2;
- static final int MSG_CALL_LONG_PRESS = 3;
- static final int MSG_CALL_LONG_PRESS_COMPLETE = 4;
- static final int MSG_CAMERA_LONG_PRESS = 5;
- static final int MSG_CAMERA_LONG_PRESS_COMPLETE = 6;
- static final int MSG_SEARCH_LONG_PRESS = 7;
- static final int MSG_SEARCH_LONG_PRESS_COMPLETE = 8;
-
- private final Handler mKeycodeMenuTimeoutHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_MENU_LONG_PRESS: {
- if (mPanelChordingKey == 0) return;
- // Before actually doing the long press, enqueue another
- // message and do the processing there. This helps if
- // the app isn't being responsive, and finally woke up --
- // if the window manager wasn't told about it processing
- // the down key for too long, it would enqueue the key up
- // at a time after the timeout of this message. So we go
- // through another message, to make sure we process an up
- // before continuing.
- mKeycodeMenuTimeoutHandler.sendEmptyMessage(
- MSG_MENU_LONG_PRESS_COMPLETE);
- break;
- }
- case MSG_CALL_LONG_PRESS: {
- if (!mKeycodeCallTimeoutActive) return;
- // See above.
- mKeycodeMenuTimeoutHandler.sendEmptyMessage(
- MSG_CALL_LONG_PRESS_COMPLETE);
- break;
- }
- case MSG_CAMERA_LONG_PRESS: {
- if (!mKeycodeCameraTimeoutActive) return;
- // See above.
- Message newMessage = Message.obtain(msg);
- newMessage.what = MSG_CAMERA_LONG_PRESS_COMPLETE;
- mKeycodeMenuTimeoutHandler.sendMessage(newMessage);
- break;
- }
- case MSG_SEARCH_LONG_PRESS: {
- if (!mSearchKeyDownReceived) return;
- // See above.
- Message newMessage = Message.obtain(msg);
- newMessage.what = MSG_SEARCH_LONG_PRESS_COMPLETE;
- mKeycodeMenuTimeoutHandler.sendMessage(newMessage);
- break;
- }
- case MSG_MENU_LONG_PRESS_COMPLETE: {
- if (mPanelChordingKey == 0) return;
- mPanelChordingKey = 0;
- mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- if (imm != null) {
- imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
- }
- } break;
- case MSG_CALL_LONG_PRESS_COMPLETE: {
- if (!mKeycodeCallTimeoutActive) return;
- mKeycodeCallTimeoutActive = false;
- mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- // launch the VoiceDialer
- Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- sendCloseSystemWindows();
- getContext().startActivity(intent);
- } catch (ActivityNotFoundException e) {
- startCallActivity();
- }
- } break;
- case MSG_CAMERA_LONG_PRESS_COMPLETE: {
- if (!mKeycodeCameraTimeoutActive) return;
- mKeycodeCameraTimeoutActive = false;
- mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- sendCloseSystemWindows();
- // Broadcast an intent that the Camera button was longpressed
- Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
- intent.putExtra(Intent.EXTRA_KEY_EVENT, (KeyEvent) msg.obj);
- getContext().sendOrderedBroadcast(intent, null);
- } break;
- case MSG_SEARCH_LONG_PRESS_COMPLETE: {
- if (getKeyguardManager().inKeyguardRestrictedInputMode() ||
- !mSearchKeyDownReceived) {
- mSearchKeyDownReceived = false;
- return;
- }
- mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- // launch the search activity
- Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- sendCloseSystemWindows();
- getContext().startActivity(intent);
- // Only clear this if we successfully start the
- // activity; otherwise we will allow the normal short
- // press action to be performed.
- mSearchKeyDownReceived = false;
- } catch (ActivityNotFoundException e) {
- // Ignore
- }
- } break;
- }
- }
- };
-
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
@@ -649,19 +535,35 @@
* @return Whether the key was handled.
*/
public final boolean onKeyDownPanel(int featureId, KeyEvent event) {
- // The panel key was pushed, so set the chording key
- mPanelChordingKey = event.getKeyCode();
-
- PanelFeatureState st = getPanelState(featureId, true);
- if (!st.isOpen) {
- if (getContext().getResources().getConfiguration().keyboard
- == Configuration.KEYBOARD_NOKEYS) {
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
- mKeycodeMenuTimeoutHandler.sendMessageDelayed(
- mKeycodeMenuTimeoutHandler.obtainMessage(MSG_MENU_LONG_PRESS),
- ViewConfiguration.getLongPressTimeout());
+ final int keyCode = event.getKeyCode();
+
+ if (event.getRepeatCount() == 0) {
+ // The panel key was pushed, so set the chording key
+ mPanelChordingKey = keyCode;
+ mPanelMayLongPress = false;
+
+ PanelFeatureState st = getPanelState(featureId, true);
+ if (!st.isOpen) {
+ if (getContext().getResources().getConfiguration().keyboard
+ == Configuration.KEYBOARD_NOKEYS) {
+ mPanelMayLongPress = true;
+ }
+ return preparePanel(st, event);
}
- return preparePanel(st, event);
+
+ } else if (mPanelMayLongPress && mPanelChordingKey == keyCode
+ && (event.getFlags()&KeyEvent.FLAG_LONG_PRESS) != 0) {
+ // We have had a long press while in a state where this
+ // should be executed... do it!
+ mPanelChordingKey = 0;
+ mPanelMayLongPress = false;
+ InputMethodManager imm = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ }
+
}
return false;
@@ -676,7 +578,7 @@
// The panel key was released, so clear the chording key
if (mPanelChordingKey != 0) {
mPanelChordingKey = 0;
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
+ mPanelMayLongPress = false;
if (event.isCanceled()) {
return;
@@ -1218,6 +1120,11 @@
* @see android.view.KeyEvent
*/
protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {
+ final KeyEvent.DispatcherState dispatcher =
+ mDecor != null ? mDecor.getKeyDispatcherState() : null;
+ //Log.i(TAG, "Key down: repeat=" + event.getRepeatCount()
+ // + " flags=0x" + Integer.toHexString(event.getFlags()));
+
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN: {
@@ -1264,26 +1171,31 @@
}
case KeyEvent.KEYCODE_CAMERA: {
- if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
+ if (getKeyguardManager().inKeyguardRestrictedInputMode()
+ || dispatcher == null) {
break;
}
- if (event.getRepeatCount() > 0) break;
- mKeycodeCameraTimeoutActive = true;
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
- Message message = mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CAMERA_LONG_PRESS);
- message.obj = event;
- mKeycodeMenuTimeoutHandler.sendMessageDelayed(message,
- ViewConfiguration.getLongPressTimeout());
+ if (event.getRepeatCount() == 0) {
+ dispatcher.startTracking(event, this);
+ } else if (event.isLongPress() && dispatcher.isTracking(event)) {
+ dispatcher.performedLongPress(event);
+ mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ sendCloseSystemWindows();
+ // Broadcast an intent that the Camera button was longpressed
+ Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
+ intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
+ getContext().sendOrderedBroadcast(intent, null);
+ }
return true;
}
case KeyEvent.KEYCODE_MENU: {
- if (event.getRepeatCount() > 0) break;
onKeyDownPanel((featureId < 0) ? FEATURE_OPTIONS_PANEL : featureId, event);
return true;
}
case KeyEvent.KEYCODE_BACK: {
+ // Currently don't do anything with long presses.
if (event.getRepeatCount() > 0) break;
if (featureId < 0) break;
if (featureId == FEATURE_OPTIONS_PANEL) {
@@ -1300,34 +1212,55 @@
}
case KeyEvent.KEYCODE_CALL: {
- if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
+ if (getKeyguardManager().inKeyguardRestrictedInputMode()
+ || dispatcher == null) {
break;
}
- if (event.getRepeatCount() > 0) break;
- mKeycodeCallTimeoutActive = true;
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
- mKeycodeMenuTimeoutHandler.sendMessageDelayed(
- mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CALL_LONG_PRESS),
- ViewConfiguration.getLongPressTimeout());
+ if (event.getRepeatCount() == 0) {
+ dispatcher.startTracking(event, this);
+ } else if (event.isLongPress() && dispatcher.isTracking(event)) {
+ dispatcher.performedLongPress(event);
+ mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ // launch the VoiceDialer
+ Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ sendCloseSystemWindows();
+ getContext().startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ startCallActivity();
+ }
+ }
return true;
}
case KeyEvent.KEYCODE_SEARCH: {
+ if (getKeyguardManager().inKeyguardRestrictedInputMode()
+ || dispatcher == null) {
+ break;
+ }
if (event.getRepeatCount() == 0) {
- mSearchKeyDownReceived = true;
+ dispatcher.startTracking(event, this);
+ } else if (event.isLongPress() && dispatcher.isTracking(event)) {
Configuration config = getContext().getResources().getConfiguration();
if (config.keyboard == Configuration.KEYBOARD_NOKEYS
- || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
- // If this device does not have a hardware keyboard,
- // or that keyboard is hidden, then we can't use the
- // search key for chording to perform shortcuts;
- // instead, we will let the user long press,
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_SEARCH_LONG_PRESS);
- mKeycodeMenuTimeoutHandler.sendMessageDelayed(
- mKeycodeMenuTimeoutHandler.obtainMessage(MSG_SEARCH_LONG_PRESS),
- ViewConfiguration.getLongPressTimeout());
+ || config.hardKeyboardHidden
+ == Configuration.HARDKEYBOARDHIDDEN_YES) {
+ // launch the search activity
+ Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ sendCloseSystemWindows();
+ getContext().startActivity(intent);
+ mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ // Only clear this if we successfully start the
+ // activity; otherwise we will allow the normal short
+ // press action to be performed.
+ dispatcher.performedLongPress(event);
+ } catch (ActivityNotFoundException e) {
+ // Ignore
+ }
}
- return true;
}
break;
}
@@ -1353,6 +1286,14 @@
* @see android.view.KeyEvent
*/
protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) {
+ final KeyEvent.DispatcherState dispatcher =
+ mDecor != null ? mDecor.getKeyDispatcherState() : null;
+ if (dispatcher != null) {
+ dispatcher.handleUpEvent(event);
+ }
+ //Log.i(TAG, "Key up: repeat=" + event.getRepeatCount()
+ // + " flags=0x" + Integer.toHexString(event.getFlags()));
+
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN: {
@@ -1378,6 +1319,21 @@
return true;
}
+ case KeyEvent.KEYCODE_BACK: {
+ if (featureId < 0) break;
+ if (featureId == FEATURE_OPTIONS_PANEL) {
+ PanelFeatureState st = getPanelState(featureId, false);
+ if (st != null && st.isInExpandedMode) {
+ // If the user is in an expanded menu and hits back, it
+ // should go back to the icon menu
+ reopenMenu(true);
+ return true;
+ }
+ }
+ closePanel(featureId);
+ return true;
+ }
+
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MEDIA_STOP:
@@ -1395,11 +1351,7 @@
if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
break;
}
- if (event.getRepeatCount() > 0) break; // Can a key up event repeat?
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
- if (!mKeycodeCameraTimeoutActive) break;
- mKeycodeCameraTimeoutActive = false;
- if (!event.isCanceled()) {
+ if (event.isTracking() && !event.isCanceled()) {
// Add short press behavior here if desired
}
return true;
@@ -1409,11 +1361,7 @@
if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
break;
}
- if (event.getRepeatCount() > 0) break;
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
- if (!mKeycodeCallTimeoutActive) break;
- mKeycodeCallTimeoutActive = false;
- if (!event.isCanceled()) {
+ if (event.isTracking() && !event.isCanceled()) {
startCallActivity();
}
return true;
@@ -1424,13 +1372,10 @@
* Do this in onKeyUp since the Search key is also used for
* chording quick launch shortcuts.
*/
- if (getKeyguardManager().inKeyguardRestrictedInputMode() ||
- !mSearchKeyDownReceived) {
- mSearchKeyDownReceived = false;
+ if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
break;
}
- mSearchKeyDownReceived = false;
- if (!event.isCanceled()) {
+ if (event.isTracking() && !event.isCanceled()) {
launchDefaultSearch();
}
return true;
@@ -2016,16 +1961,11 @@
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
- // no KEYCODE_CALL events active across focus changes
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
- mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
- mKeycodeCallTimeoutActive = false;
- mKeycodeCameraTimeoutActive = false;
+ mPanelMayLongPress = false;
// If the user is chording a menu shortcut, release the chord since
// this window lost focus
- if (!hasWindowFocus && mPanelChordingKey > 0) {
+ if (!hasWindowFocus && mPanelChordingKey != 0) {
closePanel(FEATURE_OPTIONS_PANEL);
}