diff options
| author | 2021-08-30 10:49:59 +0800 | |
|---|---|---|
| committer | 2021-09-06 08:34:55 +0000 | |
| commit | c86f1eb19e2578073849118fe1e81f694d5fae4b (patch) | |
| tree | d00413b239c436e6d79934cc245588a9deca8fe2 | |
| parent | 296e07d9719f8cc09cbb3ea8378b7f02edce0ee2 (diff) | |
Use SystemUI theme to inflate FrameLayout and SplashScreenView
The FrameLayout and SplashScreenView are only used as container in
StartingSurfaceDrawer, so they do not need to be inflated by app's
context, which could be affected by app's resources.
Bug: 197936273
Test: cold launch test app and show splash screen.
Test: launch several apps to verify that everything is fine.
Test: atest StartingSurfaceDrawerTests
Change-Id: I6de444546b5dfba23fc1d7c9c4deb12787d667c5
4 files changed, 29 insertions, 14 deletions
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index acf20d701eeb..6a875d1be65d 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -316,7 +316,8 @@ public final class SplashScreenView extends FrameLayout { } private SurfaceView createSurfaceView(@NonNull SplashScreenView view) { - final SurfaceView surfaceView = new SurfaceView(view.getContext()); + final Context viewContext = view.getContext(); + final SurfaceView surfaceView = new SurfaceView(viewContext); surfaceView.setPadding(0, 0, 0, 0); surfaceView.setBackground(mIconBackground); if (mSurfacePackage == null) { @@ -326,10 +327,10 @@ public final class SplashScreenView extends FrameLayout { + Thread.currentThread().getId()); } - SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext, - mContext.getDisplay(), + SurfaceControlViewHost viewHost = new SurfaceControlViewHost(viewContext, + viewContext.getDisplay(), surfaceView.getHostToken()); - ImageView imageView = new ImageView(mContext); + ImageView imageView = new ImageView(viewContext); imageView.setBackground(mIconDrawable); viewHost.setView(imageView, mIconSize, mIconSize); SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index 22865988e880..3db33f3f1216 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -50,6 +50,7 @@ import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Slog; +import android.view.ContextThemeWrapper; import android.view.SurfaceControl; import android.view.View; import android.window.SplashScreenView; @@ -299,6 +300,11 @@ public class SplashscreenContentDrawer { } } + /** Creates the wrapper with system theme to avoid unexpected styles from app. */ + ContextThemeWrapper createViewContextWrapper(Context appContext) { + return new ContextThemeWrapper(appContext, mContext.getTheme()); + } + /** The configuration of the splash screen window. */ public static class SplashScreenWindowAttrs { private int mWindowBgResId = 0; @@ -472,7 +478,8 @@ public class SplashscreenContentDrawer { } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon"); - final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext) + final ContextThemeWrapper wrapper = createViewContextWrapper(mContext); + final SplashScreenView.Builder builder = new SplashScreenView.Builder(wrapper) .setBackgroundColor(mThemeColor) .setOverlayDrawable(mOverlayDrawable) .setIconSize(iconSize) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 6c60bad31dba..645b881558fb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -146,7 +146,7 @@ public class StartingSurfaceDrawer { return mDisplayManager.getDisplay(displayId); } - private int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) { + int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) { return splashScreenThemeResId != 0 ? splashScreenThemeResId : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource() @@ -174,7 +174,7 @@ public class StartingSurfaceDrawer { final int displayId = taskInfo.displayId; final int taskId = taskInfo.taskId; - Context context = mContext; + // replace with the default theme if the application didn't set final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo); if (DEBUG_SPLASH_SCREEN) { @@ -182,12 +182,16 @@ public class StartingSurfaceDrawer { + " theme=" + Integer.toHexString(theme) + " task=" + taskInfo.taskId + " suggestType=" + suggestType); } - final Display display = getDisplay(displayId); if (display == null) { // Can't show splash screen on requested display, so skip showing at all. return; } + Context context = displayId == DEFAULT_DISPLAY + ? mContext : mContext.createDisplayContext(display); + if (context == null) { + return; + } if (theme != context.getThemeResId()) { try { context = context.createPackageContextAsUser(activityInfo.packageName, @@ -298,7 +302,8 @@ public class StartingSurfaceDrawer { // Record whether create splash screen view success, notify to current thread after // create splash screen view finished. final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier(); - final FrameLayout rootLayout = new FrameLayout(context); + final FrameLayout rootLayout = new FrameLayout( + mSplashscreenContentDrawer.createViewContextWrapper(context)); rootLayout.setPadding(0, 0, 0, 0); rootLayout.setFitsSystemWindows(false); final Runnable setViewSynchronized = () -> { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java index 160b3673aa8a..2994e7181369 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; import android.app.ActivityManager; @@ -85,7 +86,6 @@ public class StartingSurfaceDrawerTests { static final class TestStartingSurfaceDrawer extends StartingSurfaceDrawer{ int mAddWindowForTask = 0; - int mViewThemeResId; TestStartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor, TransactionPool pool) { @@ -97,7 +97,6 @@ public class StartingSurfaceDrawerTests { WindowManager.LayoutParams params, int suggestType) { // listen for addView mAddWindowForTask = taskId; - mViewThemeResId = view.getContext().getThemeResId(); // Do not wait for background color return false; } @@ -167,12 +166,15 @@ public class StartingSurfaceDrawerTests { final int taskId = 1; final StartingWindowInfo windowInfo = createWindowInfo(taskId, 0); + final int[] theme = new int[1]; + doAnswer(invocation -> theme[0] = (Integer) invocation.callRealMethod()) + .when(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any()); + mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder, STARTING_WINDOW_TYPE_SPLASH_SCREEN); waitHandlerIdle(mTestHandler); - verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(), - eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN)); - assertNotEquals(mStartingSurfaceDrawer.mViewThemeResId, 0); + verify(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any()); + assertNotEquals(theme[0], 0); } @Test |