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

Commit f2142d0f authored by Josh Yang's avatar Josh Yang Committed by yzj
Browse files

Draw splash window during app switch if the top activity is not drawn.

In Wear OS, when the device enters ambient mode, we will switch the front activity to the background. When device exits ambient mode, the previous activity will be moved back to the front. If the activity hasn't been drawn yet when the device enters ambient mode, we want to show the splash window when it's brought back to the front.

Bug: 176837715
Bug: 199552234
Fix: 199552234
Test: manual test
Change-Id: I8275db9cb51575b61f5a4f04316b77e3f53ba220
(cherry picked from commit 3dc923bafc4454490935fd9e6b4b6602a91febaf)
parent 2e7d9776
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -137,6 +137,11 @@ public final class StartingWindowInfo implements Parcelable {
    public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
    /** @hide */
    public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;
    /**
     * The parameter which indicates if the activity has finished drawing.
     * @hide
     */
    public static final int TYPE_PARAMETER_ACTIVITY_DRAWN = 0x00000040;
    /**
     * Application is allowed to use the legacy splash screen
     * @hide
+7 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
@@ -41,7 +42,7 @@ import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;

/**
 * Algorithm for determining the type of a new starting window on handheld devices.
 * At the moment also used on Android Auto.
 * At the moment also used on Android Auto and Wear OS.
 */
public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgorithm {
    private static final String TAG = PhoneStartingWindowTypeAlgorithm.class.getSimpleName();
@@ -58,6 +59,7 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
                (parameter & TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN) != 0;
        final boolean legacySplashScreen =
                ((parameter & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN) != 0);
        final boolean activityDrawn = (parameter & TYPE_PARAMETER_ACTIVITY_DRAWN) != 0;
        final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME;

        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
@@ -68,11 +70,14 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
                    + " activityCreated:" + activityCreated
                    + " useEmptySplashScreen:" + useEmptySplashScreen
                    + " legacySplashScreen:" + legacySplashScreen
                    + " activityDrawn:" + activityDrawn
                    + " topIsHome:" + topIsHome);
        }

        if (!topIsHome) {
            if (!processRunning || newTask || (taskSwitch && !activityCreated)) {
            if (!processRunning
                    || newTask
                    || (taskSwitch && (!activityCreated || !activityDrawn))) {
                return useEmptySplashScreen
                        ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                        : legacySplashScreen
+8 −7
Original line number Diff line number Diff line
@@ -2043,7 +2043,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    boolean addStartingWindow(String pkg, int resolvedTheme, CompatibilityInfo compatInfo,
            CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
            ActivityRecord from, boolean newTask, boolean taskSwitch, boolean processRunning,
            boolean allowTaskSnapshot, boolean activityCreated, boolean useEmpty) {
            boolean allowTaskSnapshot, boolean activityCreated, boolean useEmpty,
            boolean activityAllDrawn) {
        // If the display is frozen, we won't do anything until the actual window is
        // displayed so there is no reason to put in the starting window.
        if (!okToDisplay()) {
@@ -2064,7 +2065,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, task.mUserId,
                        false /* restoreFromDisk */, false /* isLowResolution */);
        final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
                allowTaskSnapshot, activityCreated, snapshot);
                allowTaskSnapshot, activityCreated, activityAllDrawn, snapshot);

        //TODO(191787740) Remove for T
        final boolean useLegacy = type == STARTING_WINDOW_TYPE_SPLASH_SCREEN
@@ -2078,7 +2079,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        final int typeParameter = mWmService.mStartingSurfaceController
                .makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
                        allowTaskSnapshot, activityCreated, useEmpty, useLegacy);
                        allowTaskSnapshot, activityCreated, useEmpty, useLegacy, activityAllDrawn);

        if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
            if (isActivityTypeHome()) {
@@ -2213,10 +2214,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    private final AddStartingWindow mAddStartingWindow = new AddStartingWindow();

    private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
            boolean allowTaskSnapshot, boolean activityCreated,
            boolean allowTaskSnapshot, boolean activityCreated, boolean activityAllDrawn,
            TaskSnapshot snapshot) {
        if ((newTask || !processRunning || (taskSwitch && !activityCreated))
                && !isActivityTypeHome()) {
        if ((newTask || !processRunning || (taskSwitch && !activityCreated)
                || (taskSwitch && !activityAllDrawn)) && !isActivityTypeHome()) {
            return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
        } else if (taskSwitch && allowTaskSnapshot) {
            if (isSnapshotCompatible(snapshot)) {
@@ -6649,7 +6650,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final boolean scheduled = addStartingWindow(packageName, resolvedTheme,
                compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                prev, newTask || newSingleActivity, taskSwitch, isProcessRunning(),
                allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty);
                allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty, allDrawn);
        if (DEBUG_STARTING_WINDOW_VERBOSE && scheduled) {
            Slog.d(TAG, "Scheduled starting window for " + this);
        }
+5 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.wm;

import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
@@ -86,7 +87,7 @@ public class StartingSurfaceController {

    int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
            boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
            boolean useEmpty, boolean useLegacy) {
            boolean useEmpty, boolean useLegacy, boolean activityDrawn) {
        int parameter = 0;
        if (newTask) {
            parameter |= TYPE_PARAMETER_NEW_TASK;
@@ -109,6 +110,9 @@ public class StartingSurfaceController {
        if (useLegacy) {
            parameter |= TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
        }
        if (activityDrawn) {
            parameter |= TYPE_PARAMETER_ACTIVITY_DRAWN;
        }
        return parameter;
    }

+12 −12
Original line number Diff line number Diff line
@@ -2463,7 +2463,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
        activity.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();
        assertHasStartingWindow(activity);
        activity.removeStartingWindow();
@@ -2476,7 +2476,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        activity.mTargetSdk = targetSdk;
        activity.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();
        assertHasStartingWindow(activity);
        assertEquals(activity.mStartingData.mTypeParams & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN,
@@ -2514,11 +2514,11 @@ public class ActivityRecordTests extends WindowTestsBase {
                .setVisible(false).build();
        activity1.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();
        activity2.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1,
                true, true, false, true, false, false);
                true, true, false, true, false, false, false);
        waitUntilHandlersIdle();
        assertFalse(mDisplayContent.mSkipAppTransitionAnimation);
        assertNoStartingWindow(activity1);
@@ -2536,11 +2536,11 @@ public class ActivityRecordTests extends WindowTestsBase {
                    activity2.addStartingWindow(mPackageName,
                            android.R.style.Theme, null, "Test", 0, 0, 0, 0,
                            activity1, true, true, false,
                            true, false, false);
                            true, false, false, false);
                });
        activity1.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();
        assertNoStartingWindow(activity1);
        assertHasStartingWindow(activity2);
@@ -2553,11 +2553,11 @@ public class ActivityRecordTests extends WindowTestsBase {
        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build();
        activity1.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();
        activity2.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1,
                true, true, false, true, false, false);
                true, true, false, true, false, false, false);
        waitUntilHandlersIdle();
        assertNoStartingWindow(activity1);
        assertHasStartingWindow(activity2);
@@ -2599,7 +2599,7 @@ public class ActivityRecordTests extends WindowTestsBase {
                "Test", 0 /* labelRes */, 0 /* icon */, 0 /* logo */, 0 /* windowFlags */,
                null /* transferFrom */, true /* newTask */, true /* taskSwitch */,
                false /* processRunning */, false /* allowTaskSnapshot */,
                false /* activityCreate */, false /* suggestEmpty */);
                false /* activityCreate */, false /* suggestEmpty */, false /* activityAllDrawn */);
        waitUntilHandlersIdle();
        assertHasStartingWindow(activity);

@@ -2647,7 +2647,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        task.positionChildAt(topActivity, POSITION_TOP);
        activity.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();

        // Make activities to have different rotation from it display and set fixed rotation
@@ -2664,7 +2664,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        // on activity2.
        topActivity.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity,
                false, false, false, true, false, false);
                false, false, false, true, false, false, false);
        waitUntilHandlersIdle();
        assertTrue(topActivity.hasFixedRotationTransform());
    }
@@ -2680,7 +2680,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        // Add a starting window.
        activityTop.addStartingWindow(mPackageName,
                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
                false, false);
                false, false, false);
        waitUntilHandlersIdle();

        // Make the top one invisible, and try transferring the starting window from the top to the