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
This commit is contained in:
Winson Chung
2019-06-17 17:19:13 -07:00
parent 1d4391580e
commit ffde2ea8e5
11 changed files with 76 additions and 30 deletions

View File

@@ -380,7 +380,7 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
// 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);
}

View File

@@ -1080,10 +1080,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
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);

View File

@@ -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>

View File

@@ -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" />

View File

@@ -32,4 +32,5 @@
int32 system_ui_visibility = 8;
bool is_translucent = 9;
string top_activity_component = 10;
float scale = 11;
}

View File

@@ -95,6 +95,7 @@ class TaskSnapshotController {
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 @@ class TaskSnapshotController {
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 @@ class TaskSnapshotController {
}
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 @@ class TaskSnapshotController {
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 @@ class TaskSnapshotController {
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 @@ class TaskSnapshotController {
}
void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "mFullSnapshotScale=" + mFullSnapshotScale);
mCache.dump(pw, prefix);
}
}

View File

@@ -87,14 +87,16 @@ class TaskSnapshotLoader {
+ 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;

View File

@@ -342,6 +342,7 @@ class TaskSnapshotPersister {
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 @@ class TaskSnapshotPersister {
}
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 @@ class TaskSnapshotPersister {
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 @@ class TaskSnapshotPersister {
Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
return false;
}
reduced.recycle();
swBitmap.recycle();
return true;
}

View File

@@ -248,7 +248,7 @@ class TaskSnapshotSurface implements StartingSurface {
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 @@ class TaskSnapshotSurface implements StartingSurface {
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 @@ class TaskSnapshotSurface implements StartingSurface {
(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 @@ class TaskSnapshotSurface implements StartingSurface {
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 @@ class TaskSnapshotSurface implements StartingSurface {
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);

View File

@@ -145,7 +145,10 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
@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();
@@ -252,6 +255,27 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
assertEquals(lightBarFlags, snapshotB.getSystemUiVisibility());
}
@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());

View File

@@ -77,12 +77,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
}
TaskSnapshot createSnapshot() {
return createSnapshot(1f /* scale */);
}
TaskSnapshot createSnapshot(float scale) {
return new TaskSnapshotBuilder()
.setScale(scale)
.build();
}
@@ -92,6 +87,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
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 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
return this;
}
TaskSnapshotBuilder setReducedResolution(boolean reducedResolution) {
mReducedResolution = reducedResolution;
return this;
}
TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
mIsRealSnapshot = isRealSnapshot;
return this;
@@ -130,7 +131,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
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);
}
}