diff options
author | Winson Chung <winsonc@google.com> | 2014-05-19 16:25:39 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-19 16:25:40 +0000 |
commit | 958e559b98bd7c3ab6dd20bf530bf58f56f20b63 (patch) | |
tree | 8a752bc6057bdf9cb137805136e8e74ebfaa2456 | |
parent | b82bbf6113a5b72631f1ee727d98d35a2b215121 (diff) | |
parent | 1e8d71b605b4872e93200706a80a88a3ff25498c (diff) | |
download | frameworks_base-958e559b98bd7c3ab6dd20bf530bf58f56f20b63.zip frameworks_base-958e559b98bd7c3ab6dd20bf530bf58f56f20b63.tar.gz frameworks_base-958e559b98bd7c3ab6dd20bf530bf58f56f20b63.tar.bz2 |
Merge "Initial changes to enable keyboard support with alternate Recents. (Bug 14067913)"
19 files changed, 463 insertions, 179 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 75feb5d..8fa662d 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -36,9 +36,12 @@ oneway interface IStatusBar void setImeWindowStatus(in IBinder token, int vis, int backDisposition, boolean showImeSwitcher); void setHardKeyboardStatus(boolean available, boolean enabled); + void setWindowState(int window, int state); + + void showRecentApps(boolean triggeredFromAltTab); + void hideRecentApps(); void toggleRecentApps(); void preloadRecentApps(); void cancelPreloadRecentApps(); - void setWindowState(int window, int state); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index cf334c3..9ebfd78 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -52,8 +52,11 @@ interface IStatusBarService in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys); void setSystemUiVisibility(int vis, int mask); void setHardKeyboardEnabled(boolean enabled); + void setWindowState(int window, int state); + + void showRecentApps(boolean triggeredFromAltTab); + void hideRecentApps(); void toggleRecentApps(); void preloadRecentApps(); void cancelPreloadRecentApps(); - void setWindowState(int window, int state); } diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index bda6431..a68ad2f 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -16,7 +16,8 @@ <com.android.systemui.recents.views.TaskView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:focusable="true"> <com.android.systemui.recents.views.TaskThumbnailView android:id="@+id/task_view_thumbnail" android:layout_width="match_parent" @@ -69,7 +70,7 @@ android:layout_height="@dimen/recents_task_view_application_icon_size" android:layout_gravity="center_vertical|end" android:padding="23dp" - android:src="@drawable/recents_dismiss_dark" /> + android:src="@drawable/recents_dismiss_light" /> </com.android.systemui.recents.views.TaskBarView> </com.android.systemui.recents.views.TaskView> diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java index 323905f..105f70e 100644 --- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java @@ -20,11 +20,9 @@ import android.view.Display; import android.view.View; public interface RecentsComponent { + void showRecents(boolean triggeredFromAltTab, View statusBarView); + void hideRecents(); void toggleRecents(Display display, int layoutDirection, View statusBarView); - - void preloadRecentTasksList(); - - void cancelPreloadingRecentTasksList(); - - void closeRecents(); + void preloadRecents(); + void cancelPreloadingRecents(); } diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java index de0f9de..00c43e8 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java @@ -27,7 +27,6 @@ import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.SystemProperties; import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.Log; @@ -66,10 +65,30 @@ public class Recents extends SystemUI implements RecentsComponent { } @Override + public void showRecents(boolean triggeredFromAltTab, View statusBarView) { + if (mUseAlternateRecents) { + mAlternateRecents.onShowRecents(triggeredFromAltTab, statusBarView); + } + } + + @Override + public void hideRecents() { + if (mUseAlternateRecents) { + mAlternateRecents.onHideRecents(); + } else { + Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT); + intent.setPackage("com.android.systemui"); + sendBroadcastSafely(intent); + + RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask(); + } + } + + @Override public void toggleRecents(Display display, int layoutDirection, View statusBarView) { if (mUseAlternateRecents) { // Launch the alternate recents if required - mAlternateRecents.onToggleRecents(display, layoutDirection, statusBarView); + mAlternateRecents.onToggleRecents(statusBarView); return; } @@ -222,7 +241,7 @@ public class Recents extends SystemUI implements RecentsComponent { } @Override - public void preloadRecentTasksList() { + public void preloadRecents() { if (mUseAlternateRecents) { mAlternateRecents.onPreloadRecents(); } else { @@ -236,7 +255,7 @@ public class Recents extends SystemUI implements RecentsComponent { } @Override - public void cancelPreloadingRecentTasksList() { + public void cancelPreloadingRecents() { if (mUseAlternateRecents) { mAlternateRecents.onCancelPreloadingRecents(); } else { @@ -249,19 +268,6 @@ public class Recents extends SystemUI implements RecentsComponent { } } - @Override - public void closeRecents() { - if (mUseAlternateRecents) { - mAlternateRecents.onCloseRecents(); - } else { - Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT); - intent.setPackage("com.android.systemui"); - sendBroadcastSafely(intent); - - RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask(); - } - } - /** * Send broadcast only if BOOT_COMPLETED */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index 19a1b11..ec50bfa 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -44,9 +44,9 @@ import android.view.View; import android.view.WindowManager; import com.android.systemui.R; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** A proxy implementation for the recents component */ public class AlternateRecentsComponent { @@ -72,7 +72,7 @@ public class AlternateRecentsComponent { // If we had the update the animation rects as a result of onServiceConnected, then // we check for whether we need to toggle the recents here. if (mToggleRecentsUponServiceBound) { - startAlternateRecentsActivity(); + startRecentsActivity(); mToggleRecentsUponServiceBound = false; } } @@ -90,9 +90,9 @@ public class AlternateRecentsComponent { mServiceIsBound = true; if (hasValidTaskRects()) { - // Toggle recents if this new service connection was triggered by hitting recents + // Start recents if this new service connection was triggered by hitting recents if (mToggleRecentsUponServiceBound) { - startAlternateRecentsActivity(); + startRecentsActivity(); mToggleRecentsUponServiceBound = false; } } else { @@ -114,10 +114,12 @@ public class AlternateRecentsComponent { final public static int MSG_UPDATE_TASK_THUMBNAIL = 1; final public static int MSG_PRELOAD_TASKS = 2; final public static int MSG_CANCEL_PRELOAD_TASKS = 3; - final public static int MSG_CLOSE_RECENTS = 4; - final public static int MSG_TOGGLE_RECENTS = 5; + final public static int MSG_SHOW_RECENTS = 4; + final public static int MSG_HIDE_RECENTS = 5; + final public static int MSG_TOGGLE_RECENTS = 6; final public static String EXTRA_ANIMATING_WITH_THUMBNAIL = "recents.animatingWithThumbnail"; + final public static String EXTRA_FROM_ALT_TAB = "recents.triggeredFromAltTab"; final public static String KEY_CONFIGURATION_DATA = "recents.data.updateForConfiguration"; final public static String KEY_WINDOW_RECT = "recents.windowRect"; final public static String KEY_SYSTEM_INSETS = "recents.systemInsets"; @@ -142,7 +144,10 @@ public class AlternateRecentsComponent { boolean mToggleRecentsUponServiceBound; RecentsServiceConnection mConnection = new RecentsServiceConnection(); + // Variables to keep track of if we need to start recents after binding View mStatusBarView; + boolean mTriggeredFromAltTab; + Rect mSingleCountFirstTaskRect = new Rect(); Rect mMultipleCountFirstTaskRect = new Rect(); long mLastToggleTime; @@ -160,8 +165,43 @@ public class AlternateRecentsComponent { bindToRecentsService(false); } + /** Shows the recents */ + public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) { + Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|showRecents]"); + mStatusBarView = statusBarView; + mTriggeredFromAltTab = triggeredFromAltTab; + if (!mServiceIsBound) { + // Try to create a long-running connection to the recents service before toggling + // recents + bindToRecentsService(true); + return; + } + + try { + startRecentsActivity(); + } catch (ActivityNotFoundException e) { + Console.logRawError("Failed to launch RecentAppsIntent", e); + } + } + + /** Hides the recents */ + public void onHideRecents() { + Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|hideRecents]"); + if (mServiceIsBound) { + // Notify recents to close it + try { + Bundle data = new Bundle(); + Message msg = Message.obtain(null, MSG_HIDE_RECENTS, 0, 0); + msg.setData(data); + mService.send(msg); + } catch (RemoteException re) { + re.printStackTrace(); + } + } + } + /** Toggles the alternate recents activity */ - public void onToggleRecents(Display display, int layoutDirection, View statusBarView) { + public void onToggleRecents(View statusBarView) { Console.logStartTracingTime(Constants.Log.App.TimeRecentsStartup, Constants.Log.App.TimeRecentsStartupKey); Console.logStartTracingTime(Constants.Log.App.TimeRecentsLaunchTask, @@ -169,6 +209,7 @@ public class AlternateRecentsComponent { Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|toggleRecents]", "serviceIsBound: " + mServiceIsBound); mStatusBarView = statusBarView; + mTriggeredFromAltTab = false; if (!mServiceIsBound) { // Try to create a long-running connection to the recents service before toggling // recents @@ -177,7 +218,7 @@ public class AlternateRecentsComponent { } try { - startAlternateRecentsActivity(); + toggleRecentsActivity(); } catch (ActivityNotFoundException e) { Console.logRawError("Failed to launch RecentAppsIntent", e); } @@ -191,21 +232,6 @@ public class AlternateRecentsComponent { // Do nothing } - public void onCloseRecents() { - Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|closeRecents]"); - if (mServiceIsBound) { - // Try and update the recents configuration - try { - Bundle data = new Bundle(); - Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0); - msg.setData(data); - mService.send(msg); - } catch (RemoteException re) { - re.printStackTrace(); - } - } - } - public void onConfigurationChanged(Configuration newConfig) { updateAnimationRects(); } @@ -355,20 +381,10 @@ public class AlternateRecentsComponent { taskRect.left, taskRect.top, null); } - /** Starts the recents activity */ - void startAlternateRecentsActivity() { - // If the user has toggled it too quickly, then just eat up the event here (it's better than - // showing a janky screenshot). - // NOTE: Ideally, the screenshot mechanism would take the window transform into account - if (System.currentTimeMillis() - mLastToggleTime < sMinToggleDelay) { - return; - } - - // If Recents is the front most activity, then we should just communicate with it directly - // to launch the first task or dismiss itself + /** Returns whether the recents is currently running */ + boolean isRecentsTopMost(AtomicBoolean isHomeTopMost) { SystemServicesProxy ssp = mSystemServicesProxy; List<ActivityManager.RunningTaskInfo> tasks = ssp.getRunningTasks(1); - boolean isTopTaskHome = false; if (!tasks.isEmpty()) { ActivityManager.RunningTaskInfo topTask = tasks.get(0); ComponentName topActivity = topTask.topActivity; @@ -376,33 +392,71 @@ public class AlternateRecentsComponent { // Check if the front most activity is recents if (topActivity.getPackageName().equals(sRecentsPackage) && topActivity.getClassName().equals(sRecentsActivity)) { - // Notify Recents to toggle itself - try { - Bundle data = new Bundle(); - Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0); - msg.setData(data); - mService.send(msg); - - // Time this path - Console.logTraceTime(Constants.Log.App.TimeRecentsStartup, - Constants.Log.App.TimeRecentsStartupKey, "sendToggleRecents"); - Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask, - Constants.Log.App.TimeRecentsLaunchKey, "sendToggleRecents"); - } catch (RemoteException re) { - re.printStackTrace(); + if (isHomeTopMost != null) { + isHomeTopMost.set(false); } - mLastToggleTime = System.currentTimeMillis(); - return; + return true; + } + + if (isHomeTopMost != null) { + isHomeTopMost.set(ssp.isInHomeStack(topTask.id)); + } + } + return false; + } + + /** Toggles the recents activity */ + void toggleRecentsActivity() { + // If the user has toggled it too quickly, then just eat up the event here (it's better than + // showing a janky screenshot). + // NOTE: Ideally, the screenshot mechanism would take the window transform into account + if (System.currentTimeMillis() - mLastToggleTime < sMinToggleDelay) { + return; + } + + // If Recents is the front most activity, then we should just communicate with it directly + // to launch the first task or dismiss itself + AtomicBoolean isTopTaskHome = new AtomicBoolean(); + if (isRecentsTopMost(isTopTaskHome)) { + // Notify recents to close itself + try { + Bundle data = new Bundle(); + Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0); + msg.setData(data); + mService.send(msg); + + // Time this path + Console.logTraceTime(Constants.Log.App.TimeRecentsStartup, + Constants.Log.App.TimeRecentsStartupKey, "sendToggleRecents"); + Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask, + Constants.Log.App.TimeRecentsLaunchKey, "sendToggleRecents"); + } catch (RemoteException re) { + re.printStackTrace(); } + mLastToggleTime = System.currentTimeMillis(); + return; + } else { + // Otherwise, start the recents activity + startRecentsActivity(isTopTaskHome.get()); + } + } - // Determine whether the top task is currently home - isTopTaskHome = ssp.isInHomeStack(topTask.id); + /** Starts the recents activity if it is not already running */ + void startRecentsActivity() { + // Check if the top task is in the home stack, and start the recents activity + AtomicBoolean isTopTaskHome = new AtomicBoolean(); + if (!isRecentsTopMost(isTopTaskHome)) { + startRecentsActivity(isTopTaskHome.get()); } + } - // Otherwise, Recents is not the front-most activity and we should animate into it. If + /** Starts the recents activity */ + void startRecentsActivity(boolean isTopTaskHome) { + // If Recents is not the front-most activity and we should animate into it. If // the activity at the root of the top task stack in the home stack, then we just do a // simple transition. Otherwise, we animate to the rects defined by the Recents service, // which can differ depending on the number of items in the list. + SystemServicesProxy ssp = mSystemServicesProxy; List<ActivityManager.RecentTaskInfo> recentTasks = ssp.getRecentTasks(2, UserHandle.CURRENT.getIdentifier()); Rect taskRect = hasMultipleRecentsTask(recentTasks) ? mMultipleCountFirstTaskRect : @@ -422,9 +476,6 @@ public class AlternateRecentsComponent { } // If there is no thumbnail transition, then just use a generic transition - // XXX: This should be different between home and from a recents-excluded app, perhaps the - // recents-excluded app should still show up in recents, when the app is in the - // foreground if (!useThumbnailTransition) { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_launcher_enter, @@ -444,6 +495,7 @@ public class AlternateRecentsComponent { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); intent.putExtra(EXTRA_ANIMATING_WITH_THUMBNAIL, animatingWithThumbnail); + intent.putExtra(EXTRA_FROM_ALT_TAB, mTriggeredFromAltTab); if (opts != null) { mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle( UserHandle.USER_CURRENT)); diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 90998da..9390b0d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -69,6 +69,7 @@ public class Constants { public static final boolean TouchEvents = false; public static final boolean MeasureAndLayout = false; public static final boolean HwLayers = false; + public static final boolean Focus = false; } public static class TaskStack { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index b74f6ac..325e4b0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -28,6 +28,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Pair; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; @@ -81,7 +82,10 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView String action = intent.getAction(); Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed); - if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) { + if (action.equals(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY)) { + // Dismiss recents, launching the focused task + dismissRecentsIfVisible(); + } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) { // Try and unfilter and filtered stacks if (!mRecentsView.unfilterFilteredStacks()) { // If there are no filtered stacks, dismiss recents and launch the first task @@ -105,6 +109,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView RecentsConfiguration config = RecentsConfiguration.getInstance(); config.launchedWithThumbnailAnimation = launchIntent.getBooleanExtra( AlternateRecentsComponent.EXTRA_ANIMATING_WITH_THUMBNAIL, false); + config.launchedFromAltTab = launchIntent.getBooleanExtra( + AlternateRecentsComponent.EXTRA_FROM_ALT_TAB, false); RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount); @@ -184,7 +190,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView int appWidgetId = config.searchBarAppWidgetId; if (appWidgetId >= 0) { Console.log(Constants.Log.App.SystemUIHandshake, - "[RecentsActivity|onCreate|addSearchAppWidgetView]", + "[RecentsActivity|onCreate|addSearchAppWidgetView]", "Id: " + appWidgetId, Console.AnsiBlue); mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId, @@ -205,8 +211,10 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView /** Dismisses recents if we are already visible and the intent is to toggle the recents view */ boolean dismissRecentsIfVisible() { if (mVisible) { - if (!mRecentsView.launchFirstTask()) { - finish(); + if (!mRecentsView.launchFocusedTask()) { + if (!mRecentsView.launchFirstTask()) { + finish(); + } } return true; } @@ -303,6 +311,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Register the broadcast receiver to handle messages from our service IntentFilter filter = new IntentFilter(); + filter.addAction(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY); filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY); registerReceiver(mServiceBroadcastReceiver, filter); @@ -362,6 +371,18 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_TAB) { + // Focus the next task in the stack + final boolean backward = event.isShiftPressed(); + mRecentsView.focusNextTask(!backward); + return true; + } + + return super.onKeyDown(keyCode, event); + } + + @Override public void onBackPressed() { boolean interceptedByInfoPanelClose = false; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 9afc1cb..8399551 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -65,6 +65,7 @@ public class RecentsConfiguration { public int taskBarViewLightTextColor; public int taskBarViewDarkTextColor; + public boolean launchedFromAltTab; public boolean launchedWithThumbnailAnimation; /** Private constructor */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java index 837cb34..601b382 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java @@ -106,8 +106,11 @@ class SystemUIMessageHandler extends Handler { } catch (RemoteException re) { re.printStackTrace(); } - } else if (msg.what == AlternateRecentsComponent.MSG_CLOSE_RECENTS) { - // Do nothing + } else if (msg.what == AlternateRecentsComponent.MSG_HIDE_RECENTS) { + // Send a broadcast to hide recents + Intent intent = new Intent(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY); + intent.setPackage(context.getPackageName()); + context.sendBroadcast(intent); } else if (msg.what == AlternateRecentsComponent.MSG_TOGGLE_RECENTS) { // Send a broadcast to toggle recents Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY); @@ -125,6 +128,7 @@ class SystemUIMessageHandler extends Handler { /* Service */ public class RecentsService extends Service { + final static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity"; final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity"; Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this)); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index a6d7e67..2821052 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -94,6 +94,34 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } } + /** Launches the focused task from the first stack if possible */ + public boolean launchFocusedTask() { + // Get the first stack view + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (child instanceof TaskStackView) { + TaskStackView stackView = (TaskStackView) child; + TaskStack stack = stackView.mStack; + // Iterate the stack views and try and find the focused task + int taskCount = stackView.getChildCount(); + for (int j = 0; j < taskCount; j++) { + TaskView tv = (TaskView) stackView.getChildAt(j); + Task task = tv.getTask(); + if (tv.isFocusedTask()) { + Console.log(Constants.Log.UI.Focus, "[RecentsView|launchFocusedTask]", + "Found focused Task"); + onTaskLaunched(stackView, tv, stack, task); + return true; + } + } + } + } + Console.log(Constants.Log.UI.Focus, "[RecentsView|launchFocusedTask]", + "No Tasks focused"); + return false; + } + /** Launches the first task from the first stack if possible */ public boolean launchFirstTask() { // Get the first stack view @@ -234,6 +262,24 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } } + /** Focuses the next task in the first stack view */ + public void focusNextTask(boolean forward) { + // Get the first stack view + TaskStackView stackView = null; + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (child instanceof TaskStackView) { + stackView = (TaskStackView) child; + break; + } + } + + if (stackView != null) { + stackView.focusNextTask(forward); + } + } + @Override protected void dispatchDraw(Canvas canvas) { Console.log(Constants.Log.UI.Draw, "[RecentsView|dispatchDraw]", "", diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index b64225e..37c3c35 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -80,6 +80,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal int mMaxScroll; int mStashedScroll; int mLastInfoPaneStackScroll; + int mFocusedTaskIndex = -1; OverScroller mScroller; ObjectAnimator mScrollAnimator; @@ -306,6 +307,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mStackScroll = value; } + /** + * Returns the scroll to such that the task transform at that index will have t=0. (If the scroll + * is not bounded) + */ + int getStackScrollForTaskIndex(int i) { + int taskHeight = mTaskRect.height(); + return (int) (i * Constants.Values.TaskStackView.StackOverlapPct * taskHeight); + } + /** Gets the current stack scroll */ public int getStackScroll() { return mStackScroll; @@ -460,6 +470,64 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal return false; } + /** Focuses the task at the specified index in the stack */ + void focusTask(int taskIndex, boolean scrollToNewPosition) { + Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]", "" + taskIndex); + if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) { + mFocusedTaskIndex = taskIndex; + + // Focus the view if possible, otherwise, focus the view after we scroll into position + Task t = mStack.getTasks().get(taskIndex); + TaskView tv = getChildViewForTask(t); + Runnable postScrollRunnable = null; + if (tv != null) { + tv.setFocusedTask(); + Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]", "Requesting focus"); + } else { + postScrollRunnable = new Runnable() { + @Override + public void run() { + Task t = mStack.getTasks().get(mFocusedTaskIndex); + TaskView tv = getChildViewForTask(t); + if (tv != null) { + tv.setFocusedTask(); + Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]", + "Requesting focus after scroll animation"); + } + } + }; + } + + if (scrollToNewPosition) { + // Scroll the view into position + int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, + getStackScrollForTaskIndex(taskIndex))); + + animateScroll(getStackScroll(), newScroll, postScrollRunnable); + } else { + if (postScrollRunnable != null) { + postScrollRunnable.run(); + } + } + } + } + + /** Focuses the next task in the stack */ + void focusNextTask(boolean forward) { + Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusNextTask]", "" + mFocusedTaskIndex); + + // Find the next index to focus + int numTasks = mStack.getTaskCount(); + if (mFocusedTaskIndex < 0) { + mFocusedTaskIndex = numTasks - 1; + } + if (0 <= mFocusedTaskIndex && mFocusedTaskIndex < numTasks) { + mFocusedTaskIndex = Math.max(0, Math.min(numTasks - 1, + mFocusedTaskIndex + (forward ? -1 : 1))); + } + focusTask(mFocusedTaskIndex, true); + } + /** Enables the hw layers and increments the hw layer requirement ref count */ void addHwLayersRefCount(String reason) { Console.log(Constants.Log.UI.HwLayers, @@ -631,6 +699,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal requestSynchronizeStackViewsWithModel(); synchronizeStackViewsWithModel(); + // Update the focused task index to be the next item to the top task + if (config.launchedFromAltTab) { + focusTask(Math.max(0, mStack.getTaskCount() - 2), false); + } + // Animate the task bar of the first task view if (config.launchedWithThumbnailAnimation) { TaskView tv = (TaskView) getChildAt(getChildCount() - 1); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 5fad629..ffcb82b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -18,6 +18,7 @@ package com.android.systemui.recents.views; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; +import android.annotation.Nullable; import android.content.Context; import android.graphics.Canvas; import android.graphics.Outline; @@ -57,6 +58,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task mTask; boolean mTaskDataLoaded; boolean mTaskInfoPaneVisible; + boolean mIsFocused; Point mLastTouchDown = new Point(); Path mRoundedRectClipPath = new Path(); @@ -367,6 +369,34 @@ public class TaskView extends FrameLayout implements View.OnClickListener, } } + /** + * Sets the focused task explicitly. We need a separate flag because requestFocus() won't happen + * if the view is not currently visible, or we are in touch state (where we still want to keep + * track of focus). + */ + public void setFocusedTask() { + mIsFocused = true; + requestFocus(); + } + + /** + * Updates the explicitly focused state when the view focus changes. + */ + @Override + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + if (!gainFocus) { + mIsFocused = false; + } + } + + /** + * Returns whether we have explicitly been focused. + */ + public boolean isFocusedTask() { + return mIsFocused || isFocused(); + } + /**** TaskCallbacks Implementation ****/ /** Binds this task view to the task */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index c1228d9..7918dec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -87,8 +87,9 @@ public abstract class BaseStatusBar extends SystemUI implements public static final boolean DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; - protected static final int MSG_TOGGLE_RECENTS_PANEL = 1020; - protected static final int MSG_CLOSE_RECENTS_PANEL = 1021; + protected static final int MSG_SHOW_RECENT_APPS = 1019; + protected static final int MSG_HIDE_RECENT_APPS = 1020; + protected static final int MSG_TOGGLE_RECENTS_APPS = 1021; protected static final int MSG_PRELOAD_RECENT_APPS = 1022; protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023; protected static final int MSG_OPEN_SEARCH_PANEL = 1024; @@ -496,8 +497,22 @@ public abstract class BaseStatusBar extends SystemUI implements } @Override + public void showRecentApps(boolean triggeredFromAltTab) { + int msg = MSG_SHOW_RECENT_APPS; + mHandler.removeMessages(msg); + mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, 0).sendToTarget(); + } + + @Override + public void hideRecentApps() { + int msg = MSG_HIDE_RECENT_APPS; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + + @Override public void toggleRecentApps() { - int msg = MSG_TOGGLE_RECENTS_PANEL; + int msg = MSG_TOGGLE_RECENTS_APPS; mHandler.removeMessages(msg); mHandler.sendEmptyMessage(msg); } @@ -580,12 +595,12 @@ public abstract class BaseStatusBar extends SystemUI implements public boolean onTouch(View v, MotionEvent event) { int action = event.getAction() & MotionEvent.ACTION_MASK; if (action == MotionEvent.ACTION_DOWN) { - preloadRecentTasksList(); + preloadRecents(); } else if (action == MotionEvent.ACTION_CANCEL) { - cancelPreloadingRecentTasksList(); + cancelPreloadingRecents(); } else if (action == MotionEvent.ACTION_UP) { if (!v.isPressed()) { - cancelPreloadingRecentTasksList(); + cancelPreloadingRecents(); } } @@ -593,28 +608,38 @@ public abstract class BaseStatusBar extends SystemUI implements } }; - protected void toggleRecentsActivity() { + /** Proxy for RecentsComponent */ + + protected void showRecents(boolean triggeredFromAltTab) { if (mRecents != null) { sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS); - mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView()); + mRecents.showRecents(triggeredFromAltTab, getStatusBarView()); } } - protected void preloadRecentTasksList() { + protected void hideRecents() { if (mRecents != null) { - mRecents.preloadRecentTasksList(); + sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS); + mRecents.hideRecents(); } } - protected void cancelPreloadingRecentTasksList() { + protected void toggleRecents() { if (mRecents != null) { - mRecents.cancelPreloadingRecentTasksList(); + sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS); + mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView()); } } - protected void closeRecents() { + protected void preloadRecents() { if (mRecents != null) { - mRecents.closeRecents(); + mRecents.preloadRecents(); + } + } + + protected void cancelPreloadingRecents() { + if (mRecents != null) { + mRecents.cancelPreloadingRecents(); } } @@ -655,17 +680,20 @@ public abstract class BaseStatusBar extends SystemUI implements public void handleMessage(Message m) { Intent intent; switch (m.what) { - case MSG_TOGGLE_RECENTS_PANEL: - toggleRecentsActivity(); + case MSG_SHOW_RECENT_APPS: + showRecents(m.arg1 > 0); + break; + case MSG_HIDE_RECENT_APPS: + hideRecents(); break; - case MSG_CLOSE_RECENTS_PANEL: - closeRecents(); + case MSG_TOGGLE_RECENTS_APPS: + toggleRecents(); break; case MSG_PRELOAD_RECENT_APPS: - preloadRecentTasksList(); + preloadRecents(); break; case MSG_CANCEL_PRELOAD_RECENT_APPS: - cancelPreloadingRecentTasksList(); + cancelPreloadingRecents(); break; case MSG_OPEN_SEARCH_PANEL: if (DEBUG) Log.d(TAG, "opening search panel"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 5362af5..ebab7fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -57,6 +57,8 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_PRELOAD_RECENT_APPS = 14 << MSG_SHIFT; private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 15 << MSG_SHIFT; private static final int MSG_SET_WINDOW_STATE = 16 << MSG_SHIFT; + private static final int MSG_SHOW_RECENT_APPS = 17 << MSG_SHIFT; + private static final int MSG_HIDE_RECENT_APPS = 18 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; @@ -96,11 +98,13 @@ public class CommandQueue extends IStatusBar.Stub { public void setImeWindowStatus(IBinder token, int vis, int backDisposition, boolean showImeSwitcher); public void setHardKeyboardStatus(boolean available, boolean enabled); + public void showRecentApps(boolean triggeredFromAltTab); + public void hideRecentApps(); public void toggleRecentApps(); public void preloadRecentApps(); + public void cancelPreloadRecentApps(); public void showSearchPanel(); public void hideSearchPanel(); - public void cancelPreloadRecentApps(); public void setWindowState(int window, int state); } @@ -211,6 +215,21 @@ public class CommandQueue extends IStatusBar.Stub { } } + public void showRecentApps(boolean triggeredFromAltTab) { + synchronized (mList) { + mHandler.removeMessages(MSG_SHOW_RECENT_APPS); + mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, + triggeredFromAltTab ? 1 : 0, 0, null).sendToTarget(); + } + } + + public void hideRecentApps() { + synchronized (mList) { + mHandler.removeMessages(MSG_HIDE_RECENT_APPS); + mHandler.obtainMessage(MSG_HIDE_RECENT_APPS, 0, 0, null).sendToTarget(); + } + } + public void toggleRecentApps() { synchronized (mList) { mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); @@ -309,6 +328,12 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_SET_HARD_KEYBOARD_STATUS: mCallbacks.setHardKeyboardStatus(msg.arg1 != 0, msg.arg2 != 0); break; + case MSG_SHOW_RECENT_APPS: + mCallbacks.showRecentApps(msg.arg1 != 0); + break; + case MSG_HIDE_RECENT_APPS: + mCallbacks.hideRecentApps(); + break; case MSG_TOGGLE_RECENT_APPS: mCallbacks.toggleRecentApps(); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index a2bb385..1072e49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1393,8 +1393,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if ((state & StatusBarManager.DISABLE_RECENT) != 0) { // close recents if it's visible - mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); - mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); + mHandler.removeMessages(MSG_HIDE_RECENT_APPS); + mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS); } } @@ -1545,8 +1545,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) { - mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); - mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); + mHandler.removeMessages(MSG_HIDE_RECENT_APPS); + mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS); } if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 8eed414..466c8ed 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -261,13 +261,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mLastInputMethodWindow = null; WindowState mLastInputMethodTargetWindow = null; - static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0; - static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1; - static final int RECENT_APPS_BEHAVIOR_DISMISS = 2; - static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 3; - - RecentApplicationsDialog mRecentAppsDialog; - int mRecentAppsDialogHeldModifiers; + int mRecentAppsHeldModifiers; boolean mLanguageSwitchKeyPressed; int mLidState = LID_ABSENT; @@ -807,52 +801,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { } }; - /** - * Create (if necessary) and show or dismiss the recent apps dialog according - * according to the requested behavior. - */ - void showOrHideRecentAppsDialog(final int behavior) { - mHandler.post(new Runnable() { - @Override - public void run() { - if (mRecentAppsDialog == null) { - mRecentAppsDialog = new RecentApplicationsDialog(mContext); - } - if (mRecentAppsDialog.isShowing()) { - switch (behavior) { - case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS: - case RECENT_APPS_BEHAVIOR_DISMISS: - mRecentAppsDialog.dismiss(); - break; - case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH: - mRecentAppsDialog.dismissAndSwitch(); - break; - case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW: - default: - break; - } - } else { - switch (behavior) { - case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS: - mRecentAppsDialog.show(); - break; - case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW: - try { - mWindowManager.setInTouchMode(false); - } catch (RemoteException e) { - } - mRecentAppsDialog.show(); - break; - case RECENT_APPS_BEHAVIOR_DISMISS: - case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH: - default: - break; - } - } - } - }); - } - /** {@inheritDoc} */ @Override public void init(Context context, IWindowManager windowManager, @@ -2261,21 +2209,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Display task switcher for ALT-TAB or Meta-TAB. if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) { - if (mRecentAppsDialogHeldModifiers == 0 && !keyguardOn) { + if (mRecentAppsHeldModifiers == 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); + mRecentAppsHeldModifiers = shiftlessModifiers; + showRecentApps(true); return -1; } } - } else if (!down && mRecentAppsDialogHeldModifiers != 0 - && (metaState & mRecentAppsDialogHeldModifiers) == 0) { - mRecentAppsDialogHeldModifiers = 0; - showOrHideRecentAppsDialog(keyguardOn ? RECENT_APPS_BEHAVIOR_DISMISS : - RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH); + } else if (!down && mRecentAppsHeldModifiers != 0 + && (metaState & mRecentAppsHeldModifiers) == 0) { + mRecentAppsHeldModifiers = 0; + hideRecentApps(); } // Handle keyboard language switching. @@ -2448,7 +2395,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { statusbar.cancelPreloadRecentApps(); } } catch (RemoteException e) { - Slog.e(TAG, "RemoteException when showing recent apps", e); + Slog.e(TAG, "RemoteException when cancelling recent apps preload", e); // re-acquire status bar service next time it is needed. mStatusBarService = null; } @@ -2457,19 +2404,46 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void toggleRecentApps() { mPreloadedRecentApps = false; // preloading no longer needs to be canceled - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS); try { IStatusBarService statusbar = getStatusBarService(); if (statusbar != null) { statusbar.toggleRecentApps(); } } catch (RemoteException e) { + Slog.e(TAG, "RemoteException when toggling recent apps", e); + // re-acquire status bar service next time it is needed. + mStatusBarService = null; + } + } + + private void showRecentApps(boolean triggeredFromAltTab) { + mPreloadedRecentApps = false; // preloading no longer needs to be canceled + try { + IStatusBarService statusbar = getStatusBarService(); + if (statusbar != null) { + statusbar.showRecentApps(triggeredFromAltTab); + } + } catch (RemoteException e) { Slog.e(TAG, "RemoteException when showing recent apps", e); // re-acquire status bar service next time it is needed. mStatusBarService = null; } } + private void hideRecentApps() { + mPreloadedRecentApps = false; // preloading no longer needs to be canceled + try { + IStatusBarService statusbar = getStatusBarService(); + if (statusbar != null) { + statusbar.hideRecentApps(); + } + } catch (RemoteException e) { + Slog.e(TAG, "RemoteException when closing recent apps", e); + // re-acquire status bar service next time it is needed. + mStatusBarService = null; + } + } + /** * A home key -> launch home action was detected. Take the appropriate action * given the situation with the keyguard. diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java index 2f0d7d6..bc55ed1 100644 --- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java +++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java @@ -123,7 +123,7 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener } @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { + public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_TAB) { // Ignore all meta keys other than SHIFT. The app switch key could be a // fallback action chorded with ALT, META or even CTRL depending on the key map. diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 738ad32..2c38d3c 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -460,6 +460,24 @@ public class StatusBarManagerService extends IStatusBarService.Stub } @Override + public void showRecentApps(boolean triggeredFromAltTab) { + if (mBar != null) { + try { + mBar.showRecentApps(triggeredFromAltTab); + } catch (RemoteException ex) {} + } + } + + @Override + public void hideRecentApps() { + if (mBar != null) { + try { + mBar.hideRecentApps(); + } catch (RemoteException ex) {} + } + } + + @Override public void setCurrentUser(int newUserId) { if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId); mCurrentUserId = newUserId; |