[PB] Do not show snapshot if uiMode has changed.
- Record uiMode in TaskSnapshot.
- While preparing predictive back animation, if the uiMode of snapshot
is not match activity's uiMode, fallback to use splash screen surface.
- Draw windowless splash screen with latest theme & configuration.
Flag: EXEMPT bugfix
Bug: 351119448
Test: follow issue description, switch dark/light theme then trigger
predictive back, verify no serious contrast changes.
Test: atest SnapshotDrawerUtilsTest StartingSurfaceDrawerTests
ActivityTaskManagerThumbnailLoaderTest ActivitySnapshotControllerTests
TaskSnapshotPersisterLoaderTest
Change-Id: I8c3b4e9444e5cfacf21c97da3b0d13c1ef76fcf3
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java
index f0144cb..20d1b3b 100644
--- a/core/java/android/window/TaskSnapshot.java
+++ b/core/java/android/window/TaskSnapshot.java
@@ -72,6 +72,7 @@
int mAppearance;
private final boolean mIsTranslucent;
private final boolean mHasImeSurface;
+ private final int mUiMode;
// Must be one of the named color spaces, otherwise, always use SRGB color space.
private final ColorSpace mColorSpace;
private int mInternalReferences;
@@ -96,7 +97,7 @@
Rect contentInsets, Rect letterboxInsets, boolean isLowResolution,
boolean isRealSnapshot, int windowingMode,
@WindowInsetsController.Appearance int appearance, boolean isTranslucent,
- boolean hasImeSurface) {
+ boolean hasImeSurface, int uiMode) {
mId = id;
mCaptureTime = captureTime;
mTopActivityComponent = topActivityComponent;
@@ -114,6 +115,7 @@
mAppearance = appearance;
mIsTranslucent = isTranslucent;
mHasImeSurface = hasImeSurface;
+ mUiMode = uiMode;
}
private TaskSnapshot(Parcel source) {
@@ -136,6 +138,7 @@
mAppearance = source.readInt();
mIsTranslucent = source.readBoolean();
mHasImeSurface = source.readBoolean();
+ mUiMode = source.readInt();
}
/**
@@ -273,6 +276,13 @@
return mAppearance;
}
+ /**
+ * @return The uiMode the screenshot was taken in.
+ */
+ public int getUiMode() {
+ return mUiMode;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -295,6 +305,7 @@
dest.writeInt(mAppearance);
dest.writeBoolean(mIsTranslucent);
dest.writeBoolean(mHasImeSurface);
+ dest.writeInt(mUiMode);
}
@Override
@@ -318,7 +329,8 @@
+ " mAppearance=" + mAppearance
+ " mIsTranslucent=" + mIsTranslucent
+ " mHasImeSurface=" + mHasImeSurface
- + " mInternalReferences=" + mInternalReferences;
+ + " mInternalReferences=" + mInternalReferences
+ + " mUiMode=" + Integer.toHexString(mUiMode);
}
/**
@@ -370,6 +382,7 @@
private boolean mIsTranslucent;
private boolean mHasImeSurface;
private int mPixelFormat;
+ private int mUiMode;
public Builder setId(long id) {
mId = id;
@@ -452,6 +465,14 @@
return this;
}
+ /**
+ * Sets the original uiMode while capture
+ */
+ public Builder setUiMode(int uiMode) {
+ mUiMode = uiMode;
+ return this;
+ }
+
public int getPixelFormat() {
return mPixelFormat;
}
@@ -481,7 +502,8 @@
mWindowingMode,
mAppearance,
mIsTranslucent,
- mHasImeSurface);
+ mHasImeSurface,
+ mUiMode);
}
}
diff --git a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
index 6c8dcd3..fdc00ba 100644
--- a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
+++ b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
@@ -93,7 +93,8 @@
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
false, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
- 0 /* systemUiVisibility */, false /* isTranslucent */, false /* hasImeSurface */);
+ 0 /* systemUiVisibility */, false /* isTranslucent */, false /* hasImeSurface */,
+ 0 /* uiMode */);
}
private static TaskDescription createTaskDescription(int background,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
index f372557..1a38449 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.startingsurface;
-import static android.graphics.Color.WHITE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import android.app.ActivityManager;
@@ -69,8 +68,9 @@
// Can't show splash screen on requested display, so skip showing at all.
return;
}
+ final int theme = getSplashScreenTheme(0 /* splashScreenThemeResId */, activityInfo);
final Context myContext = SplashscreenContentDrawer.createContext(mContext, windowInfo,
- 0 /* theme */, STARTING_WINDOW_TYPE_SPLASH_SCREEN, mDisplayManager);
+ theme, STARTING_WINDOW_TYPE_SPLASH_SCREEN, mDisplayManager);
if (myContext == null) {
return;
}
@@ -86,19 +86,11 @@
final Rect windowBounds = taskInfo.configuration.windowConfiguration.getBounds();
lp.width = windowBounds.width();
lp.height = windowBounds.height();
- final ActivityManager.TaskDescription taskDescription;
- if (taskInfo.taskDescription != null) {
- taskDescription = taskInfo.taskDescription;
- } else {
- taskDescription = new ActivityManager.TaskDescription();
- taskDescription.setBackgroundColor(WHITE);
- }
final FrameLayout rootLayout = new FrameLayout(
mSplashscreenContentDrawer.createViewContextWrapper(myContext));
viewHost.setView(rootLayout, lp);
-
- final int bgColor = taskDescription.getBackgroundColor();
+ final int bgColor = mSplashscreenContentDrawer.estimateTaskBackgroundColor(myContext);
final SplashScreenView splashScreenView = mSplashscreenContentDrawer
.makeSimpleSplashScreenContentView(myContext, windowInfo, bgColor);
rootLayout.addView(splashScreenView);
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 ee9f886..af6c077 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
@@ -370,6 +370,6 @@
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
false, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
0 /* systemUiVisibility */, false /* isTranslucent */,
- hasImeSurface /* hasImeSurface */);
+ hasImeSurface /* hasImeSurface */, 0 /* uiMode */);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
index a73df07..9797c8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
@@ -104,6 +104,7 @@
WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
/* appearance= */ 0,
/* isTranslucent= */ false,
- /* hasImeSurface= */ false
+ /* hasImeSurface= */ false,
+ /* uiMode */ 0
)
}
diff --git a/proto/src/windowmanager.proto b/proto/src/windowmanager.proto
index da4dfa9..6c8a486 100644
--- a/proto/src/windowmanager.proto
+++ b/proto/src/windowmanager.proto
@@ -45,6 +45,7 @@
int32 letterbox_inset_top = 18;
int32 letterbox_inset_right = 19;
int32 letterbox_inset_bottom = 20;
+ int32 ui_mode = 21;
}
// Persistent letterboxing configurations
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 68f37380..19eba5f 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -330,6 +330,7 @@
builder.setIsTranslucent(isTranslucent);
builder.setWindowingMode(source.getWindowingMode());
builder.setAppearance(mainWindow.mAttrs.insetsFlags.appearance);
+ builder.setUiMode(activity.getConfiguration().uiMode);
final Configuration taskConfig = activity.getTask().getConfiguration();
final int displayRotation = taskConfig.windowConfiguration.getDisplayRotation();
@@ -448,7 +449,8 @@
mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),
contentInsets, letterboxInsets, false /* isLowResolution */,
false /* isRealSnapshot */, source.getWindowingMode(),
- attrs.insetsFlags.appearance, false /* isTranslucent */, false /* hasImeSurface */);
+ attrs.insetsFlags.appearance, false /* isTranslucent */, false /* hasImeSurface */,
+ topActivity.getConfiguration().uiMode /* uiMode */);
return validateSnapshot(taskSnapshot);
}
diff --git a/services/core/java/com/android/server/wm/AppSnapshotLoader.java b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
index ed65a2b..5b697e5 100644
--- a/services/core/java/com/android/server/wm/AppSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
@@ -203,7 +203,7 @@
new Rect(proto.letterboxInsetLeft, proto.letterboxInsetTop,
proto.letterboxInsetRight, proto.letterboxInsetBottom),
loadLowResolutionBitmap, proto.isRealSnapshot, proto.windowingMode,
- proto.appearance, proto.isTranslucent, false /* hasImeSurface */);
+ proto.appearance, proto.isTranslucent, false /* hasImeSurface */, proto.uiMode);
} catch (IOException e) {
Slog.w(TAG, "Unable to load task snapshot data for Id=" + id);
return null;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 0f8d68b..3b263ac 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -1862,7 +1862,7 @@
return isSnapshotCompatible(snapshot, visibleOpenActivities) ? snapshot : null;
}
- static boolean isSnapshotCompatible(@NonNull TaskSnapshot snapshot,
+ static boolean isSnapshotCompatible(@Nullable TaskSnapshot snapshot,
@NonNull ActivityRecord[] visibleOpenActivities) {
if (snapshot == null) {
return false;
@@ -1873,6 +1873,12 @@
if (!ar.isSnapshotOrientationCompatible(snapshot)) {
return false;
}
+ final int appNightMode = ar.getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
+ final int snapshotNightMode = snapshot.getUiMode() & Configuration.UI_MODE_NIGHT_MASK;
+ if (appNightMode != snapshotNightMode) {
+ return false;
+ }
oneComponentMatch |= ar.isSnapshotComponentCompatible(snapshot);
}
return oneComponentMatch;
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index 16fcb09..1c8c245 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -313,6 +313,7 @@
proto.appearance = mSnapshot.getAppearance();
proto.isTranslucent = mSnapshot.isTranslucent();
proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
+ proto.uiMode = mSnapshot.getUiMode();
proto.id = mSnapshot.getId();
final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
final File file = mPersistInfoProvider.getProtoFile(mId, mUserId);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
index 03d3029..2a53df9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -258,6 +258,6 @@
Surface.ROTATION_0, new Point(100, 100), new Rect() /* contentInsets */,
new Rect() /* letterboxInsets*/, false /* isLowResolution */,
true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
- false /* isTranslucent */, false /* hasImeSurface */);
+ false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 33f7035d..b95f621 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1413,7 +1413,7 @@
Surface.ROTATION_0, taskSize, new Rect() /* contentInsets */,
new Rect() /* letterboxInsets*/, false /* isLowResolution */,
true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
- false /* isTranslucent */, false /* hasImeSurface */);
+ false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 84c0696..1e0cef0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -227,7 +227,7 @@
// disk.
false /* isLowResolution */,
mIsRealSnapshot, mWindowingMode, mSystemUiVisibility, mIsTranslucent,
- false /* hasImeSurface */);
+ false /* hasImeSurface */, 0 /* uiMode */);
}
}
}