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

Commit 4489eec9 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Remove dead window preservation" into udc-dev

parents 545019cb aee6d8ae
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -874,15 +874,6 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
                    || mWindowingMode == WINDOWING_MODE_MULTI_WINDOW;
    }

    /**
     * Returns true if any visible windows belonging to apps with this window configuration should
     * be kept on screen when the app is killed due to something like the low memory killer.
     * @hide
     */
    public boolean keepVisibleDeadAppWindowOnScreen() {
        return mWindowingMode != WINDOWING_MODE_PINNED;
    }

    /**
     * Returns true if the backdrop on the client side should match the frame of the window.
     * Returns false, if the backdrop should be fullscreen.
+0 −5
Original line number Diff line number Diff line
@@ -251,11 +251,6 @@ class ActivityClientController extends IActivityClientController.Stub {
                    // {@link #restartActivityProcessIfVisible}.
                    restartingName = r.app.mName;
                    restartingUid = r.app.mUid;
                    // Make EnsureActivitiesVisibleHelper#makeVisibleAndRestartIfNeeded not skip
                    // restarting non-top activity.
                    if (r != r.getTask().topRunningActivity()) {
                        r.setVisibleRequested(false);
                    }
                }
                r.activityStopped(icicle, persistentState, description);
            }
+1 −29
Original line number Diff line number Diff line
@@ -4135,9 +4135,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        } else if (!mVisibleRequested && launchCount > 2
                && lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
            // We have launched this activity too many times since it was able to run, so give up
            // and remove it. (Note if the activity is visible, we don't remove the record. We leave
            // the dead window on the screen but the process will not be restarted unless user
            // explicitly tap on it.)
            // and remove it.
            remove = true;
        } else {
            // The process may be gone, but the activity lives on!
@@ -4159,11 +4157,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            if (DEBUG_APP) {
                Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this);
            }
            // Set nowVisible to previous visible state. If the app was visible while it died, we
            // leave the dead window on screen so it's basically visible. This is needed when user
            // later tap on the dead window, we need to stop other apps when user transfers focus
            // to the restarted activity.
            nowVisible = mVisibleRequested;
        }
        // upgrade transition trigger to task if this is the last activity since it means we are
        // closing the task.
@@ -5290,10 +5283,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mLastDeferHidingClient = deferHidingClient;

        if (!visible) {
            // If the app is dead while it was visible, we kept its dead window on screen.
            // Now that the app is going invisible, we can remove it. It will be restarted
            // if made visible again.
            removeDeadWindows();
            // If this activity is about to finish/stopped and now becomes invisible, remove it
            // from the unknownApp list in case the activity does not want to draw anything, which
            // keep the user waiting for the next transition to start.
@@ -6642,9 +6631,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // stop tracking
        mSplashScreenStyleSolidColor = true;

        // We now have a good window to show, remove dead placeholders
        removeDeadWindows();

        if (mStartingWindow != null) {
            ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s"
                    + ": first real window is shown, no animation", win.mToken);
@@ -7380,20 +7366,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    void removeDeadWindows() {
        for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
            WindowState win = mChildren.get(winNdx);
            if (win.mAppDied) {
                ProtoLog.w(WM_DEBUG_ADD_REMOVE,
                        "removeDeadWindows: %s", win);
                // Set mDestroying, we don't want any animation or delayed removal here.
                win.mDestroying = true;
                // Also removes child windows.
                win.removeIfPossible();
            }
        }
    }

    void setWillReplaceWindows(boolean animate) {
        ProtoLog.d(WM_DEBUG_ADD_REMOVE,
                "Marking app token %s with replacing windows.", this);
+2 −10
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ class EnsureActivitiesVisibleHelper {
            }

            if (!r.attachedToProcess()) {
                makeVisibleAndRestartIfNeeded(mStarting, mConfigChanges, isTop,
                makeVisibleAndRestartIfNeeded(mStarting, mConfigChanges,
                        resumeTopActivity && isTop, r);
            } else if (r.isVisibleRequested()) {
                // If this activity is already visible, then there is nothing to do here.
@@ -243,15 +243,7 @@ class EnsureActivitiesVisibleHelper {
    }

    private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
            boolean isTop, boolean andResume, ActivityRecord r) {
        // We need to make sure the app is running if it's the top, or it is just made visible from
        // invisible. If the app is already visible, it must have died while it was visible. In this
        // case, we'll show the dead window but will not restart the app. Otherwise we could end up
        // thrashing.
        if (!isTop && r.isVisibleRequested() && !r.isState(INITIALIZING)) {
            return;
        }

            boolean andResume, ActivityRecord r) {
        // This activity needs to be visible, but isn't even running...
        // get it started and resume if no other root task in this root task is resumed.
        if (DEBUG_VISIBILITY) {
+6 −96
Original line number Diff line number Diff line
@@ -221,8 +221,6 @@ import android.view.IWindow;
import android.view.IWindowFocusObserver;
import android.view.IWindowId;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InputWindowHandle;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -571,12 +569,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    /** Completely remove from window manager after exit animation? */
    boolean mRemoveOnExit;

    /**
     * Whether the app died while it was visible, if true we might need
     * to continue to show it until it's restarted.
     */
    boolean mAppDied;

    /**
     * Set when the orientation is changing and this window has not yet
     * been updated for the new orientation.
@@ -760,7 +752,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     */
    private InsetsState mFrozenInsetsState;

    private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f;
    private KeyInterceptionInfo mKeyInterceptionInfo;

    /**
@@ -1504,13 +1495,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                }
            }

            // If it's a dead window left on screen, and the configuration changed, there is nothing
            // we can do about it. Remove the window now.
            if (mActivityRecord != null && mAppDied) {
                mActivityRecord.removeDeadWindows();
                return;
            }

            onResizeHandled();
            mWmService.makeWindowFreezingScreenIfNeededLocked(this);

@@ -2009,7 +1993,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    boolean isInteresting() {
        final RecentsAnimationController recentsAnimationController =
                mWmService.getRecentsAnimationController();
        return mActivityRecord != null && !mAppDied
        return mActivityRecord != null
                && (!mActivityRecord.isFreezingScreen() || !mAppFreezing)
                && mViewVisibility == View.VISIBLE
                && (recentsAnimationController == null
@@ -2448,11 +2432,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    @Override
    void removeIfPossible() {
        super.removeIfPossible();
        removeIfPossible(false /*keepVisibleDeadWindow*/);
    }

    private void removeIfPossible(boolean keepVisibleDeadWindow) {
        mWindowRemovalAllowed = true;
        ProtoLog.v(WM_DEBUG_ADD_REMOVE,
                "removeIfPossible: %s callers=%s", this, Debug.getCallers(5));
@@ -2527,21 +2506,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                // If we are not currently running the exit animation, we need to see about starting one
                wasVisible = isVisible();

                if (keepVisibleDeadWindow) {
                    ProtoLog.v(WM_DEBUG_ADD_REMOVE,
                            "Not removing %s because app died while it's visible", this);

                    mAppDied = true;
                    setDisplayLayoutNeeded();
                    mWmService.mWindowPlacerLocked.performSurfacePlacement();

                    // Set up a replacement input channel since the app is now dead.
                    // We need to catch tapping on the dead window to restart the app.
                    openInputChannel(null);
                    displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
                    return;
                }

                // Remove immediately if there is display transition because the animation is
                // usually unnoticeable (e.g. covered by rotation animation) and the animation
                // bounds could be inconsistent, such as depending on when the window applies
@@ -2715,19 +2679,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                || (isVisible() && mActivityRecord != null && mActivityRecord.isVisible());
    }

    private final class DeadWindowEventReceiver extends InputEventReceiver {
        DeadWindowEventReceiver(InputChannel inputChannel) {
            super(inputChannel, mWmService.mH.getLooper());
        }
        @Override
        public void onInputEvent(InputEvent event) {
            finishInputEvent(event, true);
        }
    }
    /** Fake event receiver for windows that died visible. */
    private DeadWindowEventReceiver mDeadWindowEventReceiver;

    void openInputChannel(InputChannel outInputChannel) {
    void openInputChannel(@NonNull InputChannel outInputChannel) {
        if (mInputChannel != null) {
            throw new IllegalStateException("Window already has an input channel.");
        }
@@ -2736,14 +2688,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        mInputChannelToken = mInputChannel.getToken();
        mInputWindowHandle.setToken(mInputChannelToken);
        mWmService.mInputToWindowMap.put(mInputChannelToken, this);
        if (outInputChannel != null) {
        mInputChannel.copyTo(outInputChannel);
        } else {
            // If the window died visible, we setup a fake input channel, so that taps
            // can still detected by input monitor channel, and we can relaunch the app.
            // Create fake event receiver that simply reports all events as handled.
            mDeadWindowEventReceiver = new DeadWindowEventReceiver(mInputChannel);
        }
    }

    /**
@@ -2754,10 +2699,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }

    void disposeInputChannel() {
        if (mDeadWindowEventReceiver != null) {
            mDeadWindowEventReceiver.dispose();
            mDeadWindowEventReceiver = null;
        }
        if (mInputChannelToken != null) {
            // Unregister server channel first otherwise it complains about broken channel.
            mWmService.mInputManager.removeInputChannel(mInputChannelToken);
@@ -3084,11 +3025,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                            .windowForClientLocked(mSession, mClient, false);
                    Slog.i(TAG, "WIN DEATH: " + win);
                    if (win != null) {
                        final DisplayContent dc = getDisplayContent();
                        if (win.mActivityRecord != null && win.mActivityRecord.findMainWindow() == win) {
                            mWmService.mTaskSnapshotController.onAppDied(win.mActivityRecord);
                        }
                        win.removeIfPossible(shouldKeepVisibleDeadAppWindow());
                        win.removeIfPossible();
                    } else if (mHasSurface) {
                        Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
                        WindowState.this.removeIfPossible();
@@ -3100,32 +3040,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        }
    }

    /**
     * Returns true if this window is visible and belongs to a dead app and shouldn't be removed,
     * because we want to preserve its location on screen to be re-activated later when the user
     * interacts with it.
     */
    private boolean shouldKeepVisibleDeadAppWindow() {
        if (!isVisible() || mActivityRecord == null || !mActivityRecord.isClientVisible()) {
            // Not a visible app window or the app isn't dead.
            return false;
        }

        if (mAttrs.token != mClient.asBinder()) {
            // The window was add by a client using another client's app token. We don't want to
            // keep the dead window around for this case since this is meant for 'real' apps.
            return false;
        }

        if (mAttrs.type == TYPE_APPLICATION_STARTING) {
            // We don't keep starting windows since they were added by the window manager before
            // the app even launched.
            return false;
        }

        return getWindowConfiguration().keepVisibleDeadAppWindowOnScreen();
    }

    /** Returns {@code true} if this window desires key events. */
    boolean canReceiveKeys() {
        return canReceiveKeys(false /* fromUserTouch */);
@@ -3972,7 +3886,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    @Override
    public void notifyInsetsControlChanged() {
        ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "notifyInsetsControlChanged for %s ", this);
        if (mAppDied || mRemoved) {
        if (mRemoved) {
            return;
        }
        final InsetsStateController stateController =
@@ -4278,7 +4192,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            pw.println(prefix + "mToken=" + mToken);
            if (mActivityRecord != null) {
                pw.println(prefix + "mActivityRecord=" + mActivityRecord);
                pw.print(prefix + "mAppDied=" + mAppDied);
                pw.print(prefix + "drawnStateEvaluated=" + getDrawnStateEvaluated());
                pw.println(prefix + "mightAffectAllDrawn=" + mightAffectAllDrawn());
            }
@@ -5407,10 +5320,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }

    private void applyDims() {
        if (!mAnimatingExit && mAppDied) {
            mIsDimming = true;
            getDimmer().dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);
        } else if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind())
        if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind())
                   && isVisibleNow() && !mHidden) {
            // Only show the Dimmer when the following is satisfied:
            // 1. The window has the flag FLAG_DIM_BEHIND or blur behind is requested