Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd3592af authored by Louis Chang's avatar Louis Chang
Browse files

Fix home can not be started while instrumenting

We don't want to automatically start home activities while
the home app is being instrumented because it prevents home
activities unexpectedly resumed during testing.

We should still allow launching home activities if requested
(e.g. starting home activity when home key pressed).

Bug: 118891218
Test: atest TaplTests
Test: atest ActivityStackSupervisorTests
Test: atest ActivityManagerMultiDisplayTests

Change-Id: Ia362f875d38748a3dea40b5788a4d86bcc68392c
parent 74514bcb
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -789,7 +789,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return startHomeOnDisplay(mCurrentUser, myReason, displayId);
    }

    boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId) {
    /**
     * Check if home activity start should be allowed on a display.
     * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
     * @param displayId The id of the target display.
     * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
     * @return {@code true} if allow to launch, {@code false} otherwise.
     */
    boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
            boolean allowInstrumenting) {
        if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mService.mTopAction == null) {
            // We are running in factory test mode, but unable to find the factory test app, so
@@ -799,7 +807,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D

        final WindowProcessController app =
                mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
        if (app != null && app.isInstrumenting()) {
        if (!allowInstrumenting && app != null && app.isInstrumenting()) {
            // Don't do this if the home app is currently being instrumented.
            return false;
        }
@@ -4240,7 +4248,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            return false;
        }

        if (!canStartHomeOnDisplay(aInfo, displayId)) {
        if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
            return false;
        }

+4 −4
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -72,7 +73,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;

@@ -114,9 +114,9 @@ import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.EventLogTags;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
import com.android.server.wm.LaunchParamsController.LaunchParams;
import com.android.server.pm.InstantAppResolver;

import java.io.PrintWriter;
import java.text.DateFormat;
@@ -1284,8 +1284,8 @@ class ActivityStarter {
        // Do not start home activity if it cannot be launched on preferred display. We are not
        // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
        // fallback to launch on other displays.
        if (r.isActivityTypeHome()
                && !mSupervisor.canStartHomeOnDisplay(r.info, mPreferredDisplayId)) {
        if (r.isActivityTypeHome() && !mSupervisor.canStartHomeOnDisplay(r.info,
                mPreferredDisplayId, true /* allowInstrumenting */)) {
            Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
            return START_CANCELED;
        }
+32 −4
Original line number Diff line number Diff line
@@ -25,12 +25,12 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.view.Display.DEFAULT_DISPLAY;

import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;


import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
@@ -54,6 +54,8 @@ import static org.mockito.Mockito.verify;

import android.app.ActivityOptions;
import android.app.WaitResult;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;

@@ -436,7 +438,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
     * Tests that home activities can be started on the displays that supports system decorations.
     */
    @Test
    public void testStartHomeOnAllDisplays() throws Exception {
    public void testStartHomeOnAllDisplays() {
        // Create secondary displays.
        final TestActivityDisplay secondDisplay = spy(createNewActivityDisplay());
        mSupervisor.addChild(secondDisplay, POSITION_TOP);
@@ -450,7 +452,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
                .create(any(), anyInt(), any(), any(), any(), any());
        doReturn(true).when(mService.mStackSupervisor)
                .ensureVisibilityAndConfig(any(), anyInt(), anyBoolean(), anyBoolean());
        doReturn(true).when(mSupervisor).canStartHomeOnDisplay(any(), anyInt());
        doReturn(true).when(mSupervisor).canStartHomeOnDisplay(any(), anyInt(), anyBoolean());

        mSupervisor.startHomeOnAllDisplays(0, "testStartHome");

@@ -463,7 +465,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
     * Tests that home activities won't be started before booting when display added.
     */
    @Test
    public void testNotStartHomeBeforeBoot() throws Exception {
    public void testNotStartHomeBeforeBoot() {
        final int displayId = 1;
        final boolean isBooting = mService.mAmInternal.isBooting();
        final boolean isBooted = mService.mAmInternal.isBooted();
@@ -477,4 +479,30 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
            mService.mAmInternal.setBooted(isBooted);
        }
    }

    /**
     * Tests whether home can be started if being instrumented.
     */
    @Test
    public void testCanStartHomeWhenInstrumented() {
        final ActivityInfo info = new ActivityInfo();
        info.applicationInfo = new ApplicationInfo();
        final WindowProcessController app = mock(WindowProcessController.class);
        doReturn(app).when(mService).getProcessController(any(), anyInt());

        // Can not start home if we don't want to start home while home is being instrumented.
        doReturn(true).when(app).isInstrumenting();
        assertFalse(mSupervisor.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                false /* allowInstrumenting*/));

        // Can start home for other cases.
        assertTrue(mSupervisor.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                true /* allowInstrumenting*/));

        doReturn(false).when(app).isInstrumenting();
        assertTrue(mSupervisor.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                false /* allowInstrumenting*/));
        assertTrue(mSupervisor.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                true /* allowInstrumenting*/));
    }
}