Loading services/core/java/com/android/server/wm/ActivityMetricsLogger.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -300,9 +300,12 @@ class ActivityMetricsLogger { return; return; } } if (mLastLaunchedActivity != null) { if (mLastLaunchedActivity != null) { // Transfer the launch cookie because it is a consecutive launch event. // Transfer the launch cookie and launch root task because it is a consecutive // launch event. r.mLaunchCookie = mLastLaunchedActivity.mLaunchCookie; r.mLaunchCookie = mLastLaunchedActivity.mLaunchCookie; mLastLaunchedActivity.mLaunchCookie = null; mLastLaunchedActivity.mLaunchCookie = null; r.mLaunchRootTask = mLastLaunchedActivity.mLaunchRootTask; mLastLaunchedActivity.mLaunchRootTask = null; } } mLastLaunchedActivity = r; mLastLaunchedActivity = r; if (!r.noDisplay && !r.isReportedDrawn()) { if (!r.noDisplay && !r.isReportedDrawn()) { Loading services/core/java/com/android/server/wm/ActivityRecord.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -831,6 +831,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Tracking cookie for the launch of this activity and it's task. // Tracking cookie for the launch of this activity and it's task. IBinder mLaunchCookie; IBinder mLaunchCookie; // Tracking indicated launch root in order to propagate it among trampoline activities. WindowContainerToken mLaunchRootTask; // Entering PiP is usually done in two phases, we put the task into pinned mode first and // Entering PiP is usually done in two phases, we put the task into pinned mode first and // SystemUi sets the pinned mode on activity after transition is done. // SystemUi sets the pinned mode on activity after transition is done. boolean mWaitForEnteringPinnedMode; boolean mWaitForEnteringPinnedMode; Loading Loading @@ -1041,6 +1044,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.print("launchCookie="); pw.print("launchCookie="); pw.println(mLaunchCookie); pw.println(mLaunchCookie); } } if (mLaunchRootTask != null) { pw.print(prefix); pw.print("mLaunchRootTask="); pw.println(mLaunchRootTask); } pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState); pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState); pw.print(" mIcicle="); pw.println(mIcicle); pw.print(" mIcicle="); pw.println(mIcicle); pw.print(prefix); pw.print("state="); pw.print(mState); pw.print(prefix); pw.print("state="); pw.print(mState); Loading Loading @@ -1795,6 +1803,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; mHandoverLaunchDisplayId = options.getLaunchDisplayId(); mHandoverLaunchDisplayId = options.getLaunchDisplayId(); mLaunchCookie = options.getLaunchCookie(); mLaunchCookie = options.getLaunchCookie(); mLaunchRootTask = options.getLaunchRootTask(); } } mPersistentState = persistentState; mPersistentState = persistentState; Loading Loading @@ -5963,6 +5972,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (task != null) { if (task != null) { task.setHasBeenVisible(true); task.setHasBeenVisible(true); } } // Clear indicated launch root task because there's no trampoline activity to expect after // the windows are drawn. mLaunchRootTask = null; } } /** Called when the windows associated app window container are visible. */ /** Called when the windows associated app window container are visible. */ Loading services/core/java/com/android/server/wm/ActivityStarter.java +19 −6 Original line number Original line Diff line number Diff line Loading @@ -2586,13 +2586,28 @@ class ActivityStarter { /** /** * Figure out which task and activity to bring to front when we have found an existing matching * Figure out which task and activity to bring to front when we have found an existing matching * activity record in history. May also clear the task if needed. * activity record in history. May also clear the task if needed. * * @param intentActivity Existing matching activity. * @param intentActivity Existing matching activity. * @return {@link ActivityRecord} brought to front. * @return {@link ActivityRecord} brought to front. */ */ private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { mTargetRootTask = intentActivity.getRootTask(); intentActivity.getTaskFragment().clearLastPausedActivity(); intentActivity.getTaskFragment().clearLastPausedActivity(); Task intentTask = intentActivity.getTask(); Task intentTask = intentActivity.getTask(); // Only update the target-root-task when it is not indicated. if (mTargetRootTask == null) { if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { // Inherit the target-root-task from source to ensure trampoline activities will be // launched into the same root task. mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask); } else { final Task launchRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions); mTargetRootTask = launchRootTask != null ? launchRootTask : intentActivity.getRootTask(); } } // If the target task is not in the front, then we need to bring it to the front... // If the target task is not in the front, then we need to bring it to the front... // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have // the same behavior as if a new instance was being started, which means not bringing it // the same behavior as if a new instance was being started, which means not bringing it Loading Loading @@ -2620,9 +2635,7 @@ class ActivityStarter { intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); } } final Task launchRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, if (mTargetRootTask == intentActivity.getRootTask()) { intentTask, mOptions); if (launchRootTask == null || launchRootTask == mTargetRootTask) { // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels // tasks hierarchies. // tasks hierarchies. if (mTargetRootTask != intentTask if (mTargetRootTask != intentTask Loading @@ -2646,7 +2659,7 @@ class ActivityStarter { "bringingFoundTaskToFront"); "bringingFoundTaskToFront"); mMovedToFront = !wasTopOfVisibleRootTask; mMovedToFront = !wasTopOfVisibleRootTask; } else { } else { intentTask.reparent(launchRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); mMovedToFront = true; mMovedToFront = true; } } Loading services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.IBinder; import android.os.SystemClock; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.ArrayMap; import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; Loading Loading @@ -449,8 +450,10 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { @Test @Test public void testConsecutiveLaunchNewTask() { public void testConsecutiveLaunchNewTask() { final IBinder launchCookie = mock(IBinder.class); final IBinder launchCookie = mock(IBinder.class); final WindowContainerToken launchRootTask = mock(WindowContainerToken.class); mTrampolineActivity.noDisplay = true; mTrampolineActivity.noDisplay = true; mTrampolineActivity.mLaunchCookie = launchCookie; mTrampolineActivity.mLaunchCookie = launchCookie; mTrampolineActivity.mLaunchRootTask = launchRootTask; onActivityLaunched(mTrampolineActivity); onActivityLaunched(mTrampolineActivity); final ActivityRecord activityOnNewTask = new ActivityBuilder(mAtm) final ActivityRecord activityOnNewTask = new ActivityBuilder(mAtm) .setCreateTask(true) .setCreateTask(true) Loading @@ -464,6 +467,10 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { mTrampolineActivity.mLaunchCookie).isNull(); mTrampolineActivity.mLaunchCookie).isNull(); assertWithMessage("The last launch task has the transferred cookie").that( assertWithMessage("The last launch task has the transferred cookie").that( activityOnNewTask.mLaunchCookie).isEqualTo(launchCookie); activityOnNewTask.mLaunchCookie).isEqualTo(launchCookie); assertWithMessage("Trampoline's launch root task must be transferred").that( mTrampolineActivity.mLaunchRootTask).isNull(); assertWithMessage("The last launch task has the transferred launch root task").that( activityOnNewTask.mLaunchRootTask).isEqualTo(launchRootTask); } } @Test @Test Loading Loading
services/core/java/com/android/server/wm/ActivityMetricsLogger.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -300,9 +300,12 @@ class ActivityMetricsLogger { return; return; } } if (mLastLaunchedActivity != null) { if (mLastLaunchedActivity != null) { // Transfer the launch cookie because it is a consecutive launch event. // Transfer the launch cookie and launch root task because it is a consecutive // launch event. r.mLaunchCookie = mLastLaunchedActivity.mLaunchCookie; r.mLaunchCookie = mLastLaunchedActivity.mLaunchCookie; mLastLaunchedActivity.mLaunchCookie = null; mLastLaunchedActivity.mLaunchCookie = null; r.mLaunchRootTask = mLastLaunchedActivity.mLaunchRootTask; mLastLaunchedActivity.mLaunchRootTask = null; } } mLastLaunchedActivity = r; mLastLaunchedActivity = r; if (!r.noDisplay && !r.isReportedDrawn()) { if (!r.noDisplay && !r.isReportedDrawn()) { Loading
services/core/java/com/android/server/wm/ActivityRecord.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -831,6 +831,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Tracking cookie for the launch of this activity and it's task. // Tracking cookie for the launch of this activity and it's task. IBinder mLaunchCookie; IBinder mLaunchCookie; // Tracking indicated launch root in order to propagate it among trampoline activities. WindowContainerToken mLaunchRootTask; // Entering PiP is usually done in two phases, we put the task into pinned mode first and // Entering PiP is usually done in two phases, we put the task into pinned mode first and // SystemUi sets the pinned mode on activity after transition is done. // SystemUi sets the pinned mode on activity after transition is done. boolean mWaitForEnteringPinnedMode; boolean mWaitForEnteringPinnedMode; Loading Loading @@ -1041,6 +1044,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.print("launchCookie="); pw.print("launchCookie="); pw.println(mLaunchCookie); pw.println(mLaunchCookie); } } if (mLaunchRootTask != null) { pw.print(prefix); pw.print("mLaunchRootTask="); pw.println(mLaunchRootTask); } pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState); pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState); pw.print(" mIcicle="); pw.println(mIcicle); pw.print(" mIcicle="); pw.println(mIcicle); pw.print(prefix); pw.print("state="); pw.print(mState); pw.print(prefix); pw.print("state="); pw.print(mState); Loading Loading @@ -1795,6 +1803,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; mHandoverLaunchDisplayId = options.getLaunchDisplayId(); mHandoverLaunchDisplayId = options.getLaunchDisplayId(); mLaunchCookie = options.getLaunchCookie(); mLaunchCookie = options.getLaunchCookie(); mLaunchRootTask = options.getLaunchRootTask(); } } mPersistentState = persistentState; mPersistentState = persistentState; Loading Loading @@ -5963,6 +5972,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (task != null) { if (task != null) { task.setHasBeenVisible(true); task.setHasBeenVisible(true); } } // Clear indicated launch root task because there's no trampoline activity to expect after // the windows are drawn. mLaunchRootTask = null; } } /** Called when the windows associated app window container are visible. */ /** Called when the windows associated app window container are visible. */ Loading
services/core/java/com/android/server/wm/ActivityStarter.java +19 −6 Original line number Original line Diff line number Diff line Loading @@ -2586,13 +2586,28 @@ class ActivityStarter { /** /** * Figure out which task and activity to bring to front when we have found an existing matching * Figure out which task and activity to bring to front when we have found an existing matching * activity record in history. May also clear the task if needed. * activity record in history. May also clear the task if needed. * * @param intentActivity Existing matching activity. * @param intentActivity Existing matching activity. * @return {@link ActivityRecord} brought to front. * @return {@link ActivityRecord} brought to front. */ */ private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { mTargetRootTask = intentActivity.getRootTask(); intentActivity.getTaskFragment().clearLastPausedActivity(); intentActivity.getTaskFragment().clearLastPausedActivity(); Task intentTask = intentActivity.getTask(); Task intentTask = intentActivity.getTask(); // Only update the target-root-task when it is not indicated. if (mTargetRootTask == null) { if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { // Inherit the target-root-task from source to ensure trampoline activities will be // launched into the same root task. mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask); } else { final Task launchRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions); mTargetRootTask = launchRootTask != null ? launchRootTask : intentActivity.getRootTask(); } } // If the target task is not in the front, then we need to bring it to the front... // If the target task is not in the front, then we need to bring it to the front... // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have // the same behavior as if a new instance was being started, which means not bringing it // the same behavior as if a new instance was being started, which means not bringing it Loading Loading @@ -2620,9 +2635,7 @@ class ActivityStarter { intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); } } final Task launchRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, if (mTargetRootTask == intentActivity.getRootTask()) { intentTask, mOptions); if (launchRootTask == null || launchRootTask == mTargetRootTask) { // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels // tasks hierarchies. // tasks hierarchies. if (mTargetRootTask != intentTask if (mTargetRootTask != intentTask Loading @@ -2646,7 +2659,7 @@ class ActivityStarter { "bringingFoundTaskToFront"); "bringingFoundTaskToFront"); mMovedToFront = !wasTopOfVisibleRootTask; mMovedToFront = !wasTopOfVisibleRootTask; } else { } else { intentTask.reparent(launchRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); mMovedToFront = true; mMovedToFront = true; } } Loading
services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.IBinder; import android.os.SystemClock; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.ArrayMap; import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; Loading Loading @@ -449,8 +450,10 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { @Test @Test public void testConsecutiveLaunchNewTask() { public void testConsecutiveLaunchNewTask() { final IBinder launchCookie = mock(IBinder.class); final IBinder launchCookie = mock(IBinder.class); final WindowContainerToken launchRootTask = mock(WindowContainerToken.class); mTrampolineActivity.noDisplay = true; mTrampolineActivity.noDisplay = true; mTrampolineActivity.mLaunchCookie = launchCookie; mTrampolineActivity.mLaunchCookie = launchCookie; mTrampolineActivity.mLaunchRootTask = launchRootTask; onActivityLaunched(mTrampolineActivity); onActivityLaunched(mTrampolineActivity); final ActivityRecord activityOnNewTask = new ActivityBuilder(mAtm) final ActivityRecord activityOnNewTask = new ActivityBuilder(mAtm) .setCreateTask(true) .setCreateTask(true) Loading @@ -464,6 +467,10 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { mTrampolineActivity.mLaunchCookie).isNull(); mTrampolineActivity.mLaunchCookie).isNull(); assertWithMessage("The last launch task has the transferred cookie").that( assertWithMessage("The last launch task has the transferred cookie").that( activityOnNewTask.mLaunchCookie).isEqualTo(launchCookie); activityOnNewTask.mLaunchCookie).isEqualTo(launchCookie); assertWithMessage("Trampoline's launch root task must be transferred").that( mTrampolineActivity.mLaunchRootTask).isNull(); assertWithMessage("The last launch task has the transferred launch root task").that( activityOnNewTask.mLaunchRootTask).isEqualTo(launchRootTask); } } @Test @Test Loading