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

Commit ad24f96d authored by Chong Zhang's avatar Chong Zhang
Browse files

Only use saved surface if started by launcher or moved to front

Restrict saved surface to launcher start (ACTION_MAIN&CATEGORY_
LAUNCHER), or there is no intent at all (eg. task being brought to
front). If the intent is something else, likely the app is going
to show some specific page or view, instead of what's left last time.

This solves problems like the launcher shortcuts on DeckClock,
each of them is a different intent and will show one specific
view regardless of last states. Another example is Chrome tab
opened directly by action VIEW to open some URL.

(Note that this doesn't solve the problem with Chrome homescreen
shortcuts, it will still start with saved surface (if Chrome
is already open). This is because the shortcut is a trampoline
activity that starts the real chrome tab activity, but when
the trampoline is started, the whole task is already brought
to front, and ChromeTab could become visible with the task
before we actually start it.)

bug:27747315

Change-Id: Id3e61c61ef516b0edc1f174320f02661222f226b
parent 793075b3
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -176,7 +176,7 @@ interface IWindowManager
            in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
            in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
            int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
            int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
    void setAppVisibility(IBinder token, boolean visible);
    void setAppVisibility(IBinder token, boolean visible);
    void notifyAppResumed(IBinder token, boolean wasStopped);
    void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface);
    void notifyAppStopped(IBinder token);
    void notifyAppStopped(IBinder token);
    void startAppFreezingScreen(IBinder token, int configChanges);
    void startAppFreezingScreen(IBinder token, int configChanges);
    void stopAppFreezingScreen(IBinder token, boolean force);
    void stopAppFreezingScreen(IBinder token, boolean force);
+8 −0
Original line number Original line Diff line number Diff line
@@ -745,6 +745,14 @@ final class ActivityRecord {
                && intent.getType() == null;
                && intent.getType() == null;
    }
    }


    static boolean isMainIntent(Intent intent) {
        return Intent.ACTION_MAIN.equals(intent.getAction())
                && intent.hasCategory(Intent.CATEGORY_LAUNCHER)
                && intent.getCategories().size() == 1
                && intent.getData() == null
                && intent.getType() == null;
    }

    private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
    private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
        if (uid == Process.myUid() || uid == 0) {
        if (uid == Process.myUid() || uid == 0) {
            // System process can launch home activity.
            // System process can launch home activity.
+13 −1
Original line number Original line Diff line number Diff line
@@ -2553,13 +2553,25 @@ final class ActivityStack {
                    }
                    }
                }
                }


                boolean allowSavedSurface = true;
                if (next.newIntents != null) {
                if (next.newIntents != null) {
                    // Restrict saved surface to launcher start, or there is no intent at all
                    // (eg. task being brought to front). If the intent is something else,
                    // likely the app is going to show some specific page or view, instead of
                    // what's left last time.
                    for (int i = next.newIntents.size() - 1; i >= 0; i--) {
                        final Intent intent = next.newIntents.get(i);
                        if (!ActivityRecord.isMainIntent(intent)) {
                            allowSavedSurface = false;
                            break;
                        }
                    }
                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
                }
                }


                // Well the app will no longer be stopped.
                // Well the app will no longer be stopped.
                // Clear app token stopped state in window manager if needed.
                // Clear app token stopped state in window manager if needed.
                mWindowManager.notifyAppResumed(next.appToken, next.stopped);
                mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface);


                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);
                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);
+6 −2
Original line number Original line Diff line number Diff line
@@ -597,12 +597,16 @@ class AppWindowToken extends WindowToken {
     * Notify that the app is now resumed, and it was not stopped before, perform a clean
     * Notify that the app is now resumed, and it was not stopped before, perform a clean
     * up of the surfaces
     * up of the surfaces
     */
     */
    void notifyAppResumed(boolean wasStopped) {
    void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this);
        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
                + " allowSavedSurface=" + allowSavedSurface + " " + this);
        mAppStopped = false;
        mAppStopped = false;
        if (!wasStopped) {
        if (!wasStopped) {
            destroySurfaces(true /*cleanupOnResume*/);
            destroySurfaces(true /*cleanupOnResume*/);
        }
        }
        if (!allowSavedSurface) {
            destroySavedSurfaces();
        }
    }
    }


    /**
    /**
+2 −2
Original line number Original line Diff line number Diff line
@@ -3580,7 +3580,7 @@ public class WindowManagerService extends IWindowManager.Stub
    }
    }


    @Override
    @Override
    public void notifyAppResumed(IBinder token, boolean wasStopped) {
    public void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface) {
        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "notifyAppResumed()")) {
                "notifyAppResumed()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3593,7 +3593,7 @@ public class WindowManagerService extends IWindowManager.Stub
                Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token);
                Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token);
                return;
                return;
            }
            }
            wtoken.notifyAppResumed(wasStopped);
            wtoken.notifyAppResumed(wasStopped, allowSavedSurface);
        }
        }
    }
    }


Loading