diff options
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); |