Loading services/core/java/com/android/server/wm/ActivityStack.java +21 −2 Original line number Diff line number Diff line Loading @@ -1311,8 +1311,17 @@ class ActivityStack extends Task { /** * Make sure that all activities that need to be visible in the stack (that is, they * currently can be seen by the user) actually are and update their configuration. * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * @param preserveWindows Flag indicating whether windows should be preserved when updating * configuration in {@link mEnsureActivitiesVisibleHelper}. * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen as part of * {@link mEnsureActivitiesVisibleHelper}. * */ void ensureActivitiesVisible(ActivityRecord starting, int configChanges, void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows) { ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); } Loading @@ -1321,9 +1330,19 @@ class ActivityStack extends Task { * Ensure visibility with an option to also update the configuration of visible activities. * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * @param notifyClients Flag indicating whether the visibility updates should be sent to the * clients in {@link mEnsureActivitiesVisibleHelper}. * @param preserveWindows Flag indicating whether windows should be preserved when updating * configuration in {@link mEnsureActivitiesVisibleHelper}. * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen as part of * {@link mEnsureActivitiesVisibleHelper}. */ // TODO: Should be re-worked based on the fact that each task as a stack in most cases. void ensureActivitiesVisible(ActivityRecord starting, int configChanges, void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { mTopActivityOccludesKeyguard = false; mTopDismissingKeyguardActivity = null; Loading services/core/java/com/android/server/wm/ActivityStarter.java +8 −2 Original line number Diff line number Diff line Loading @@ -1539,7 +1539,10 @@ class ActivityStarter { * * Note: This method should only be called from {@link #startActivityUnchecked}. */ private int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner @VisibleForTesting int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity) { Loading Loading @@ -1660,7 +1663,10 @@ class ActivityStarter { // Also, we don't want to resume activities in a task that currently has an overlay // as the starting activity just needs to be in the visible paused state until the // over is removed. mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS); // Passing {@code null} as the start parameter ensures all activities are made // visible. mTargetStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mTargetStack.getDisplay().mDisplayContent.executeAppTransition(); Loading services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static com.android.server.wm.ActivityStack.TAG_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; import android.annotation.Nullable; import android.util.Slog; import com.android.internal.util.function.pooled.PooledConsumer; Loading @@ -42,6 +43,16 @@ class EnsureActivitiesVisibleHelper { mContiner = container; } /** * Update all attributes except {@link mContiner} to use in subsequent calculations. * * @param starting The activity that is being started * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen. * @param preserveWindows Flag indicating whether windows should be preserved when updating. * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc * be sent to the clients. */ void reset(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { mStarting = starting; Loading @@ -60,8 +71,17 @@ class EnsureActivitiesVisibleHelper { * Ensure visibility with an option to also update the configuration of visible activities. * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean) * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen. * @param preserveWindows Flag indicating whether windows should be preserved when updating. * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc * be sent to the clients. */ void process(ActivityRecord starting, int configChanges, boolean preserveWindows, void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { reset(starting, configChanges, preserveWindows, notifyClients); Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +46 −5 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; Loading @@ -56,10 +57,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; Loading Loading @@ -99,7 +100,6 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class ActivityStarterTests extends ActivityTestsBase { private ActivityStarter mStarter; private ActivityStartController mController; private ActivityMetricsLogger mActivityMetricsLogger; private PackageManagerInternal mMockPackageManager; Loading Loading @@ -127,8 +127,6 @@ public class ActivityStarterTests extends ActivityTestsBase { mController = mock(ActivityStartController.class); mActivityMetricsLogger = mock(ActivityMetricsLogger.class); clearInvocations(mActivityMetricsLogger); mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); } @Test Loading Loading @@ -181,6 +179,7 @@ public class ActivityStarterTests extends ActivityTestsBase { * {@link ActivityStarter#execute} based on these preconditions and ensures the result matches * the expected. It is important to note that the method also checks side effects of the start, * such as ensuring {@link ActivityOptions#abort()} is called in the relevant scenarios. * * @param preconditions A bitmask representing the preconditions for the launch * @param launchFlags The launch flags to be provided by the launch {@link Intent}. * @param expectedResult The expected result from the launch. Loading @@ -202,7 +201,7 @@ public class ActivityStarterTests extends ActivityTestsBase { final WindowProcessController wpc = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP) ? null : new WindowProcessController(service, ai, null, 0, -1, null, listener); doReturn(wpc).when(service).getProcessController(anyObject()); doReturn(wpc).when(service).getProcessController(any()); final Intent intent = new Intent(); intent.setFlags(launchFlags); Loading Loading @@ -1034,4 +1033,46 @@ public class ActivityStarterTests extends ActivityTestsBase { verify(recentTasks, times(1)).add(any()); } @Test public void testStartActivityInner_allSplitScreenPrimaryActivitiesVisible() { // Given final ActivityStarter starter = prepareStarter(0, false); starter.setReason("testAllSplitScreenPrimaryActivitiesAreResumed"); final ActivityRecord targetRecord = new ActivityBuilder(mService).build(); targetRecord.setFocusable(false); targetRecord.setVisibility(false); final ActivityRecord sourceRecord = new ActivityBuilder(mService).build(); final ActivityStack stack = spy( mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, /* onTop */true)); stack.addChild(targetRecord); doReturn(stack).when(mRootWindowContainer) .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); starter.mStartActivity = new ActivityBuilder(mService).build(); // When starter.startActivityInner( /* r */targetRecord, /* sourceRecord */ sourceRecord, /* voiceSession */null, /* voiceInteractor */ null, /* startFlags */ 0, /* doResume */true, /* options */null, /* inTask */null, /* restrictedBgActivity */false); // Then verify(stack).ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); verify(targetRecord).makeVisibleIfNeeded(null, true); assertTrue(targetRecord.mVisibleRequested); } } Loading
services/core/java/com/android/server/wm/ActivityStack.java +21 −2 Original line number Diff line number Diff line Loading @@ -1311,8 +1311,17 @@ class ActivityStack extends Task { /** * Make sure that all activities that need to be visible in the stack (that is, they * currently can be seen by the user) actually are and update their configuration. * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * @param preserveWindows Flag indicating whether windows should be preserved when updating * configuration in {@link mEnsureActivitiesVisibleHelper}. * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen as part of * {@link mEnsureActivitiesVisibleHelper}. * */ void ensureActivitiesVisible(ActivityRecord starting, int configChanges, void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows) { ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); } Loading @@ -1321,9 +1330,19 @@ class ActivityStack extends Task { * Ensure visibility with an option to also update the configuration of visible activities. * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * @param notifyClients Flag indicating whether the visibility updates should be sent to the * clients in {@link mEnsureActivitiesVisibleHelper}. * @param preserveWindows Flag indicating whether windows should be preserved when updating * configuration in {@link mEnsureActivitiesVisibleHelper}. * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen as part of * {@link mEnsureActivitiesVisibleHelper}. */ // TODO: Should be re-worked based on the fact that each task as a stack in most cases. void ensureActivitiesVisible(ActivityRecord starting, int configChanges, void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { mTopActivityOccludesKeyguard = false; mTopDismissingKeyguardActivity = null; Loading
services/core/java/com/android/server/wm/ActivityStarter.java +8 −2 Original line number Diff line number Diff line Loading @@ -1539,7 +1539,10 @@ class ActivityStarter { * * Note: This method should only be called from {@link #startActivityUnchecked}. */ private int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner @VisibleForTesting int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity) { Loading Loading @@ -1660,7 +1663,10 @@ class ActivityStarter { // Also, we don't want to resume activities in a task that currently has an overlay // as the starting activity just needs to be in the visible paused state until the // over is removed. mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS); // Passing {@code null} as the start parameter ensures all activities are made // visible. mTargetStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mTargetStack.getDisplay().mDisplayContent.executeAppTransition(); Loading
services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static com.android.server.wm.ActivityStack.TAG_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; import android.annotation.Nullable; import android.util.Slog; import com.android.internal.util.function.pooled.PooledConsumer; Loading @@ -42,6 +43,16 @@ class EnsureActivitiesVisibleHelper { mContiner = container; } /** * Update all attributes except {@link mContiner} to use in subsequent calculations. * * @param starting The activity that is being started * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen. * @param preserveWindows Flag indicating whether windows should be preserved when updating. * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc * be sent to the clients. */ void reset(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { mStarting = starting; Loading @@ -60,8 +71,17 @@ class EnsureActivitiesVisibleHelper { * Ensure visibility with an option to also update the configuration of visible activities. * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean) * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean) * @param starting The top most activity in the task. * The activity is either starting or resuming. * Caller should ensure starting activity is visible. * * @param configChanges Parts of the configuration that changed for this activity for evaluating * if the screen should be frozen. * @param preserveWindows Flag indicating whether windows should be preserved when updating. * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc * be sent to the clients. */ void process(ActivityRecord starting, int configChanges, boolean preserveWindows, void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { reset(starting, configChanges, preserveWindows, notifyClients); Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +46 −5 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; Loading @@ -56,10 +57,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; Loading Loading @@ -99,7 +100,6 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class ActivityStarterTests extends ActivityTestsBase { private ActivityStarter mStarter; private ActivityStartController mController; private ActivityMetricsLogger mActivityMetricsLogger; private PackageManagerInternal mMockPackageManager; Loading Loading @@ -127,8 +127,6 @@ public class ActivityStarterTests extends ActivityTestsBase { mController = mock(ActivityStartController.class); mActivityMetricsLogger = mock(ActivityMetricsLogger.class); clearInvocations(mActivityMetricsLogger); mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); } @Test Loading Loading @@ -181,6 +179,7 @@ public class ActivityStarterTests extends ActivityTestsBase { * {@link ActivityStarter#execute} based on these preconditions and ensures the result matches * the expected. It is important to note that the method also checks side effects of the start, * such as ensuring {@link ActivityOptions#abort()} is called in the relevant scenarios. * * @param preconditions A bitmask representing the preconditions for the launch * @param launchFlags The launch flags to be provided by the launch {@link Intent}. * @param expectedResult The expected result from the launch. Loading @@ -202,7 +201,7 @@ public class ActivityStarterTests extends ActivityTestsBase { final WindowProcessController wpc = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP) ? null : new WindowProcessController(service, ai, null, 0, -1, null, listener); doReturn(wpc).when(service).getProcessController(anyObject()); doReturn(wpc).when(service).getProcessController(any()); final Intent intent = new Intent(); intent.setFlags(launchFlags); Loading Loading @@ -1034,4 +1033,46 @@ public class ActivityStarterTests extends ActivityTestsBase { verify(recentTasks, times(1)).add(any()); } @Test public void testStartActivityInner_allSplitScreenPrimaryActivitiesVisible() { // Given final ActivityStarter starter = prepareStarter(0, false); starter.setReason("testAllSplitScreenPrimaryActivitiesAreResumed"); final ActivityRecord targetRecord = new ActivityBuilder(mService).build(); targetRecord.setFocusable(false); targetRecord.setVisibility(false); final ActivityRecord sourceRecord = new ActivityBuilder(mService).build(); final ActivityStack stack = spy( mRootWindowContainer.getDefaultTaskDisplayArea() .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, /* onTop */true)); stack.addChild(targetRecord); doReturn(stack).when(mRootWindowContainer) .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); starter.mStartActivity = new ActivityBuilder(mService).build(); // When starter.startActivityInner( /* r */targetRecord, /* sourceRecord */ sourceRecord, /* voiceSession */null, /* voiceInteractor */ null, /* startFlags */ 0, /* doResume */true, /* options */null, /* inTask */null, /* restrictedBgActivity */false); // Then verify(stack).ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); verify(targetRecord).makeVisibleIfNeeded(null, true); assertTrue(targetRecord.mVisibleRequested); } }