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

Commit 8ed531a9 authored by Evan Rosky's avatar Evan Rosky Committed by Chris Li
Browse files

Change visible-requested updates to "push" model

We do many more queries of isVisibleRequested than we
do sets. Since queries above WindowToken level have to
walk the full subtree, it can waste time. Instead, just
keep track of visibleRequested on all containers and
update it when they change.

Bug: 260059642
Test: atest ActivityVisibilityTests TaskTests
Change-Id: Ied56accea568bb848d38fd77b1b8de47949cd212
parent 765e03a5
Loading
Loading
Loading
Loading
+10 −27
Original line number Diff line number Diff line
@@ -796,12 +796,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    // TODO: Make this final
    int mTargetSdk;

    // Is this window's surface needed?  This is almost like visible, except
    // it will sometimes be true a little earlier: when the activity record has
    // been shown, but is still waiting for its app transition to execute
    // before making its windows shown.
    private boolean mVisibleRequested;

    // Last visibility state we reported to the app token.
    boolean reportedVisible;

@@ -1574,15 +1568,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        if (oldParent != null) {
            oldParent.cleanUpActivityReferences(this);
            // Update isVisibleRequested value of parent TaskFragment and send the callback to the
            // client side if needed.
            oldParent.onActivityVisibleRequestedChanged();
        }

        if (newParent != null) {
            // Update isVisibleRequested value of parent TaskFragment and send the callback to the
            // client side if needed.
            newParent.onActivityVisibleRequestedChanged();
            if (isState(RESUMED)) {
                newParent.setResumedActivity(this, "onParentChanged");
                mImeInsetsFrozenUntilStartInput = false;
@@ -5086,11 +5074,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return mVisible;
    }

    @Override
    boolean isVisibleRequested() {
        return mVisibleRequested;
    }

    void setVisible(boolean visible) {
        if (visible != mVisible) {
            mVisible = visible;
@@ -5105,16 +5088,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * This is the only place that writes {@link #mVisibleRequested} (except unit test). The caller
     * outside of this class should use {@link #setVisibility}.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    void setVisibleRequested(boolean visible) {
        if (visible == mVisibleRequested) {
            return;
        }
        mVisibleRequested = visible;
        final TaskFragment taskFragment = getTaskFragment();
        if (taskFragment != null) {
            taskFragment.onActivityVisibleRequestedChanged();
        }
    @Override
    boolean setVisibleRequested(boolean visible) {
        if (!super.setVisibleRequested(visible)) return false;
        setInsetsFrozen(!visible);
        if (app != null) {
            mTaskSupervisor.onProcessActivityStateChanged(app, false /* forceBatch */);
@@ -5123,6 +5099,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (!visible) {
            finishOrAbortReplacingWindow();
        }
        return true;
    }

    @Override
    protected boolean onChildVisibleRequestedChanged(@Nullable WindowContainer child) {
        // Activity manages visibleRequested directly (it's not determined by children)
        return false;
    }

    /**
+4 −7
Original line number Diff line number Diff line
@@ -3529,13 +3529,10 @@ class Task extends TaskFragment {
    }

    @Override
    void onActivityVisibleRequestedChanged() {
        final boolean prevVisibleRequested = mVisibleRequested;
        // mVisibleRequested is updated in super method.
        super.onActivityVisibleRequestedChanged();
        if (prevVisibleRequested != mVisibleRequested) {
    protected boolean onChildVisibleRequestedChanged(@Nullable WindowContainer child) {
        if (!super.onChildVisibleRequestedChanged(child)) return false;
        sendTaskFragmentParentInfoChangedIfNeeded();
        }
        return true;
    }

    void sendTaskFragmentParentInfoChangedIfNeeded() {
+0 −19
Original line number Diff line number Diff line
@@ -316,9 +316,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {

    final Point mLastSurfaceSize = new Point();

    /** The latest updated value when there's a child {@link #onActivityVisibleRequestedChanged} */
    boolean mVisibleRequested;

    private final Rect mTmpBounds = new Rect();
    private final Rect mTmpFullBounds = new Rect();
    /** For calculating screenWidthDp and screenWidthDp, i.e. the area without the system bars. */
@@ -2787,22 +2784,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        return getWindowingMode() == WINDOWING_MODE_FULLSCREEN || matchParentBounds();
    }

    void onActivityVisibleRequestedChanged() {
        final boolean isVisibleRequested = isVisibleRequested();
        if (mVisibleRequested == isVisibleRequested) {
            return;
        }
        mVisibleRequested = isVisibleRequested;
        final WindowContainer<?> parent = getParent();
        if (parent == null) {
            return;
        }
        final TaskFragment parentTf = parent.asTaskFragment();
        if (parentTf != null) {
            parentTf.onActivityVisibleRequestedChanged();
        }
    }

    @Nullable
    @Override
    TaskFragment getTaskFragment(Predicate<TaskFragment> callback) {
+7 −7
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ class WallpaperWindowToken extends WindowToken {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;

    private boolean mVisibleRequested = false;

    WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
            DisplayContent dc, boolean ownerCanManageAppTokens) {
        this(service, token, explicit, dc, ownerCanManageAppTokens, null /* options */);
@@ -221,15 +219,17 @@ class WallpaperWindowToken extends WindowToken {
        return false;
    }

    void setVisibleRequested(boolean visible) {
        if (mVisibleRequested == visible) return;
        mVisibleRequested = visible;
    @Override
    protected boolean setVisibleRequested(boolean visible) {
        if (!super.setVisibleRequested(visible)) return false;
        setInsetsFrozen(!visible);
        return true;
    }

    @Override
    boolean isVisibleRequested() {
        return mVisibleRequested;
    protected boolean onChildVisibleRequestedChanged(@Nullable WindowContainer child) {
        // Wallpaper manages visibleRequested directly (it's not determined by children)
        return false;
    }

    @Override
+42 −5
Original line number Diff line number Diff line
@@ -314,6 +314,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<

    private boolean mIsFocusable = true;

    /**
     * This indicates whether this window is visible by policy. This can precede physical
     * visibility ({@link #isVisible} - whether it has a surface showing on the screen) in
     * cases where an animation is on-going.
     */
    protected boolean mVisibleRequested;

    /**
     * Used as a unique, cross-process identifier for this Container. It also serves a minimal
     * interface to other processes.
@@ -772,6 +779,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
            parent.mTreeWeight += child.mTreeWeight;
            parent = parent.getParent();
        }
        onChildVisibleRequestedChanged(child);
        onChildPositionChanged(child);
    }

@@ -800,6 +808,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
            parent.mTreeWeight -= child.mTreeWeight;
            parent = parent.getParent();
        }
        onChildVisibleRequestedChanged(null);
        onChildPositionChanged(child);
    }

@@ -1288,13 +1297,41 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
     * the transition is finished.
     */
    boolean isVisibleRequested() {
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final WindowContainer child = mChildren.get(i);
            if (child.isVisibleRequested()) {
        return mVisibleRequested;
    }

    /** @return `true` if visibleRequested changed. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
    boolean setVisibleRequested(boolean visible) {
        if (mVisibleRequested == visible) return false;
        mVisibleRequested = visible;
        final WindowContainer parent = getParent();
        if (parent != null) {
            parent.onChildVisibleRequestedChanged(this);
        }
        return true;
    }

    /**
     * @param child The changed or added child. `null` if a child was removed.
     * @return `true` if visibleRequested changed.
     */
    protected boolean onChildVisibleRequestedChanged(@Nullable WindowContainer child) {
        final boolean childVisReq = child != null && child.isVisibleRequested();
        boolean newVisReq = mVisibleRequested;
        if (childVisReq && !mVisibleRequested) {
            newVisReq = true;
        } else if (!childVisReq && mVisibleRequested) {
            newVisReq = false;
            for (int i = mChildren.size() - 1; i >= 0; --i) {
                final WindowContainer wc = mChildren.get(i);
                if (wc != child && wc.isVisibleRequested()) {
                    newVisReq = true;
                    break;
                }
            }
        return false;
        }
        return setVisibleRequested(newVisReq);
    }

    /**
Loading