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

Commit a5545793 authored by wilsonshih's avatar wilsonshih
Browse files

Correct StartingWindowInfo for non-top activity.

When finishing a top activity and goes to resume the below activity, if
the resumed activity was gone and need to recreate, this should be treat
as warm launch and there should show an empty style splash screen on it.
Previous there do create a splash screen window but the parameters are
wrong because we are trying to create the StartingWIndowInfo from the
top activity.

Fixes: 193040222
Test: atest ActivityRecordTests
Test:
1. enable "Dont keep Activities"
2. Launch twitter, open link.
3. Click back key and there should show empty splash screen.

Change-Id: I33ac43ef6ca79c7422a818e468a7af32c7894eeb
parent 9028f499
Loading
Loading
Loading
Loading
+48 −4
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ import android.app.servertransaction.TopResumedActivityChangeItem;
import android.app.servertransaction.TransferSplashScreenViewStateItem;
import android.app.usage.UsageEvents.Event;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
@@ -6236,7 +6237,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

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

    /**
@@ -6271,7 +6272,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return null;
    }

    private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord) {
    private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord, boolean startActivity) {
        if (sourceRecord == null && !startActivity) {
            // Use empty style if this activity is not top activity. This could happen when adding
            // a splash screen window to the warm start activity which is re-create because top is
            // finishing.
            final ActivityRecord above = task.getActivityAbove(this);
            if (above != null) {
                return true;
            }
        }
        if (mPendingOptions != null) {
            final int optionsStyle = mPendingOptions.getSplashScreenStyle();
            if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_EMPTY) {
@@ -6298,8 +6308,41 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return true;
    }

    private int getSplashscreenTheme() {
        // Find the splash screen theme. User can override the persisted theme by
        // ActivityOptions.
        String splashScreenThemeResName = mPendingOptions != null
                ? mPendingOptions.getSplashScreenThemeResName() : null;
        if (splashScreenThemeResName == null || splashScreenThemeResName.isEmpty()) {
            try {
                splashScreenThemeResName = mAtmService.getPackageManager()
                        .getSplashScreenTheme(packageName, mUserId);
            } catch (RemoteException ignore) {
                // Just use the default theme
            }
        }
        int splashScreenThemeResId = 0;
        if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) {
            try {
                final Context packageContext = mAtmService.mContext
                        .createPackageContext(packageName, 0);
                splashScreenThemeResId = packageContext.getResources()
                        .getIdentifier(splashScreenThemeResName, null, null);
            } catch (PackageManager.NameNotFoundException
                    | Resources.NotFoundException ignore) {
                // Just use the default theme
            }
        }
        return splashScreenThemeResId;
    }

    /**
     * @param prev Previous activity which contains a starting window.
     * @param startActivity Whether this activity is just created from starter.
     * @param sourceRecord The source activity which start this activity.
     */
    void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
            int splashScreenTheme, ActivityRecord sourceRecord) {
            boolean startActivity, ActivityRecord sourceRecord) {
        if (mTaskOverlay) {
            // We don't show starting window for overlay activities.
            return;
@@ -6313,8 +6356,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final CompatibilityInfo compatInfo =
                mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);

        mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord);
        mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord, startActivity);

        final int splashScreenTheme = startActivity ? getSplashscreenTheme() : 0;
        final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme,
                splashScreenTheme);

+2 −2
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ public class StartingSurfaceController {
        synchronized (mService.mGlobalLock) {
            final Task task = activity.getTask();
            if (task != null && mService.mAtmService.mTaskOrganizerController.addStartingWindow(
                    task, activity.token, theme, null /* taskSnapshot */)) {
                    task, activity, theme, null /* taskSnapshot */)) {
                return new ShellStartingSurface(task);
            }
        }
@@ -149,7 +149,7 @@ public class StartingSurfaceController {
            }
            if (DEBUG_ENABLE_SHELL_DRAWER) {
                mService.mAtmService.mTaskOrganizerController.addStartingWindow(task,
                        activity.token, 0 /* launchTheme */, taskSnapshot);
                        activity, 0 /* launchTheme */, taskSnapshot);
                return new ShellStartingSurface(task);
            }
        }
+14 −42
Original line number Diff line number Diff line
@@ -179,14 +179,12 @@ import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.ResumeActivityItem;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
@@ -4163,26 +4161,25 @@ class Task extends WindowContainer<WindowContainer> {
        return info;
    }

    StartingWindowInfo getStartingWindowInfo() {
    /**
     * Returns a {@link StartingWindowInfo} with information from this task and the target activity.
     * @param activity Target activity which to show the starting window.
     */
    StartingWindowInfo getStartingWindowInfo(ActivityRecord activity) {
        final StartingWindowInfo info = new StartingWindowInfo();
        info.taskInfo = getTaskInfo();

        info.isKeyguardOccluded =
            mAtmService.mKeyguardController.isDisplayOccluded(DEFAULT_DISPLAY);
        final ActivityRecord topActivity = getTopMostActivity();
        if (topActivity != null) {
            info.startingWindowTypeParameter =
                    topActivity.mStartingData != null
                            ? topActivity.mStartingData.mTypeParams
                            : 0;
            final WindowState mainWindow = topActivity.findMainWindow();

        info.startingWindowTypeParameter = activity.mStartingData.mTypeParams;
        final WindowState mainWindow = activity.findMainWindow();
        if (mainWindow != null) {
            info.mainWindowLayoutParams = mainWindow.getAttrs();
        }
        // If the developer has persist a different configuration, we need to override it to the
        // starting window because persisted configuration does not effect to Task.
            info.taskInfo.configuration.setTo(topActivity.getConfiguration());
        }
        info.taskInfo.configuration.setTo(activity.getConfiguration());
        final ActivityRecord topFullscreenActivity = getTopFullscreenActivity();
        if (topFullscreenActivity != null) {
            final WindowState topFullscreenOpaqueWindow =
@@ -6691,33 +6688,8 @@ class Task extends WindowContainer<WindowContainer> {
                    }
                }

                // Find the splash screen theme. User can override the persisted theme by
                // ActivityOptions.
                String splashScreenThemeResName = options != null
                        ? options.getSplashScreenThemeResName() : null;
                if (splashScreenThemeResName == null || splashScreenThemeResName.isEmpty()) {
                    try {
                        splashScreenThemeResName = mAtmService.getPackageManager()
                                .getSplashScreenTheme(r.packageName, r.mUserId);
                    } catch (RemoteException ignore) {
                        // Just use the default theme
                    }
                }
                int splashScreenThemeResId = 0;
                if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) {
                    try {
                        final Context packageContext = mAtmService.mContext
                                .createPackageContext(r.packageName, 0);
                        splashScreenThemeResId = packageContext.getResources()
                                .getIdentifier(splashScreenThemeResName, null, null);
                    } catch (PackageManager.NameNotFoundException
                            | Resources.NotFoundException ignore) {
                        // Just use the default theme
                    }
                }

                r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity),
                        splashScreenThemeResId, sourceRecord);
                        true /* startActivity */, sourceRecord);
            }
        } else {
            // If this is the first activity, don't do any fancy animations,
+8 −8
Original line number Diff line number Diff line
@@ -122,16 +122,16 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
            return mTaskOrganizer.asBinder();
        }

        void addStartingWindow(Task task, IBinder appToken, int launchTheme,
        void addStartingWindow(Task task, ActivityRecord activity, int launchTheme,
                TaskSnapshot taskSnapshot) {
            final StartingWindowInfo info = task.getStartingWindowInfo();
            final StartingWindowInfo info = task.getStartingWindowInfo(activity);
            if (launchTheme != 0) {
                info.splashScreenThemeResId = launchTheme;
            }
            info.mTaskSnapshot = taskSnapshot;
            // make this happen prior than prepare surface
            try {
                mTaskOrganizer.addStartingWindow(info, appToken);
                mTaskOrganizer.addStartingWindow(info, activity.token);
            } catch (RemoteException e) {
                Slog.e(TAG, "Exception sending onTaskStart callback", e);
            }
@@ -311,9 +311,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
            mUid = uid;
        }

        void addStartingWindow(Task t, IBinder appToken, int launchTheme,
        void addStartingWindow(Task t, ActivityRecord activity, int launchTheme,
                TaskSnapshot taskSnapshot) {
            mOrganizer.addStartingWindow(t, appToken, launchTheme, taskSnapshot);
            mOrganizer.addStartingWindow(t, activity, launchTheme, taskSnapshot);
        }

        void removeStartingWindow(Task t, boolean prepareAnimation) {
@@ -547,15 +547,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
        return !ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, winMode);
    }

    boolean addStartingWindow(Task task, IBinder appToken, int launchTheme,
    boolean addStartingWindow(Task task, ActivityRecord activity, int launchTheme,
            TaskSnapshot taskSnapshot) {
        final Task rootTask = task.getRootTask();
        if (rootTask == null || rootTask.mTaskOrganizer == null) {
        if (rootTask == null || rootTask.mTaskOrganizer == null || activity.mStartingData == null) {
            return false;
        }
        final TaskOrganizerState state =
                mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
        state.addStartingWindow(task, appToken, launchTheme, taskSnapshot);
        state.addStartingWindow(task, activity, launchTheme, taskSnapshot);
        return true;
    }

+3 −3
Original line number Diff line number Diff line
@@ -2561,19 +2561,19 @@ public class ActivityRecordTests extends WindowTestsBase {
        final ActivityRecord sourceRecord = new ActivityBuilder(mAtm)
                .setCreateTask(true).setLaunchedFromUid(Process.SYSTEM_UID).build();
        sourceRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
                0 /* splashScreenTheme */, null);
                true /* startActivity */, null);

        final ActivityRecord secondRecord = new ActivityBuilder(mAtm)
                .setTask(sourceRecord.getTask()).build();
        secondRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
                0 /* splashScreenTheme */, sourceRecord);
                true /* startActivity */, sourceRecord);
        assertFalse(secondRecord.mSplashScreenStyleEmpty);
        secondRecord.onStartingWindowDrawn();

        final ActivityRecord finalRecord = new ActivityBuilder(mAtm)
                .setTask(sourceRecord.getTask()).build();
        finalRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
                0 /* splashScreenTheme */, secondRecord);
                true /* startActivity */, secondRecord);
        assertTrue(finalRecord.mSplashScreenStyleEmpty);
    }