summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2014-05-19 16:25:39 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-05-19 16:25:40 +0000
commit958e559b98bd7c3ab6dd20bf530bf58f56f20b63 (patch)
tree8a752bc6057bdf9cb137805136e8e74ebfaa2456
parentb82bbf6113a5b72631f1ee727d98d35a2b215121 (diff)
parent1e8d71b605b4872e93200706a80a88a3ff25498c (diff)
downloadframeworks_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)"
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl5
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl5
-rw-r--r--packages/SystemUI/res/layout/recents_task_view.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/RecentsComponent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/Recents.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java166
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Constants.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsService.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java8
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java100
-rw-r--r--policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java2
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java18
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;