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

Commit e6d106c3 authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Automerger Merge Worker
Browse files

Merge "Tracking launch activity to decide next splash screen style." into sc-dev am: 9e14f714

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14326844

Change-Id: I6037f3b59556fe264c3e7551dfe1c9c37c6194e3
parents da8fc0ee 9e14f714
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ public final class StartingWindowInfo implements Parcelable {
            TYPE_PARAMETER_PROCESS_RUNNING,
            TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
            TYPE_PARAMETER_ACTIVITY_CREATED,
            TYPE_PARAMETER_SAME_PACKAGE
            TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN
    })
    public @interface StartingTypeParams {}

@@ -121,7 +121,7 @@ public final class StartingWindowInfo implements Parcelable {
    /** @hide */
    public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
    /** @hide */
    public static final int TYPE_PARAMETER_SAME_PACKAGE = 0x00000020;
    public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;

    /**
     * The parameters which effect the starting window type.
+11 −10
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_SAME_PACKAGE;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;

import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_SPLASH_SCREEN;
import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_TASK_SNAPSHOT;
@@ -52,7 +52,8 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
        final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0;
        final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0;
        final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0;
        final boolean samePackage = (parameter & TYPE_PARAMETER_SAME_PACKAGE) != 0;
        final boolean useEmptySplashScreen =
                (parameter & TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN) != 0;
        final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME;

        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
@@ -61,19 +62,19 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
                    + " processRunning " + processRunning
                    + " allowTaskSnapshot " + allowTaskSnapshot
                    + " activityCreated " + activityCreated
                    + " samePackage " + samePackage
                    + " useEmptySplashScreen " + useEmptySplashScreen
                    + " topIsHome " + topIsHome);
        }
        if (!topIsHome) {
            if (!processRunning) {
                return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
                return useEmptySplashScreen
                        ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                        : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
            }
            if (newTask) {
                if (samePackage) {
                    return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
                } else {
                    return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
                }
                return useEmptySplashScreen
                        ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                        : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
            }
            if (taskSwitch && !activityCreated) {
                return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
@@ -84,7 +85,7 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
                return STARTING_WINDOW_TYPE_SNAPSHOT;
            }
            if (!topIsHome) {
                return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
                return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
            }
        }
        return STARTING_WINDOW_TYPE_NONE;
+1 −1
Original line number Diff line number Diff line
@@ -1170,7 +1170,7 @@ class ActivityClientController extends IActivityClientController.Stub {
                final boolean activityIsBaseActivity = baseIntent != null
                        && r.mActivityComponent.equals(baseIntent.getComponent());
                baseActivityIntent = activityIsBaseActivity ? r.intent : null;
                launchedFromHome = r.launchedFromHomeProcess;
                launchedFromHome = r.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_HOME);
            }

            // If the activity is one of the main entry points for the application, then we should
+143 −42
Original line number Diff line number Diff line
@@ -437,7 +437,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    final int launchedFromUid; // always the uid who started the activity.
    final String launchedFromPackage; // always the package who started the activity.
    final @Nullable String launchedFromFeatureId; // always the feature in launchedFromPackage
    final boolean launchedFromHomeProcess; // as per original caller
    private final int mLaunchSourceType; // original launch source type
    final Intent intent;    // the original intent that generated us
    final String shortComponentName; // the short component name of the intent
    final String resolvedType; // as per original caller;
@@ -540,6 +540,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    static final int STARTING_WINDOW_SHOWN = 1;
    static final int STARTING_WINDOW_REMOVED = 2;
    int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;

    // Tracking splash screen status from previous activity
    boolean mSplashScreenStyleEmpty = false;

    static final int LAUNCH_SOURCE_TYPE_SYSTEM = 1;
    static final int LAUNCH_SOURCE_TYPE_HOME = 2;
    static final int LAUNCH_SOURCE_TYPE_SYSTEMUI = 3;
    static final int LAUNCH_SOURCE_TYPE_APPLICATION = 4;
    /**
     * The type of launch source.
     */
    @IntDef(prefix = {"LAUNCH_SOURCE_TYPE_"}, value = {
            LAUNCH_SOURCE_TYPE_SYSTEM,
            LAUNCH_SOURCE_TYPE_HOME,
            LAUNCH_SOURCE_TYPE_SYSTEMUI,
            LAUNCH_SOURCE_TYPE_APPLICATION
    })
    @interface LaunchSourceType {}

    private boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.

    // Marking the reason why this activity is being relaunched. Mainly used to track that this
@@ -1582,7 +1601,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        launchedFromUid = _launchedFromUid;
        launchedFromPackage = _launchedFromPackage;
        launchedFromFeatureId = _launchedFromFeature;
        launchedFromHomeProcess = _caller != null && _caller.isHomeProcess();
        mLaunchSourceType = determineLaunchSourceType(_launchedFromUid, _caller);
        shortComponentName = _intent.getComponent().flattenToShortString();
        resolvedType = _resolvedType;
        componentSpecified = _componentSpecified;
@@ -1774,12 +1793,34 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return selectedTheme;
    }

    // Whether this activity launched from system or Home or SystemUI
    /**
     * @return Whether this {@link ActivityRecord} was launched from a system surface (e.g
     * Launcher, Notification,...)
     */
    private boolean launchedFromSystemSurface() {
        return launchedFromUid == Process.SYSTEM_UID || launchedFromUid == Process.ROOT_UID
                || launchedFromHomeProcess
                || mAtmService.getSysUiServiceComponentLocked().getPackageName().equals(
                        launchedFromPackage);
        return mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEM
                || mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME
                || mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI;
    }

    boolean isLaunchSourceType(@LaunchSourceType int type) {
        return mLaunchSourceType == type;
    }

    private int determineLaunchSourceType(int launchFromUid, WindowProcessController caller) {
        if (launchFromUid == Process.SYSTEM_UID || launchFromUid == Process.ROOT_UID) {
            return LAUNCH_SOURCE_TYPE_SYSTEM;
        }
        if (caller != null) {
            if (caller.isHomeProcess()) {
                return LAUNCH_SOURCE_TYPE_HOME;
            }
            if (mAtmService.getSysUiServiceComponentLocked().getPackageName()
                    .equals(caller.mInfo.packageName)) {
                return LAUNCH_SOURCE_TYPE_SYSTEMUI;
            }
        }
        return LAUNCH_SOURCE_TYPE_APPLICATION;
    }

    private boolean validateStartingWindowTheme(String pkg, int theme) {
@@ -1787,10 +1828,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // effect (a full-screen opaque starting window that fades away to the real contents
        // when it is ready) does not work for this.
        ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Checking theme of starting window: 0x%x", theme);
        if (theme != 0) {
            AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
                    com.android.internal.R.styleable.Window,
                    mWmService.mCurrentUserId);
        if (theme == 0) {
            return false;
        }

        final AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
                com.android.internal.R.styleable.Window, mWmService.mCurrentUserId);
        if (ent == null) {
            // Whoops!  App doesn't exist. Um. Okay. We'll just pretend like we didn't
            // see that.
@@ -1809,14 +1852,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                windowIsTranslucent, windowIsFloating, windowShowWallpaper,
                windowDisableStarting);
        // If this activity is launched from system surface, ignore windowDisableStarting
            if (windowIsTranslucent || windowIsFloating
                    || (windowDisableStarting && !launchedFromSystemSurface())) {
        if (windowIsTranslucent || windowIsFloating) {
            return false;
        }
        if (windowShowWallpaper
                && getDisplayContent().mWallpaperController.getWallpaperTarget() != null) {
            return false;
        }
        if (windowDisableStarting && !launchedFromSystemSurface()) {
            return false;
        }
        return true;
    }
@@ -1846,7 +1890,7 @@ 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,
            IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
            boolean allowTaskSnapshot, boolean activityCreated, boolean samePackage) {
            boolean allowTaskSnapshot, boolean activityCreated, boolean useEmpty) {
        // 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()) {
@@ -1868,7 +1912,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                        false /* restoreFromDisk */, false /* isLowResolution */);
        final int typeParameter = mWmService.mStartingSurfaceController
                .makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
                        allowTaskSnapshot, activityCreated, samePackage);
                        allowTaskSnapshot, activityCreated, useEmpty);
        final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
                allowTaskSnapshot, activityCreated, snapshot);

@@ -5673,6 +5717,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

    void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
        firstWindowDrawn = true;
        // stop tracking
        mSplashScreenStyleEmpty = true;

        // We now have a good window to show, remove dead placeholders
        removeDeadWindows();
@@ -5691,6 +5737,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

    void onStartingWindowDrawn() {
        if (task != null) {
            mSplashScreenStyleEmpty = true;
            task.setHasBeenVisible(true);
        }
    }
@@ -6097,11 +6144,62 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

    void showStartingWindow(boolean taskSwitch) {
        showStartingWindow(null /* prev */, false /* newTask */, taskSwitch,
                0 /* splashScreenTheme */, true /* samePackage */);
                0 /* splashScreenTheme */, null);
    }

    /**
     * Search for the candidate launching activity from currently visible activities.
     *
     * This activity could be launched from service, so we need to check whether there is existing a
     * foreground activity from the same process or same package.
     *
     */
    private ActivityRecord searchCandidateLaunchingActivity() {
        // Get previous activity below self
        ActivityRecord below = task.getActivityBelow(this);
        if (below == null) {
            below = task.getParent().getActivityBelow(this);
        }

        if (below == null || below.isActivityTypeHome()) {
            return null;
        }
        final WindowProcessController myProcess = app != null
                ? app : mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
        final WindowProcessController candidateProcess = below.app != null
                        ? below.app
                        : mAtmService.mProcessNames.get(below.processName,
                                below.info.applicationInfo.uid);
        // same process or same package
        if (candidateProcess == myProcess
                || mActivityComponent.getPackageName()
                .equals(below.mActivityComponent.getPackageName())) {
            return below;
        }
        return null;
    }

    private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord) {
        if (sourceRecord == null) {
            sourceRecord = searchCandidateLaunchingActivity();
        }

        if (sourceRecord != null && !sourceRecord.isActivityTypeHome()) {
            return sourceRecord.mSplashScreenStyleEmpty;
        }

        // If this activity was launched from a system surface, never use an empty splash screen
        // Need to check sourceRecord before in case this activity is launched from service.
        if (launchedFromSystemSurface()) {
            return false;
        }

        // Otherwise use empty.
        return true;
    }

    void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
            int splashScreenTheme, boolean samePackage) {
            int splashScreenTheme, ActivityRecord sourceRecord) {
        if (mTaskOverlay) {
            // We don't show starting window for overlay activities.
            return;
@@ -6115,14 +6213,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final CompatibilityInfo compatInfo =
                mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);

        mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord);

        final int resolvedTheme = evaluateStartingWindowTheme(packageName, theme,
                splashScreenTheme);

        final boolean shown = addStartingWindow(packageName, resolvedTheme,
                compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                allowTaskSnapshot(),
                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
                samePackage);
                mSplashScreenStyleEmpty);
        if (shown) {
            mStartingWindowState = STARTING_WINDOW_SHOWN;
        }
+9 −9
Original line number Diff line number Diff line
@@ -1123,6 +1123,14 @@ class ActivityStarter {

            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }
        // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
        // Pending intent launched from systemui also depends on caller app
        if (callerApp == null && realCallingPid > 0) {
            final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
            if (wpc != null) {
                callerApp = wpc;
            }
        }
        final ActivityRecord r = new ActivityRecord.Builder(mService)
                .setCaller(callerApp)
                .setLaunchedFromPid(callingPid)
@@ -1752,17 +1760,9 @@ class ActivityStarter {
        mRootWindowContainer.startPowerModeLaunchIfNeeded(
                false /* forceSend */, mStartActivity);

        final boolean startFromSamePackage;
        if (sourceRecord != null && sourceRecord.mActivityComponent != null) {
            startFromSamePackage = mStartActivity.mActivityComponent
                    .getPackageName().equals(sourceRecord.mActivityComponent.getPackageName());
        } else {
            startFromSamePackage = false;
        }

        mTargetRootTask.startActivityLocked(mStartActivity,
                topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
                mKeepCurTransition, mOptions, startFromSamePackage);
                mKeepCurTransition, mOptions, sourceRecord);
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
Loading