summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java30
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java18
3 files changed, 46 insertions, 5 deletions
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index d62e15a94f89..3249b41da934 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -174,6 +174,9 @@ interface IActivityTaskManager {
ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo();
Rect getTaskBounds(int taskId);
+ /** Focuses the top task on a display if it isn't already focused. Used for Recents. */
+ void focusTopTask(int displayId);
+
void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES)")
void updateLockTaskPackages(int userId, in String[] packages);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 4f362d4ed0d8..d22ed2b6f94e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -36,6 +36,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
+import android.view.Display;
import android.view.IRecentsAnimationController;
import android.view.IRecentsAnimationRunner;
import android.view.RemoteAnimationTarget;
@@ -219,6 +220,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
private int mRecentsTaskId = -1;
private TransitionInfo mInfo = null;
private boolean mOpeningSeparateHome = false;
+ private boolean mPausingSeparateHome = false;
private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
private PictureInPictureSurfaceTransaction mPipTransaction = null;
private IBinder mTransition = null;
@@ -407,6 +409,10 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// raise closing (pausing) task to "above" layer so it isn't covered
t.setLayer(target.leash, info.getChanges().size() * 3 - i);
mPausingTasks.add(new TaskState(change, target.leash));
+ if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // This can only happen if we have a separate recents/home (3p launcher)
+ mPausingSeparateHome = true;
+ }
if (taskInfo.pictureInPictureParams != null
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()) {
mPipTask = taskInfo.token;
@@ -657,6 +663,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mFinishCB != null, enabled);
return;
}
+ final int displayId = mInfo.getRootCount() > 0 ? mInfo.getRoot(0).getDisplayId()
+ : Display.DEFAULT_DISPLAY;
// transient launches don't receive focus automatically. Since we are taking over
// the gesture now, take focus explicitly.
// This also moves recents back to top if the user gestured before a switch
@@ -665,7 +673,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.setInputConsumerEnabled: set focus to recents",
mInstanceId);
- ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
+ ActivityTaskManager.getService().focusTopTask(displayId);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to set focused task", e);
}
@@ -700,8 +708,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return;
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- "[%d] RecentsController.finishInner: toHome=%b userLeave=%b willFinishToHome=%b",
- mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome);
+ "[%d] RecentsController.finishInner: toHome=%b userLeave=%b "
+ + "willFinishToHome=%b state=%d",
+ mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome, mState);
final Transitions.TransitionFinishCallback finishCB = mFinishCB;
mFinishCB = null;
@@ -712,8 +721,19 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
if (toHome) wct.reorder(mRecentsTask, true /* toTop */);
else wct.restoreTransientOrder(mRecentsTask);
}
- if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " returning to app");
+ if (!toHome
+ // If a recents gesture starts on the 3p launcher, then the 3p launcher is the
+ // live tile (pausing app). If the gesture is "cancelled" we need to return to
+ // 3p launcher instead of "task-switching" away from it.
+ && (!mWillFinishToHome || mPausingSeparateHome)
+ && mPausingTasks != null && mState == STATE_NORMAL) {
+ if (mPausingSeparateHome) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " returning to 3p home");
+ } else {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " returning to app");
+ }
// The gesture is returning to the pausing-task(s) rather than continuing with
// recents, so end the transition by moving the app back to the top (and also
// re-showing it's task).
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f93afe81f804..ea0731ae346a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1996,6 +1996,24 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
+ @Override
+ public void focusTopTask(int displayId) {
+ enforceTaskPermission("focusTopTask()");
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final DisplayContent dc = mRootWindowContainer.getDisplayContent(displayId);
+ if (dc == null) return;
+ final Task task = dc.getTask((t) -> t.isLeafTask() && t.isFocusable(),
+ true /* traverseTopToBottom */);
+ if (task == null) return;
+ setFocusedTask(task.mTaskId, null /* touchedActivity */);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
void setFocusedTask(int taskId, ActivityRecord touchedActivity) {
ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d touchedActivity=%s", taskId,
touchedActivity);