Add config to control full task snapshot scale
- Also save the scale with the snapshot data instead of trying to infer it
from the state
- Also recycle the reduced resolution snapshot copy after writing it
Bug: 135150767
Test: atest TaskSnapshotPersisterLoaderTest
Change-Id: I64a9ccf16f3966ad5c6d07ff0b6ce8e9dd710e40
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index fa73758..7bfed91 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -380,7 +380,7 @@
// don't want the navigation bar background be moving around when resizing in docked mode.
// However, we need it for the transitions into/out of docked mode.
if (mNavigationBarColor != null && fullscreen) {
- DecorView.getNavigationBarRect(width, height, stableInsets, systemInsets, mTmpRect);
+ DecorView.getNavigationBarRect(width, height, stableInsets, systemInsets, mTmpRect, 1f);
mNavigationBarColor.setBounds(mTmpRect);
mNavigationBarColor.draw(canvas);
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 723f161..afe7954 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1080,10 +1080,13 @@
}
public static void getNavigationBarRect(int canvasWidth, int canvasHeight, Rect stableInsets,
- Rect contentInsets, Rect outRect) {
- final int bottomInset = getColorViewBottomInset(stableInsets.bottom, contentInsets.bottom);
- final int leftInset = getColorViewLeftInset(stableInsets.left, contentInsets.left);
- final int rightInset = getColorViewLeftInset(stableInsets.right, contentInsets.right);
+ Rect contentInsets, Rect outRect, float scale) {
+ final int bottomInset =
+ (int) (getColorViewBottomInset(stableInsets.bottom, contentInsets.bottom) * scale);
+ final int leftInset =
+ (int) (getColorViewLeftInset(stableInsets.left, contentInsets.left) * scale);
+ final int rightInset =
+ (int) (getColorViewLeftInset(stableInsets.right, contentInsets.right) * scale);
final int size = getNavBarSize(bottomInset, rightInset, leftInset);
if (isNavBarToRightEdge(bottomInset, rightInset)) {
outRect.set(canvasWidth - size, 0, canvasWidth, canvasHeight);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 14abb77..dd75c56 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2787,6 +2787,9 @@
screen. -->
<bool name="config_lowRamTaskSnapshotsAndRecents">false</bool>
+ <!-- The amount to scale fullscreen snapshots for Overview and snapshot starting windows. -->
+ <item name="config_fullTaskSnapshotScale" format="float" type="dimen">1.0</item>
+
<!-- Determines whether recent tasks are provided to the user. Default device has recents
property. If this is false, then the following recents config flags are ignored. -->
<bool name="config_hasRecents">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9d75654..50814c5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -355,6 +355,7 @@
<java-symbol type="bool" name="config_enableMultiUserUI"/>
<java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
<java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
+ <java-symbol type="dimen" name="config_fullTaskSnapshotScale" />
<java-symbol type="bool" name="config_lowRamTaskSnapshotsAndRecents" />
<java-symbol type="bool" name="config_hasRecents" />
<java-symbol type="string" name="config_recentsComponentName" />
diff --git a/proto/src/task_snapshot.proto b/proto/src/task_snapshot.proto
index a1bbe52..381d983 100644
--- a/proto/src/task_snapshot.proto
+++ b/proto/src/task_snapshot.proto
@@ -32,4 +32,5 @@
int32 system_ui_visibility = 8;
bool is_translucent = 9;
string top_activity_component = 10;
+ float scale = 11;
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index d526e7c..6e7ab2e3 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -95,6 +95,7 @@
private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>();
private final ArraySet<Task> mTmpTasks = new ArraySet<>();
private final Handler mHandler = new Handler();
+ private final float mFullSnapshotScale;
private final Rect mTmpRect = new Rect();
@@ -124,6 +125,8 @@
PackageManager.FEATURE_EMBEDDED);
mIsRunningOnWear = mService.mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WATCH);
+ mFullSnapshotScale = mService.mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_fullTaskSnapshotScale);
}
void systemReady() {
@@ -287,7 +290,9 @@
}
final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
- final float scaleFraction = isLowRamDevice ? mPersister.getReducedScale() : 1f;
+ final float scaleFraction = isLowRamDevice
+ ? mPersister.getReducedScale()
+ : mFullSnapshotScale;
final WindowState mainWindow = appWindowToken.findMainWindow();
if (mainWindow == null) {
@@ -378,9 +383,10 @@
task.getTaskDescription().getBackgroundColor(), 255);
final LayoutParams attrs = mainWindow.getAttrs();
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
- attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription());
- final int width = task.getBounds().width();
- final int height = task.getBounds().height();
+ attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription(),
+ mFullSnapshotScale);
+ final int width = (int) (task.getBounds().width() * mFullSnapshotScale);
+ final int height = (int) (task.getBounds().height() * mFullSnapshotScale);
final RenderNode node = RenderNode.create("TaskSnapshotController", null);
node.setLeftTopRightBottom(0, 0, width, height);
@@ -399,7 +405,7 @@
return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
hwBitmap.getColorSpace(), topChild.getConfiguration().orientation,
getInsets(mainWindow), ActivityManager.isLowRamDeviceStatic() /* reduced */,
- 1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(),
+ mFullSnapshotScale, false /* isRealSnapshot */, task.getWindowingMode(),
getSystemUiVisibility(task), false);
}
@@ -481,6 +487,7 @@
}
void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "mFullSnapshotScale=" + mFullSnapshotScale);
mCache.dump(pw, prefix);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index f7b8945..fcd97c1 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -87,14 +87,16 @@
+ bitmapFile.getPath());
return null;
}
- ComponentName topActivityComponent = ComponentName.unflattenFromString(
+ final ComponentName topActivityComponent = ComponentName.unflattenFromString(
proto.topActivityComponent);
+ // For legacy snapshots, restore the scale based on the reduced resolution state
+ final float legacyScale = reducedResolution ? mPersister.getReducedScale() : 1f;
+ final float scale = Float.compare(proto.scale, 0f) != 0 ? proto.scale : legacyScale;
return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
proto.orientation,
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
- reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f,
- proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
- proto.isTranslucent);
+ reducedResolution, scale, proto.isRealSnapshot, proto.windowingMode,
+ proto.systemUiVisibility, proto.isTranslucent);
} catch (IOException e) {
Slog.w(TAG, "Unable to load task snapshot data for taskId=" + taskId);
return null;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 0b63f48..72fc189 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -342,6 +342,7 @@
proto.systemUiVisibility = mSnapshot.getSystemUiVisibility();
proto.isTranslucent = mSnapshot.isTranslucent();
proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
+ proto.scale = mSnapshot.getScale();
final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
final File file = getProtoFile(mTaskId, mUserId);
final AtomicFile atomicFile = new AtomicFile(file);
@@ -369,12 +370,13 @@
}
final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
- final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
final Bitmap reduced = mSnapshot.isReducedResolution()
? swBitmap
: Bitmap.createScaledBitmap(swBitmap,
(int) (bitmap.getWidth() * mReducedScale),
(int) (bitmap.getHeight() * mReducedScale), true /* filter */);
+
+ final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
try {
FileOutputStream reducedFos = new FileOutputStream(reducedFile);
reduced.compress(JPEG, QUALITY, reducedFos);
@@ -383,6 +385,7 @@
Slog.e(TAG, "Unable to open " + reducedFile +" for persisting.", e);
return false;
}
+ reduced.recycle();
// For snapshots with reduced resolution, do not create or save full sized bitmaps
if (mSnapshot.isReducedResolution()) {
@@ -399,7 +402,6 @@
Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
return false;
}
- reduced.recycle();
swBitmap.recycle();
return true;
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 5d99db5..a7760a86 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -248,7 +248,7 @@
mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
mTaskBounds = taskBounds;
mSystemBarBackgroundPainter = new SystemBarBackgroundPainter(windowFlags,
- windowPrivateFlags, sysUiVis, taskDescription);
+ windowPrivateFlags, sysUiVis, taskDescription, 1f);
mStatusBarColor = taskDescription.getStatusBarColor();
mOrientationOnCreation = currentOrientation;
}
@@ -488,12 +488,14 @@
private final int mWindowFlags;
private final int mWindowPrivateFlags;
private final int mSysUiVis;
+ private final float mScale;
- SystemBarBackgroundPainter( int windowFlags, int windowPrivateFlags, int sysUiVis,
- TaskDescription taskDescription) {
+ SystemBarBackgroundPainter(int windowFlags, int windowPrivateFlags, int sysUiVis,
+ TaskDescription taskDescription, float scale) {
mWindowFlags = windowFlags;
mWindowPrivateFlags = windowPrivateFlags;
mSysUiVis = sysUiVis;
+ mScale = scale;
final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
final int semiTransparent = context.getColor(
R.color.system_bar_background_semi_transparent);
@@ -521,7 +523,7 @@
(mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)) {
- return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
+ return (int) (getColorViewTopInset(mStableInsets.top, mContentInsets.top) * mScale);
} else {
return 0;
}
@@ -544,8 +546,8 @@
int statusBarHeight) {
if (statusBarHeight > 0 && Color.alpha(mStatusBarColor) != 0
&& (alreadyDrawnFrame == null || c.getWidth() > alreadyDrawnFrame.right)) {
- final int rightInset = DecorView.getColorViewRightInset(mStableInsets.right,
- mContentInsets.right);
+ final int rightInset = (int) (DecorView.getColorViewRightInset(mStableInsets.right,
+ mContentInsets.right) * mScale);
final int left = alreadyDrawnFrame != null ? alreadyDrawnFrame.right : 0;
c.drawRect(left, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
}
@@ -555,7 +557,7 @@
void drawNavigationBarBackground(Canvas c) {
final Rect navigationBarRect = new Rect();
getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
- navigationBarRect);
+ navigationBarRect, mScale);
final boolean visible = isNavigationBarColorViewVisible();
if (visible && Color.alpha(mNavigationBarColor) != 0 && !navigationBarRect.isEmpty()) {
c.drawRect(navigationBarRect, mNavigationBarPaint);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index b0eafee..f958867 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -145,7 +145,10 @@
@Test
public void testLowResolutionPersistAndLoadSnapshot() {
- TaskSnapshot a = createSnapshot(0.5f /* reducedResolution */);
+ TaskSnapshot a = new TaskSnapshotBuilder()
+ .setScale(0.5f)
+ .setReducedResolution(true)
+ .build();
assertTrue(a.isReducedResolution());
mPersister.persistSnapshot(1 , mTestUserId, a);
mPersister.waitForQueueEmpty();
@@ -253,6 +256,27 @@
}
@Test
+ public void testScalePersistAndLoadSnapshot() {
+ TaskSnapshot a = new TaskSnapshotBuilder()
+ .setScale(0.25f)
+ .build();
+ TaskSnapshot b = new TaskSnapshotBuilder()
+ .setScale(0.75f)
+ .build();
+ assertEquals(0.25f, a.getScale(), 1E-5);
+ assertEquals(0.75f, b.getScale(), 1E-5);
+ mPersister.persistSnapshot(1, mTestUserId, a);
+ mPersister.persistSnapshot(2, mTestUserId, b);
+ mPersister.waitForQueueEmpty();
+ final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+ final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+ assertNotNull(snapshotA);
+ assertNotNull(snapshotB);
+ assertEquals(0.25f, snapshotA.getScale(), 1E-5);
+ assertEquals(0.75f, snapshotB.getScale(), 1E-5);
+ }
+
+ @Test
public void testRemoveObsoleteFiles() {
mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
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 c3b0a67..e004cd3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -77,12 +77,7 @@
}
TaskSnapshot createSnapshot() {
- return createSnapshot(1f /* scale */);
- }
-
- TaskSnapshot createSnapshot(float scale) {
return new TaskSnapshotBuilder()
- .setScale(scale)
.build();
}
@@ -92,6 +87,7 @@
static class TaskSnapshotBuilder {
private float mScale = 1f;
+ private boolean mReducedResolution = false;
private boolean mIsRealSnapshot = true;
private boolean mIsTranslucent = false;
private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
@@ -102,6 +98,11 @@
return this;
}
+ TaskSnapshotBuilder setReducedResolution(boolean reducedResolution) {
+ mReducedResolution = reducedResolution;
+ return this;
+ }
+
TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
mIsRealSnapshot = isRealSnapshot;
return this;
@@ -130,7 +131,7 @@
buffer.unlockCanvasAndPost(c);
return new TaskSnapshot(new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
- mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
+ mReducedResolution, mScale, mIsRealSnapshot,
mWindowingMode, mSystemUiVisibility, mIsTranslucent);
}
}