Loading core/java/android/window/flags/windowing_sdk.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -188,3 +188,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { namespace: "windowing_sdk" name: "fix_bal_reparent_existing_task" description: "Avoid reparent existing task when the background launch is not allowed." bug: "434047695" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file services/core/java/com/android/server/wm/ActivityStarter.java +18 −7 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.BackgroundActivityStartController.BalVerdict; import com.android.server.wm.LaunchParamsController.LaunchParams; import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import com.android.window.flags.Flags; import java.io.PrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -200,7 +201,8 @@ class ActivityStarter { // If the code is BAL_BLOCK, background activity can only be started in an existing task that // contains an activity with same uid, or if activity starts are enabled in developer options. private BalVerdict mBalVerdict; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) BalVerdict mBalVerdict; private int mLaunchMode; private boolean mLaunchTaskBehind; Loading Loading @@ -2020,7 +2022,7 @@ class ActivityStarter { recordTransientLaunchIfNeeded(targetTaskTop); // Recycle the target task for this launch. startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants, balVerdict); recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); if (startResult != START_SUCCESS) { return startResult; } Loading Loading @@ -2383,7 +2385,7 @@ class ActivityStarter { */ @VisibleForTesting int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants, BalVerdict balVerdict) { NeededUriGrants intentGrants) { // Should not recycle task which is from a different user, just adding the starting // activity to the task. if (targetTask.mUserId != mStartActivity.mUserId) { Loading Loading @@ -3078,11 +3080,19 @@ class ActivityStarter { Task intentTask = intentActivity.getTask(); // The intent task might be reparented while in getOrCreateRootTask, caches the original // root task to distinguish if it is moving to front or not. final Task origRootTask = intentTask != null ? intentTask.getRootTask() : null; final Task origRootTask; if (Flags.fixBalReparentExistingTask()) { origRootTask = intentTask.getRootTask(); } else { origRootTask = intentTask != null ? intentTask.getRootTask() : null; } if (mTargetRootTask == null) { // Update launch target task when it is not indicated. if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { if (mTargetRootTask == null) { if (Flags.fixBalReparentExistingTask() && mBalVerdict.blocks()) { // Stays on the same root task if the activity launch is not allowed. mTargetRootTask = origRootTask; } else 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); Loading Loading @@ -3388,7 +3398,8 @@ class ActivityStarter { return launchFlags; } private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions) { final boolean onTop = (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +25 −2 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; Loading Loading @@ -1318,12 +1319,34 @@ public class ActivityStarterTests extends WindowTestsBase { .setUserId(10) .build(); final int result = starter.recycleTask(task, null, null, null, BalVerdict.ALLOW_PRIVILEGED); final int result = starter.recycleTask(task, null, null, null); assertThat(result == START_SUCCESS).isTrue(); assertThat(starter.mAddingToTask).isTrue(); } @Test @EnableFlags(Flags.FLAG_FIX_BAL_REPARENT_EXISTING_TASK) public void testRecycleTaskWhenBalBlocks() { final ActivityStarter starter = prepareStarter(0 /* flags */); starter.mStartActivity = new ActivityBuilder(mAtm).build(); starter.mBalVerdict = BalVerdict.BLOCK; final Task task = new TaskBuilder(mAtm.mTaskSupervisor) .setParentTask(createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD)) .setCreateActivity(true) .build(); final Task rootTask = task.getRootTask(); final ActivityRecord topActivity = task.getTopMostActivity(); spyOn(starter); final Task launchRootTask = new TaskBuilder(mAtm.mTaskSupervisor).build(); doReturn(launchRootTask).when(starter).getOrCreateRootTask(eq(starter.mStartActivity), anyInt(), eq(task), any()); starter.recycleTask(task, topActivity, task, null); assertThat(rootTask == task.getRootTask()).isTrue(); } @Test public void testRecycleTaskWakeUpWhenDreaming() { doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyInt(), anyString()); Loading Loading
core/java/android/window/flags/windowing_sdk.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -188,3 +188,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { namespace: "windowing_sdk" name: "fix_bal_reparent_existing_task" description: "Avoid reparent existing task when the background launch is not allowed." bug: "434047695" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file
services/core/java/com/android/server/wm/ActivityStarter.java +18 −7 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.BackgroundActivityStartController.BalVerdict; import com.android.server.wm.LaunchParamsController.LaunchParams; import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import com.android.window.flags.Flags; import java.io.PrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -200,7 +201,8 @@ class ActivityStarter { // If the code is BAL_BLOCK, background activity can only be started in an existing task that // contains an activity with same uid, or if activity starts are enabled in developer options. private BalVerdict mBalVerdict; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) BalVerdict mBalVerdict; private int mLaunchMode; private boolean mLaunchTaskBehind; Loading Loading @@ -2020,7 +2022,7 @@ class ActivityStarter { recordTransientLaunchIfNeeded(targetTaskTop); // Recycle the target task for this launch. startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants, balVerdict); recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); if (startResult != START_SUCCESS) { return startResult; } Loading Loading @@ -2383,7 +2385,7 @@ class ActivityStarter { */ @VisibleForTesting int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants, BalVerdict balVerdict) { NeededUriGrants intentGrants) { // Should not recycle task which is from a different user, just adding the starting // activity to the task. if (targetTask.mUserId != mStartActivity.mUserId) { Loading Loading @@ -3078,11 +3080,19 @@ class ActivityStarter { Task intentTask = intentActivity.getTask(); // The intent task might be reparented while in getOrCreateRootTask, caches the original // root task to distinguish if it is moving to front or not. final Task origRootTask = intentTask != null ? intentTask.getRootTask() : null; final Task origRootTask; if (Flags.fixBalReparentExistingTask()) { origRootTask = intentTask.getRootTask(); } else { origRootTask = intentTask != null ? intentTask.getRootTask() : null; } if (mTargetRootTask == null) { // Update launch target task when it is not indicated. if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { if (mTargetRootTask == null) { if (Flags.fixBalReparentExistingTask() && mBalVerdict.blocks()) { // Stays on the same root task if the activity launch is not allowed. mTargetRootTask = origRootTask; } else 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); Loading Loading @@ -3388,7 +3398,8 @@ class ActivityStarter { return launchFlags; } private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions) { final boolean onTop = (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +25 −2 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; Loading Loading @@ -1318,12 +1319,34 @@ public class ActivityStarterTests extends WindowTestsBase { .setUserId(10) .build(); final int result = starter.recycleTask(task, null, null, null, BalVerdict.ALLOW_PRIVILEGED); final int result = starter.recycleTask(task, null, null, null); assertThat(result == START_SUCCESS).isTrue(); assertThat(starter.mAddingToTask).isTrue(); } @Test @EnableFlags(Flags.FLAG_FIX_BAL_REPARENT_EXISTING_TASK) public void testRecycleTaskWhenBalBlocks() { final ActivityStarter starter = prepareStarter(0 /* flags */); starter.mStartActivity = new ActivityBuilder(mAtm).build(); starter.mBalVerdict = BalVerdict.BLOCK; final Task task = new TaskBuilder(mAtm.mTaskSupervisor) .setParentTask(createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD)) .setCreateActivity(true) .build(); final Task rootTask = task.getRootTask(); final ActivityRecord topActivity = task.getTopMostActivity(); spyOn(starter); final Task launchRootTask = new TaskBuilder(mAtm.mTaskSupervisor).build(); doReturn(launchRootTask).when(starter).getOrCreateRootTask(eq(starter.mStartActivity), anyInt(), eq(task), any()); starter.recycleTask(task, topActivity, task, null); assertThat(rootTask == task.getRootTask()).isTrue(); } @Test public void testRecycleTaskWakeUpWhenDreaming() { doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyInt(), anyString()); Loading