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

Commit b2594850 authored by Robert Carr's avatar Robert Carr
Browse files

Fix bugs with takeSurface and preserveWindows.

When reusing a ViewRoot and DecorView as we do with preserveWindows
there are two issues with SurfaceHolders.  First, we update the
SurfaceHolder callbacks when we call ViewRootImpl.setView. In the
case of preserved window relaunch, the DecorView is reused and there is
no call to setView. We need the ActivityThread to notify the ViewRoot
that something has changed. Secondly, we were assuming the only time
a new surface would be created for the purposes of SurfaceHolder
notification was when we previously did not have a valid surface.
Instead we need to check if the native Surface object has changed each time we
get a result from relayout.

Bug: 28331264
Change-Id: If1b4aab9b2ba579fa040e2a3ab4471842476d82f
parent a51388d6
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3474,6 +3474,12 @@ public final class ActivityThread {
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    // Normally the ViewRoot sets up callbacks with the Activity
                    // in addView->ViewRootImpl#setView. If we are instead reusing
                    // the decor view we have to notify the view root that the
                    // callbacks may have changed.
                    ViewRootImpl impl = decor.getViewRootImpl();
                    impl.notifyChildRebuilt();
                }
                if (a.mVisibleFromClient && !a.mWindowAdded) {
                    a.mWindowAdded = true;
+31 −2
Original line number Diff line number Diff line
@@ -513,6 +513,34 @@ public final class ViewRootImpl implements ViewParent,
        return false;
    }

    /**
     * Notifies us that our child has been rebuilt, following
     * a window preservation operation. In these cases we
     * keep the same DecorView, but the activity controlling it
     * is a different instance, and we need to update our
     * callbacks.
     *
     * @hide
     */
    public void notifyChildRebuilt() {
        if (mView instanceof RootViewSurfaceTaker) {
            mSurfaceHolderCallback =
                ((RootViewSurfaceTaker)mView).willYouTakeTheSurface();
            if (mSurfaceHolderCallback != null) {
                mSurfaceHolder = new TakenSurfaceHolder();
                mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
            } else {
                mSurfaceHolder = null;
            }

            mInputQueueCallback =
                ((RootViewSurfaceTaker)mView).willYouTakeTheInputQueue();
            if (mInputQueueCallback != null) {
                mInputQueueCallback.onInputQueueCreated(mInputQueue);
            }
        }
    }

    /**
     * We have one child
     */
@@ -1645,6 +1673,8 @@ public final class ViewRootImpl implements ViewParent,
        boolean insetsPending = false;
        int relayoutResult = 0;

        final int surfaceGenerationId = mSurface.getGenerationId();

        final boolean isViewVisible = viewVisibility == View.VISIBLE;
        if (mFirst || windowShouldResize || insetsChanged ||
                viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
@@ -1689,7 +1719,6 @@ public final class ViewRootImpl implements ViewParent,
                    }
                    mChoreographer.mFrameInfo.addFlags(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED);
                }
                final int surfaceGenerationId = mSurface.getGenerationId();
                relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);

                if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString()
@@ -1883,7 +1912,7 @@ public final class ViewRootImpl implements ViewParent,
                mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
                mSurfaceHolder.mSurfaceLock.unlock();
                if (mSurface.isValid()) {
                    if (!hadSurface) {
                    if (!hadSurface || surfaceGenerationId != mSurface.getGenerationId()) {
                        mSurfaceHolder.ungetCallbacks();

                        mIsCreating = true;