Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +124 −59 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; import android.view.IRecentsAnimationController; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; Loading Loading @@ -106,12 +105,24 @@ public class RemoteTransitionCompat { private RecentsAnimationListener mListener = null; private RecentsAnimationControllerCompat mWrapped = null; private IRemoteTransitionFinishedCallback mFinishCB = null; /** * List of tasks that we are switching away from via this transition. Upon finish, these * pausing tasks will become invisible. * These need to be ordered since the order must be restored if there is no task-switch. */ private ArrayList<TaskState> mPausingTasks = null; /** * List of tasks that we are switching to. Upon finish, these will remain visible and * on top. */ private ArrayList<TaskState> mOpeningTasks = null; private WindowContainerToken mPipTask = null; private WindowContainerToken mRecentsTask = null; private int mRecentsTaskId = 0; private TransitionInfo mInfo = null; private ArrayList<SurfaceControl> mOpeningLeashes = null; private boolean mOpeningSeparateHome = false; private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; private PictureInPictureSurfaceTransaction mPipTransaction = null; Loading @@ -120,6 +131,15 @@ public class RemoteTransitionCompat { private RemoteAnimationTarget[] mAppearedTargets; private boolean mWillFinishToHome = false; /** The animation is idle, waiting for the user to choose a task to switch to. */ private static final int STATE_NORMAL = 0; /** The user chose a new task to switch to and the animation is animating to it. */ private static final int STATE_NEW_TASK = 1; /** The latest state that the recents animation is operating in. */ private int mState = STATE_NORMAL; void start(RecentsAnimationControllerCompat wrapped, RecentsAnimationListener listener, IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishedCallback) { Loading @@ -132,12 +152,14 @@ public class RemoteTransitionCompat { mInfo = info; mFinishCB = finishedCallback; mPausingTasks = new ArrayList<>(); mOpeningTasks = new ArrayList<>(); mPipTask = null; mRecentsTask = null; mRecentsTaskId = -1; mLeashMap = new ArrayMap<>(); mTransition = transition; mKeyguardLocked = (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0; mState = STATE_NORMAL; final ArrayList<RemoteAnimationTarget> apps = new ArrayList<>(); final ArrayList<RemoteAnimationTarget> wallpapers = new ArrayList<>(); Loading Loading @@ -178,6 +200,9 @@ public class RemoteTransitionCompat { } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { mRecentsTask = taskInfo.token; mRecentsTaskId = taskInfo.taskId; } else if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { mOpeningTasks.add(new TaskState(change, target.leash)); } } } Loading @@ -189,34 +214,41 @@ public class RemoteTransitionCompat { @SuppressLint("NewApi") boolean merge(TransitionInfo info, SurfaceControl.Transaction t) { SparseArray<TransitionInfo.Change> openingTasks = null; ArrayList<TransitionInfo.Change> openingTasks = null; ArrayList<TransitionInfo.Change> closingTasks = null; mAppearedTargets = null; boolean foundHomeOpening = false; mOpeningSeparateHome = false; TransitionInfo.Change recentsOpening = null; boolean foundRecentsClosing = false; boolean hasChangingApp = false; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final RemoteAnimationTargetCompat.LeafTaskFilter leafTaskFilter = new RemoteAnimationTargetCompat.LeafTaskFilter(); for (int i = 0; i < info.getChanges().size(); ++i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); if (taskInfo != null) { final boolean isLeafTask = leafTaskFilter.test(change); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { if (mRecentsTask.equals(change.getContainer())) { recentsOpening = change; } else if (isLeafTask) { if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { // This is usually a 3p launcher foundHomeOpening = true; mOpeningSeparateHome = true; } if (openingTasks == null) { openingTasks = new SparseArray<>(); } if (taskInfo.hasParentTask()) { // Collects opening leaf tasks only since Launcher monitors leaf task // ids to perform recents animation. openingTasks.remove(taskInfo.parentTaskId); openingTasks = new ArrayList<>(); } openingTasks.put(taskInfo.taskId, change); openingTasks.add(change); } } else if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) { if (mRecentsTask.equals(change.getContainer())) { foundRecentsClosing = true; } else if (isLeafTask) { if (closingTasks == null) { closingTasks = new ArrayList<>(); } closingTasks.add(change); } } else if (change.getMode() == TRANSIT_CHANGE) { hasChangingApp = true; Loading @@ -234,45 +266,72 @@ public class RemoteTransitionCompat { } return false; } if (openingTasks == null) return false; int pauseMatches = 0; if (!foundHomeOpening) { for (int i = 0; i < openingTasks.size(); ++i) { if (TaskState.indexOf(mPausingTasks, openingTasks.valueAt(i)) >= 0) { ++pauseMatches; } } } if (pauseMatches > 0) { if (pauseMatches != mPausingTasks.size()) { // We are not really "returning" properly... something went wrong. throw new IllegalStateException("\"Concelling\" a recents transitions by " + "unpausing " + pauseMatches + " apps after pausing " + mPausingTasks.size() + " apps."); } // In this case, we are "returning" to an already running app, so just consume // the merge and do nothing. info.releaseAllSurfaces(); t.close(); return true; } if (recentsOpening != null) { // the recents task re-appeared. This happens if the user gestures before the // task-switch (NEW_TASK) animation finishes. if (mState == STATE_NORMAL) { Log.e(TAG, "Returning to recents while recents is already idle."); } if (closingTasks == null || closingTasks.size() == 0) { Log.e(TAG, "Returning to recents without closing any opening tasks."); } // Setup may hide it initially since it doesn't know that overview was still active. t.show(recentsOpening.getLeash()); t.setAlpha(recentsOpening.getLeash(), 1.f); mState = STATE_NORMAL; } boolean didMergeThings = false; if (closingTasks != null) { // Cancelling a task-switch. Move the tasks back to mPausing from mOpening for (int i = 0; i < closingTasks.size(); ++i) { final TransitionInfo.Change change = closingTasks.get(i); int openingIdx = TaskState.indexOf(mOpeningTasks, change); if (openingIdx < 0) { Log.e(TAG, "Back to existing recents animation from an unrecognized " + "task: " + change.getTaskInfo().taskId); continue; } mPausingTasks.add(mOpeningTasks.remove(openingIdx)); didMergeThings = true; } } if (openingTasks != null && openingTasks.size() > 0) { // Switching to some new tasks, add to mOpening and remove from mPausing. Also, // enter NEW_TASK state since this will start the switch-to animation. final int layer = mInfo.getChanges().size() * 3; mOpeningLeashes = new ArrayList<>(); mOpeningSeparateHome = foundHomeOpening; final RemoteAnimationTarget[] targets = new RemoteAnimationTarget[openingTasks.size()]; for (int i = 0; i < openingTasks.size(); ++i) { final TransitionInfo.Change change = openingTasks.valueAt(i); mOpeningLeashes.add(change.getLeash()); final TransitionInfo.Change change = openingTasks.get(i); int pausingIdx = TaskState.indexOf(mPausingTasks, change); if (pausingIdx >= 0) { // Something is showing/opening a previously-pausing app. targets[i] = newTarget(change, layer, mPausingTasks.get(pausingIdx).mLeash); mOpeningTasks.add(mPausingTasks.remove(pausingIdx)); // Setup hides opening tasks initially, so make it visible again (since we // are already showing it). t.show(change.getLeash()); t.setAlpha(change.getLeash(), 1.f); } else { // We are receiving new opening tasks, so convert to onTasksAppeared. targets[i] = newTarget(change, layer, info, t, mLeashMap); t.reparent(targets[i].leash, mInfo.getRootLeash()); t.setLayer(targets[i].leash, layer); mOpeningTasks.add(new TaskState(change, targets[i].leash)); } } didMergeThings = true; mState = STATE_NEW_TASK; mAppearedTargets = targets; } if (!didMergeThings) { // Didn't recognize anything in incoming transition so don't merge it. Log.w(TAG, "Don't know how to merge this transition."); return false; } t.apply(); // not using the incoming anim-only surfaces info.releaseAnimSurfaces(); mAppearedTargets = targets; return true; } Loading Loading @@ -300,6 +359,8 @@ public class RemoteTransitionCompat { if (enabled) { // 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 // animation finished. try { ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId); } catch (RemoteException e) { Loading Loading @@ -336,8 +397,8 @@ public class RemoteTransitionCompat { if (toHome) wct.reorder(mRecentsTask, true /* toTop */); else wct.restoreTransientOrder(mRecentsTask); } if (!toHome && !mWillFinishToHome && mPausingTasks != null && mOpeningLeashes == null) { // The gesture went back to opening the app rather than continuing with if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) { // 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). for (int i = mPausingTasks.size() - 1; i >= 0; --i) { Loading @@ -349,25 +410,28 @@ public class RemoteTransitionCompat { wct.restoreTransientOrder(mRecentsTask); } } else if (toHome && mOpeningSeparateHome && mPausingTasks != null) { // Special situaition where 3p launcher was changed during recents (this happens // Special situation where 3p launcher was changed during recents (this happens // during tapltests...). Here we get both "return to home" AND "home opening". // This is basically going home, but we have to restore recents order and also // treat the home "pausing" task properly. for (int i = mPausingTasks.size() - 1; i >= 0; --i) { final TaskState state = mPausingTasks.get(i); // This is basically going home, but we have to restore the recents and home order. for (int i = 0; i < mOpeningTasks.size(); ++i) { final TaskState state = mOpeningTasks.get(i); if (state.mTaskInfo.topActivityType == ACTIVITY_TYPE_HOME) { // Treat as opening (see above) // Make sure it is on top. wct.reorder(state.mToken, true /* onTop */); } t.show(state.mTaskSurface); } else { // Treat as hiding (see below) t.hide(state.mTaskSurface); } for (int i = mPausingTasks.size() - 1; i >= 0; --i) { t.hide(mPausingTasks.get(i).mTaskSurface); } if (!mKeyguardLocked && mRecentsTask != null) { wct.restoreTransientOrder(mRecentsTask); } } else { // The general case: committing to recents, going home, or switching tasks. for (int i = 0; i < mOpeningTasks.size(); ++i) { t.show(mOpeningTasks.get(i).mTaskSurface); } for (int i = 0; i < mPausingTasks.size(); ++i) { if (!sendUserLeaveHint) { // This means recents is not *actually* finishing, so of course we gotta Loading @@ -391,7 +455,7 @@ public class RemoteTransitionCompat { try { mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t); } catch (RemoteException e) { Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e); Log.e(TAG, "Failed to call animation finish callback", e); t.apply(); } // Only release the non-local created surface references. The animator is responsible Loading @@ -402,12 +466,13 @@ public class RemoteTransitionCompat { mListener = null; mFinishCB = null; mPausingTasks = null; mOpeningTasks = null; mAppearedTargets = null; mInfo = null; mOpeningLeashes = null; mOpeningSeparateHome = false; mLeashMap = null; mTransition = null; mState = STATE_NORMAL; } @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) { Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +19 −1 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; Loading Loading @@ -2034,7 +2035,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return; } if (r.moveFocusableActivityToTop("setFocusedTask")) { final Transition transition = (getTransitionController().isCollecting() || !getTransitionController().isShellTransitionsEnabled()) ? null : getTransitionController().createTransition(TRANSIT_TO_FRONT); if (transition != null) { // Set ready before doing anything. If order does change, then that will set it unready // so that we wait for the new lifecycles to complete. transition.setReady(task, true /* ready */); } final boolean movedToTop = r.moveFocusableActivityToTop("setFocusedTask"); if (movedToTop) { if (transition != null) { getTransitionController().requestStartTransition( transition, null /* startTask */, null /* remote */, null /* display */); } mRootWindowContainer.resumeFocusedTasksTopActivities(); } else if (touchedActivity != null && touchedActivity.isFocusable()) { final TaskFragment parent = touchedActivity.getTaskFragment(); Loading @@ -2046,6 +2060,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { true /* updateInputWindows */); } } if (transition != null && !movedToTop) { // No order changes and focus-changes, alone, aren't captured in transitions. transition.abort(); } } @Override Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +124 −59 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; import android.view.IRecentsAnimationController; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; Loading Loading @@ -106,12 +105,24 @@ public class RemoteTransitionCompat { private RecentsAnimationListener mListener = null; private RecentsAnimationControllerCompat mWrapped = null; private IRemoteTransitionFinishedCallback mFinishCB = null; /** * List of tasks that we are switching away from via this transition. Upon finish, these * pausing tasks will become invisible. * These need to be ordered since the order must be restored if there is no task-switch. */ private ArrayList<TaskState> mPausingTasks = null; /** * List of tasks that we are switching to. Upon finish, these will remain visible and * on top. */ private ArrayList<TaskState> mOpeningTasks = null; private WindowContainerToken mPipTask = null; private WindowContainerToken mRecentsTask = null; private int mRecentsTaskId = 0; private TransitionInfo mInfo = null; private ArrayList<SurfaceControl> mOpeningLeashes = null; private boolean mOpeningSeparateHome = false; private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; private PictureInPictureSurfaceTransaction mPipTransaction = null; Loading @@ -120,6 +131,15 @@ public class RemoteTransitionCompat { private RemoteAnimationTarget[] mAppearedTargets; private boolean mWillFinishToHome = false; /** The animation is idle, waiting for the user to choose a task to switch to. */ private static final int STATE_NORMAL = 0; /** The user chose a new task to switch to and the animation is animating to it. */ private static final int STATE_NEW_TASK = 1; /** The latest state that the recents animation is operating in. */ private int mState = STATE_NORMAL; void start(RecentsAnimationControllerCompat wrapped, RecentsAnimationListener listener, IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishedCallback) { Loading @@ -132,12 +152,14 @@ public class RemoteTransitionCompat { mInfo = info; mFinishCB = finishedCallback; mPausingTasks = new ArrayList<>(); mOpeningTasks = new ArrayList<>(); mPipTask = null; mRecentsTask = null; mRecentsTaskId = -1; mLeashMap = new ArrayMap<>(); mTransition = transition; mKeyguardLocked = (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0; mState = STATE_NORMAL; final ArrayList<RemoteAnimationTarget> apps = new ArrayList<>(); final ArrayList<RemoteAnimationTarget> wallpapers = new ArrayList<>(); Loading Loading @@ -178,6 +200,9 @@ public class RemoteTransitionCompat { } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { mRecentsTask = taskInfo.token; mRecentsTaskId = taskInfo.taskId; } else if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { mOpeningTasks.add(new TaskState(change, target.leash)); } } } Loading @@ -189,34 +214,41 @@ public class RemoteTransitionCompat { @SuppressLint("NewApi") boolean merge(TransitionInfo info, SurfaceControl.Transaction t) { SparseArray<TransitionInfo.Change> openingTasks = null; ArrayList<TransitionInfo.Change> openingTasks = null; ArrayList<TransitionInfo.Change> closingTasks = null; mAppearedTargets = null; boolean foundHomeOpening = false; mOpeningSeparateHome = false; TransitionInfo.Change recentsOpening = null; boolean foundRecentsClosing = false; boolean hasChangingApp = false; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final RemoteAnimationTargetCompat.LeafTaskFilter leafTaskFilter = new RemoteAnimationTargetCompat.LeafTaskFilter(); for (int i = 0; i < info.getChanges().size(); ++i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); if (taskInfo != null) { final boolean isLeafTask = leafTaskFilter.test(change); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { if (mRecentsTask.equals(change.getContainer())) { recentsOpening = change; } else if (isLeafTask) { if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { // This is usually a 3p launcher foundHomeOpening = true; mOpeningSeparateHome = true; } if (openingTasks == null) { openingTasks = new SparseArray<>(); } if (taskInfo.hasParentTask()) { // Collects opening leaf tasks only since Launcher monitors leaf task // ids to perform recents animation. openingTasks.remove(taskInfo.parentTaskId); openingTasks = new ArrayList<>(); } openingTasks.put(taskInfo.taskId, change); openingTasks.add(change); } } else if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) { if (mRecentsTask.equals(change.getContainer())) { foundRecentsClosing = true; } else if (isLeafTask) { if (closingTasks == null) { closingTasks = new ArrayList<>(); } closingTasks.add(change); } } else if (change.getMode() == TRANSIT_CHANGE) { hasChangingApp = true; Loading @@ -234,45 +266,72 @@ public class RemoteTransitionCompat { } return false; } if (openingTasks == null) return false; int pauseMatches = 0; if (!foundHomeOpening) { for (int i = 0; i < openingTasks.size(); ++i) { if (TaskState.indexOf(mPausingTasks, openingTasks.valueAt(i)) >= 0) { ++pauseMatches; } } } if (pauseMatches > 0) { if (pauseMatches != mPausingTasks.size()) { // We are not really "returning" properly... something went wrong. throw new IllegalStateException("\"Concelling\" a recents transitions by " + "unpausing " + pauseMatches + " apps after pausing " + mPausingTasks.size() + " apps."); } // In this case, we are "returning" to an already running app, so just consume // the merge and do nothing. info.releaseAllSurfaces(); t.close(); return true; } if (recentsOpening != null) { // the recents task re-appeared. This happens if the user gestures before the // task-switch (NEW_TASK) animation finishes. if (mState == STATE_NORMAL) { Log.e(TAG, "Returning to recents while recents is already idle."); } if (closingTasks == null || closingTasks.size() == 0) { Log.e(TAG, "Returning to recents without closing any opening tasks."); } // Setup may hide it initially since it doesn't know that overview was still active. t.show(recentsOpening.getLeash()); t.setAlpha(recentsOpening.getLeash(), 1.f); mState = STATE_NORMAL; } boolean didMergeThings = false; if (closingTasks != null) { // Cancelling a task-switch. Move the tasks back to mPausing from mOpening for (int i = 0; i < closingTasks.size(); ++i) { final TransitionInfo.Change change = closingTasks.get(i); int openingIdx = TaskState.indexOf(mOpeningTasks, change); if (openingIdx < 0) { Log.e(TAG, "Back to existing recents animation from an unrecognized " + "task: " + change.getTaskInfo().taskId); continue; } mPausingTasks.add(mOpeningTasks.remove(openingIdx)); didMergeThings = true; } } if (openingTasks != null && openingTasks.size() > 0) { // Switching to some new tasks, add to mOpening and remove from mPausing. Also, // enter NEW_TASK state since this will start the switch-to animation. final int layer = mInfo.getChanges().size() * 3; mOpeningLeashes = new ArrayList<>(); mOpeningSeparateHome = foundHomeOpening; final RemoteAnimationTarget[] targets = new RemoteAnimationTarget[openingTasks.size()]; for (int i = 0; i < openingTasks.size(); ++i) { final TransitionInfo.Change change = openingTasks.valueAt(i); mOpeningLeashes.add(change.getLeash()); final TransitionInfo.Change change = openingTasks.get(i); int pausingIdx = TaskState.indexOf(mPausingTasks, change); if (pausingIdx >= 0) { // Something is showing/opening a previously-pausing app. targets[i] = newTarget(change, layer, mPausingTasks.get(pausingIdx).mLeash); mOpeningTasks.add(mPausingTasks.remove(pausingIdx)); // Setup hides opening tasks initially, so make it visible again (since we // are already showing it). t.show(change.getLeash()); t.setAlpha(change.getLeash(), 1.f); } else { // We are receiving new opening tasks, so convert to onTasksAppeared. targets[i] = newTarget(change, layer, info, t, mLeashMap); t.reparent(targets[i].leash, mInfo.getRootLeash()); t.setLayer(targets[i].leash, layer); mOpeningTasks.add(new TaskState(change, targets[i].leash)); } } didMergeThings = true; mState = STATE_NEW_TASK; mAppearedTargets = targets; } if (!didMergeThings) { // Didn't recognize anything in incoming transition so don't merge it. Log.w(TAG, "Don't know how to merge this transition."); return false; } t.apply(); // not using the incoming anim-only surfaces info.releaseAnimSurfaces(); mAppearedTargets = targets; return true; } Loading Loading @@ -300,6 +359,8 @@ public class RemoteTransitionCompat { if (enabled) { // 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 // animation finished. try { ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId); } catch (RemoteException e) { Loading Loading @@ -336,8 +397,8 @@ public class RemoteTransitionCompat { if (toHome) wct.reorder(mRecentsTask, true /* toTop */); else wct.restoreTransientOrder(mRecentsTask); } if (!toHome && !mWillFinishToHome && mPausingTasks != null && mOpeningLeashes == null) { // The gesture went back to opening the app rather than continuing with if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) { // 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). for (int i = mPausingTasks.size() - 1; i >= 0; --i) { Loading @@ -349,25 +410,28 @@ public class RemoteTransitionCompat { wct.restoreTransientOrder(mRecentsTask); } } else if (toHome && mOpeningSeparateHome && mPausingTasks != null) { // Special situaition where 3p launcher was changed during recents (this happens // Special situation where 3p launcher was changed during recents (this happens // during tapltests...). Here we get both "return to home" AND "home opening". // This is basically going home, but we have to restore recents order and also // treat the home "pausing" task properly. for (int i = mPausingTasks.size() - 1; i >= 0; --i) { final TaskState state = mPausingTasks.get(i); // This is basically going home, but we have to restore the recents and home order. for (int i = 0; i < mOpeningTasks.size(); ++i) { final TaskState state = mOpeningTasks.get(i); if (state.mTaskInfo.topActivityType == ACTIVITY_TYPE_HOME) { // Treat as opening (see above) // Make sure it is on top. wct.reorder(state.mToken, true /* onTop */); } t.show(state.mTaskSurface); } else { // Treat as hiding (see below) t.hide(state.mTaskSurface); } for (int i = mPausingTasks.size() - 1; i >= 0; --i) { t.hide(mPausingTasks.get(i).mTaskSurface); } if (!mKeyguardLocked && mRecentsTask != null) { wct.restoreTransientOrder(mRecentsTask); } } else { // The general case: committing to recents, going home, or switching tasks. for (int i = 0; i < mOpeningTasks.size(); ++i) { t.show(mOpeningTasks.get(i).mTaskSurface); } for (int i = 0; i < mPausingTasks.size(); ++i) { if (!sendUserLeaveHint) { // This means recents is not *actually* finishing, so of course we gotta Loading @@ -391,7 +455,7 @@ public class RemoteTransitionCompat { try { mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t); } catch (RemoteException e) { Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e); Log.e(TAG, "Failed to call animation finish callback", e); t.apply(); } // Only release the non-local created surface references. The animator is responsible Loading @@ -402,12 +466,13 @@ public class RemoteTransitionCompat { mListener = null; mFinishCB = null; mPausingTasks = null; mOpeningTasks = null; mAppearedTargets = null; mInfo = null; mOpeningLeashes = null; mOpeningSeparateHome = false; mLeashMap = null; mTransition = null; mState = STATE_NORMAL; } @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) { Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +19 −1 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; Loading Loading @@ -2034,7 +2035,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return; } if (r.moveFocusableActivityToTop("setFocusedTask")) { final Transition transition = (getTransitionController().isCollecting() || !getTransitionController().isShellTransitionsEnabled()) ? null : getTransitionController().createTransition(TRANSIT_TO_FRONT); if (transition != null) { // Set ready before doing anything. If order does change, then that will set it unready // so that we wait for the new lifecycles to complete. transition.setReady(task, true /* ready */); } final boolean movedToTop = r.moveFocusableActivityToTop("setFocusedTask"); if (movedToTop) { if (transition != null) { getTransitionController().requestStartTransition( transition, null /* startTask */, null /* remote */, null /* display */); } mRootWindowContainer.resumeFocusedTasksTopActivities(); } else if (touchedActivity != null && touchedActivity.isFocusable()) { final TaskFragment parent = touchedActivity.getTaskFragment(); Loading @@ -2046,6 +2060,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { true /* updateInputWindows */); } } if (transition != null && !movedToTop) { // No order changes and focus-changes, alone, aren't captured in transitions. transition.abort(); } } @Override Loading