@@ -298,9 +298,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
298298 GlobalActions mGlobalActions ;
299299 volatile boolean mPowerKeyHandled ; // accessed from input reader and handler thread
300300 boolean mPendingPowerKeyUpCanceled ;
301- RecentApplicationsDialog mRecentAppsDialog ;
302301 Handler mHandler ;
303302
303+ static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0 ;
304+ static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1 ;
305+ static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 2 ;
306+
307+ RecentApplicationsDialog mRecentAppsDialog ;
308+ int mRecentAppsDialogHeldModifiers ;
309+
304310 private static final int LID_ABSENT = -1 ;
305311 private static final int LID_CLOSED = 0 ;
306312 private static final int LID_OPEN = 1 ;
@@ -693,7 +699,7 @@ private void handleLongPressOnHome() {
693699 }
694700
695701 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG ) {
696- showOrHideRecentAppsDialog (0 , true /*dismissIfShown*/ );
702+ showOrHideRecentAppsDialog (RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS );
697703 } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI ) {
698704 try {
699705 mStatusBarService .toggleRecentApps ();
@@ -704,23 +710,44 @@ private void handleLongPressOnHome() {
704710 }
705711
706712 /**
707- * Create (if necessary) and launch the recent apps dialog, or hide it if it is
708- * already shown .
713+ * Create (if necessary) and show or dismiss the recent apps dialog according
714+ * according to the requested behavior .
709715 */
710- void showOrHideRecentAppsDialog (final int heldModifiers , final boolean dismissIfShown ) {
716+ void showOrHideRecentAppsDialog (final int behavior ) {
711717 mHandler .post (new Runnable () {
712718 @ Override
713719 public void run () {
714720 if (mRecentAppsDialog == null ) {
715721 mRecentAppsDialog = new RecentApplicationsDialog (mContext );
716722 }
717723 if (mRecentAppsDialog .isShowing ()) {
718- if (dismissIfShown ) {
719- mRecentAppsDialog .dismiss ();
724+ switch (behavior ) {
725+ case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS :
726+ mRecentAppsDialog .dismiss ();
727+ break ;
728+ case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH :
729+ mRecentAppsDialog .dismissAndSwitch ();
730+ break ;
731+ case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW :
732+ default :
733+ break ;
720734 }
721735 } else {
722- mRecentAppsDialog .setHeldModifiers (heldModifiers );
723- mRecentAppsDialog .show ();
736+ switch (behavior ) {
737+ case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS :
738+ mRecentAppsDialog .show ();
739+ break ;
740+ case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW :
741+ try {
742+ mWindowManager .setInTouchMode (false );
743+ } catch (RemoteException e ) {
744+ }
745+ mRecentAppsDialog .show ();
746+ break ;
747+ case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH :
748+ default :
749+ break ;
750+ }
724751 }
725752 }
726753 });
@@ -1598,7 +1625,7 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
15981625 return 0 ;
15991626 } else if (keyCode == KeyEvent .KEYCODE_APP_SWITCH ) {
16001627 if (down && repeatCount == 0 ) {
1601- showOrHideRecentAppsDialog (0 , true /*dismissIfShown*/ );
1628+ showOrHideRecentAppsDialog (RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS );
16021629 }
16031630 return -1 ;
16041631 }
@@ -1634,6 +1661,26 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
16341661 }
16351662 }
16361663
1664+ // Invoke shortcuts using Meta.
1665+ if (down && repeatCount == 0
1666+ && (metaState & KeyEvent .META_META_ON ) != 0 ) {
1667+ final KeyCharacterMap kcm = event .getKeyCharacterMap ();
1668+ Intent shortcutIntent = mShortcutManager .getIntent (kcm , keyCode ,
1669+ metaState & ~(KeyEvent .META_META_ON
1670+ | KeyEvent .META_META_LEFT_ON | KeyEvent .META_META_RIGHT_ON ));
1671+ if (shortcutIntent != null ) {
1672+ shortcutIntent .addFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
1673+ try {
1674+ mContext .startActivity (shortcutIntent );
1675+ } catch (ActivityNotFoundException ex ) {
1676+ Slog .w (TAG , "Dropping shortcut key combination because "
1677+ + "the activity to which it is registered was not found: "
1678+ + "META+" + KeyEvent .keyCodeToString (keyCode ), ex );
1679+ }
1680+ return -1 ;
1681+ }
1682+ }
1683+
16371684 // Handle application launch keys.
16381685 if (down && repeatCount == 0 ) {
16391686 String category = sApplicationLaunchKeyCategories .get (keyCode );
@@ -1647,9 +1694,29 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
16471694 + "the activity to which it is registered was not found: "
16481695 + "keyCode=" + keyCode + ", category=" + category , ex );
16491696 }
1697+ return -1 ;
16501698 }
16511699 }
16521700
1701+ // Display task switcher for ALT-TAB or Meta-TAB.
1702+ if (down && repeatCount == 0 && keyCode == KeyEvent .KEYCODE_TAB ) {
1703+ if (mRecentAppsDialogHeldModifiers == 0 ) {
1704+ final int shiftlessModifiers = event .getModifiers () & ~KeyEvent .META_SHIFT_MASK ;
1705+ if (KeyEvent .metaStateHasModifiers (shiftlessModifiers , KeyEvent .META_ALT_ON )
1706+ || KeyEvent .metaStateHasModifiers (
1707+ shiftlessModifiers , KeyEvent .META_META_ON )) {
1708+ mRecentAppsDialogHeldModifiers = shiftlessModifiers ;
1709+ showOrHideRecentAppsDialog (RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW );
1710+ return -1 ;
1711+ }
1712+ }
1713+ } else if (!down && mRecentAppsDialogHeldModifiers != 0
1714+ && (metaState & mRecentAppsDialogHeldModifiers ) == 0 ) {
1715+ mRecentAppsDialogHeldModifiers = 0 ;
1716+ showOrHideRecentAppsDialog (RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH );
1717+ }
1718+
1719+ // Let the application handle the key.
16531720 return 0 ;
16541721 }
16551722
@@ -1671,39 +1738,6 @@ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policy
16711738 final KeyCharacterMap kcm = event .getKeyCharacterMap ();
16721739 final int keyCode = event .getKeyCode ();
16731740 final int metaState = event .getMetaState ();
1674- final boolean initialDown = event .getAction () == KeyEvent .ACTION_DOWN
1675- && event .getRepeatCount () == 0 ;
1676-
1677- if (initialDown ) {
1678- // Invoke shortcuts using Meta as a fallback.
1679- if ((metaState & KeyEvent .META_META_ON ) != 0 ) {
1680- Intent shortcutIntent = mShortcutManager .getIntent (kcm , keyCode ,
1681- metaState & ~(KeyEvent .META_META_ON
1682- | KeyEvent .META_META_LEFT_ON | KeyEvent .META_META_RIGHT_ON ));
1683- if (shortcutIntent != null ) {
1684- shortcutIntent .addFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
1685- try {
1686- mContext .startActivity (shortcutIntent );
1687- } catch (ActivityNotFoundException ex ) {
1688- Slog .w (TAG , "Dropping shortcut key combination because "
1689- + "the activity to which it is registered was not found: "
1690- + "META+" + KeyEvent .keyCodeToString (keyCode ), ex );
1691- }
1692- return null ;
1693- }
1694- }
1695-
1696- // Display task switcher for ALT-TAB or Meta-TAB.
1697- if (keyCode == KeyEvent .KEYCODE_TAB ) {
1698- final int shiftlessModifiers = event .getModifiers () & ~KeyEvent .META_SHIFT_MASK ;
1699- if (KeyEvent .metaStateHasModifiers (shiftlessModifiers , KeyEvent .META_ALT_ON )
1700- || KeyEvent .metaStateHasModifiers (
1701- shiftlessModifiers , KeyEvent .META_META_ON )) {
1702- showOrHideRecentAppsDialog (shiftlessModifiers , false /*dismissIfShown*/ );
1703- return null ;
1704- }
1705- }
1706- }
17071741
17081742 // Check for fallback actions specified by the key character map.
17091743 if (getFallbackAction (kcm , keyCode , metaState , mFallbackAction )) {
0 commit comments