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

Commit 6932c77d authored by Vadim Caen's avatar Vadim Caen
Browse files

Postpone setting background when window is set.

The DecorView background is the same as the window background.
If a background is set before the DecorView's window is set,
setWindowBackground will throw an NPE.

This happens when the default theme has android:view set with a
non-null value, so the background is set within the super constructor
(in View.java) before the PhoneWindow is set in the constructor of
DecorView.

Fixes: 137764086
Test: regression test DecoreViewTest.setBackgroundWithNoWindow()
Change-Id: I3b3c31cfe50ffa7284a1b37ca4b2f864be77c838
parent 7d3306a0
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -249,6 +249,14 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    private Drawable mOriginalBackgroundDrawable;
    private Drawable mLastOriginalBackgroundDrawable;
    private Drawable mResizingBackgroundDrawable;

    /**
     * Temporary holder for a window background when it is set before {@link #mWindow} is
     * initialized. It will be set as the actual background once {@link #setWindow(PhoneWindow)} is
     * called.
     */
    @Nullable
    private Drawable mPendingWindowBackground;
    private Drawable mCaptionBackgroundDrawable;
    private Drawable mUserCaptionBackgroundDrawable;

@@ -961,6 +969,10 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    }

    public void setWindowBackground(Drawable drawable) {
        if (mWindow == null) {
            mPendingWindowBackground = drawable;
            return;
        }
        if (mOriginalBackgroundDrawable != drawable) {
            mOriginalBackgroundDrawable = drawable;
            updateBackgroundDrawable();
@@ -2003,6 +2015,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            DecorContext decorContext = (DecorContext) context;
            decorContext.setPhoneWindow(mWindow);
        }
        if (mPendingWindowBackground != null) {
            Drawable background = mPendingWindowBackground;
            mPendingWindowBackground = null;
            setWindowBackground(background);
        }
    }

    @Override
+3 −0
Original line number Diff line number Diff line
@@ -39,4 +39,7 @@
        <item name="android:colorBackground">@null</item>
        <item name="android:windowBackgroundFallback">#0000FF</item>
    </style>
    <style name="ViewDefaultBackground">
        <item name="android:background">#00000000</item>
    </style>
</resources>
+9 −0
Original line number Diff line number Diff line
@@ -76,4 +76,13 @@ public class DecorViewTest {
        expectedBitmap.getPixels(expPixels, 0, w, 0, 0, w, h);
        assertThat(Arrays.toString(expPixels)).isEqualTo(Arrays.toString(resPixels));
    }

    @Test
    public void setBackgroundWithNoWindow() {
        PhoneWindow phoneWindow = new PhoneWindow(mContext);
        // Set a theme that defines a non-null value for android:background
        mContext.setTheme(R.style.ViewDefaultBackground);
        DecorView decorView = (DecorView) phoneWindow.getDecorView();
        assertThat(decorView.getBackground()).isNotNull();
    }
}