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

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

Some fixes for black screen when pressing home button

Pressing home button sometimes involves a rotation (eg. when app is
running in landscape mode but launch is fixed portrait mode). This will
trigger a screen freeze, which clears the transition. We still need to
add the opening app to the opening list even if transition is unset,
otherwise it doesn't wait for app to draw first frame.

Also during rotation, app, launcher and wallpaper all get relaunched.
The transition can't start until the first frame on the new launcher
window comes back. We can't start it based on the draw state of the old
window, because the old window could get removed and readded shortly
after we start the transition, and it shows up as a black frame.

bug: 27391256
bug: 27295820
Change-Id: I346685076657eef209d0fab68f272e218b55e011
parent 4e7ad35b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6650,7 +6650,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                ActivityRecord.activityResumedLocked(token);
                stack.activityResumedLocked(token);
            }
        }
        Binder.restoreCallingIdentity(origId);
+0 −7
Original line number Diff line number Diff line
@@ -1275,13 +1275,6 @@ final class ActivityRecord {
        }
    }

    static void activityResumedLocked(IBinder token) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
        r.icicle = null;
        r.haveState = false;
    }

    static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (r == null) {
+8 −1
Original line number Diff line number Diff line
@@ -1088,6 +1088,13 @@ final class ActivityStack {
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

    final void activityResumedLocked(IBinder token) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
        r.icicle = null;
        r.haveState = false;
    }

    final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
            PersistableBundle persistentState, CharSequence description) {
        if (r.state != ActivityState.STOPPING) {
@@ -4436,10 +4443,10 @@ final class ActivityStack {
                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r
                    + " callers=" + Debug.getCallers(6));
            r.forceNewConfig = false;
            mStackSupervisor.activityRelaunchingLocked(r);
            r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
                    !andResume, new Configuration(mService.mConfiguration),
                    new Configuration(r.task.mOverrideConfig), preserveWindow);
            mStackSupervisor.activityRelaunchingLocked(r);
            // Note: don't need to call pauseIfSleepingLocked() here, because
            // the caller will only pass in 'andResume' if this activity is
            // currently resumed, which implies we aren't sleeping.
+33 −3
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ class AppWindowToken extends WindowToken {
    boolean mAlwaysFocusable;

    boolean mAppStopped;
    int mPendingRelaunchCount;

    ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();

@@ -531,6 +532,26 @@ class AppWindowToken extends WindowToken {
        }
    }

    boolean isRelaunching() {
        return mPendingRelaunchCount > 0;
    }

    void startRelaunching() {
        if (canFreezeBounds()) {
            freezeBounds();
        }
        mPendingRelaunchCount++;
    }

    void finishRelaunching() {
        if (canFreezeBounds()) {
            unfreezeBounds();
        }
        if (mPendingRelaunchCount > 0) {
            mPendingRelaunchCount--;
        }
    }

    void addWindow(WindowState w) {
        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
            WindowState candidate = allAppWindows.get(i);
@@ -579,20 +600,26 @@ class AppWindowToken extends WindowToken {
        }
    }

    private boolean canFreezeBounds() {
        // For freeform windows, we can't freeze the bounds at the moment because this would make
        // the resizing unresponsive.
        return mTask != null && !mTask.inFreeformWorkspace();
    }

    /**
     * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
     * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
     * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
     * with a queue.
     */
    void freezeBounds() {
    private void freezeBounds() {
        mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
    }

    /**
     * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
     */
    void unfreezeBounds() {
    private void unfreezeBounds() {
        mFrozenBounds.remove();
        for (int i = windows.size() - 1; i >= 0; i--) {
            final WindowState win = windows.get(i);
@@ -658,7 +685,10 @@ class AppWindowToken extends WindowToken {
                    pw.print(" startingMoved="); pw.println(startingMoved);
        }
        if (!mFrozenBounds.isEmpty()) {
            pw.print(prefix); pw.print("mFrozenBounds="); pw.print(mFrozenBounds);
            pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
        }
        if (mPendingRelaunchCount != 0) {
            pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
        }
    }

+27 −34
Original line number Diff line number Diff line
@@ -2340,6 +2340,7 @@ public class WindowManagerService extends IWindowManager.Stub
                mTokenMap.remove(token.token);
            } else if (atoken != null) {
                atoken.firstWindowDrawn = false;
                atoken.allDrawn = false;
            }
        }

@@ -4251,26 +4252,8 @@ public class WindowManagerService extends IWindowManager.Stub
                        TAG_WM, "No longer Stopped: " + wtoken);
                wtoken.mAppStopped = false;
                wtoken.setWindowsExiting(false);
            }

            // If we are preparing an app transition, then delay changing
            // the visibility of this token until we execute that transition.
            if (okToDisplay() && mAppTransition.isTransitionSet()) {
                // A dummy animation is a placeholder animation which informs others that an
                // animation is going on (in this case an application transition). If the animation
                // was transferred from another application/animator, no dummy animator should be
                // created since an animation is already in progress.
                if (!wtoken.mAppAnimator.usingTransferredAnimation &&
                        (!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
                    if (DEBUG_APP_TRANSITIONS) Slog.v(
                            TAG_WM, "Setting dummy animation on: " + wtoken);
                    wtoken.mAppAnimator.setDummyAnimation();
                }
                wtoken.inPendingTransaction = true;
                if (visible) {
                mOpeningApps.add(wtoken);
                wtoken.startingMoved = false;
                    wtoken.mEnteringAnimation = true;

                // If the token is currently hidden (should be the
                // common case), then we need to set up to wait for
@@ -4291,6 +4274,24 @@ public class WindowManagerService extends IWindowManager.Stub
                        wtoken.sendAppVisibilityToClients();
                    }
                }
            }

            // If we are preparing an app transition, then delay changing
            // the visibility of this token until we execute that transition.
            if (okToDisplay() && mAppTransition.isTransitionSet()) {
                // A dummy animation is a placeholder animation which informs others that an
                // animation is going on (in this case an application transition). If the animation
                // was transferred from another application/animator, no dummy animator should be
                // created since an animation is already in progress.
                if (!wtoken.mAppAnimator.usingTransferredAnimation &&
                        (!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
                    if (DEBUG_APP_TRANSITIONS) Slog.v(
                            TAG_WM, "Setting dummy animation on: " + wtoken);
                    wtoken.mAppAnimator.setDummyAnimation();
                }
                wtoken.inPendingTransaction = true;
                if (visible) {
                    wtoken.mEnteringAnimation = true;
                } else {
                    wtoken.setWindowsExiting(true);
                    mClosingApps.add(wtoken);
@@ -9636,8 +9637,8 @@ public class WindowManagerService extends IWindowManager.Stub
    public void notifyAppRelaunching(IBinder token) {
        synchronized (mWindowMap) {
            AppWindowToken appWindow = findAppWindowToken(token);
            if (canFreezeBounds(appWindow)) {
                appWindow.freezeBounds();
            if (appWindow != null) {
                appWindow.startRelaunching();
            }
        }
    }
@@ -9645,18 +9646,10 @@ public class WindowManagerService extends IWindowManager.Stub
    public void notifyAppRelaunchingFinished(IBinder token) {
        synchronized (mWindowMap) {
            AppWindowToken appWindow = findAppWindowToken(token);
            if (canFreezeBounds(appWindow)) {
                appWindow.unfreezeBounds();
            }
            if (appWindow != null) {
                appWindow.finishRelaunching();
            }
        }

    private boolean canFreezeBounds(AppWindowToken appWindow) {

        // For freeform windows, we can't freeze the bounds at the moment because this would make
        // the resizing unresponsive.
        return appWindow != null && appWindow.mTask != null
                && !appWindow.mTask.inFreeformWorkspace();
    }

    @Override
Loading