summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotPersister.java44
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotSurface.java25
3 files changed, 66 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bc7f33021c77..ecf9067b55c9 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -18,6 +18,8 @@ package com.android.server.wm;
import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
+import static com.android.server.wm.TaskSnapshotPersister.DISABLE_FULL_SIZED_BITMAPS;
+import static com.android.server.wm.TaskSnapshotPersister.REDUCED_SCALE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -188,7 +190,8 @@ class TaskSnapshotController {
*/
@Nullable TaskSnapshot getSnapshot(int taskId, int userId, boolean restoreFromDisk,
boolean reducedResolution) {
- return mCache.getSnapshot(taskId, userId, restoreFromDisk, reducedResolution);
+ return mCache.getSnapshot(taskId, userId, restoreFromDisk, reducedResolution
+ || DISABLE_FULL_SIZED_BITMAPS);
}
/**
@@ -209,14 +212,16 @@ class TaskSnapshotController {
if (mainWindow == null) {
return null;
}
+ final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
+ final float scaleFraction = isLowRamDevice ? REDUCED_SCALE : 1f;
final GraphicBuffer buffer = top.mDisplayContent.screenshotApplicationsToBuffer(top.token,
- -1, -1, false, 1.0f, false, true);
+ -1, -1, false, scaleFraction, false, true);
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
return null;
}
return new TaskSnapshot(buffer, top.getConfiguration().orientation,
- minRect(mainWindow.mContentInsets, mainWindow.mStableInsets), false /* reduced */,
- 1f /* scale */);
+ minRect(mainWindow.mContentInsets, mainWindow.mStableInsets),
+ isLowRamDevice /* reduced */, scaleFraction /* scale */);
}
private boolean shouldDisableSnapshots() {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index f90b3fb6c1de..1252aee14964 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -21,6 +21,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.TestApi;
+import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
@@ -53,6 +54,7 @@ class TaskSnapshotPersister {
private static final String SNAPSHOTS_DIRNAME = "snapshots";
private static final String REDUCED_POSTFIX = "_reduced";
static final float REDUCED_SCALE = 0.5f;
+ static final boolean DISABLE_FULL_SIZED_BITMAPS = ActivityManager.isLowRamDeviceStatic();
private static final long DELAY_MS = 100;
private static final int QUALITY = 95;
private static final String PROTO_EXTENSION = ".proto";
@@ -183,6 +185,11 @@ class TaskSnapshotPersister {
}
File getBitmapFile(int taskId, int userId) {
+ // Full sized bitmaps are disabled on low ram devices
+ if (DISABLE_FULL_SIZED_BITMAPS) {
+ Slog.wtf(TAG, "This device does not support full sized resolution bitmaps.");
+ return null;
+ }
return new File(getDirectory(userId), taskId + BITMAP_EXTENSION);
}
@@ -197,11 +204,15 @@ class TaskSnapshotPersister {
private void deleteSnapshot(int taskId, int userId) {
final File protoFile = getProtoFile(taskId, userId);
- final File bitmapFile = getBitmapFile(taskId, userId);
final File bitmapReducedFile = getReducedResolutionBitmapFile(taskId, userId);
protoFile.delete();
- bitmapFile.delete();
bitmapReducedFile.delete();
+
+ // Low ram devices do not have a full sized file to delete
+ if (!DISABLE_FULL_SIZED_BITMAPS) {
+ final File bitmapFile = getBitmapFile(taskId, userId);
+ bitmapFile.delete();
+ }
}
interface DirectoryResolver {
@@ -323,7 +334,6 @@ class TaskSnapshotPersister {
boolean writeBuffer() {
final File file = getBitmapFile(mTaskId, mUserId);
- final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
if (bitmap == null) {
Slog.e(TAG, "Invalid task snapshot hw bitmap");
@@ -331,18 +341,32 @@ class TaskSnapshotPersister {
}
final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
- final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
- (int) (bitmap.getWidth() * REDUCED_SCALE),
- (int) (bitmap.getHeight() * REDUCED_SCALE), true /* filter */);
+ final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
+ final Bitmap reduced = mSnapshot.isReducedResolution()
+ ? swBitmap
+ : Bitmap.createScaledBitmap(swBitmap,
+ (int) (bitmap.getWidth() * REDUCED_SCALE),
+ (int) (bitmap.getHeight() * REDUCED_SCALE), true /* filter */);
try {
- FileOutputStream fos = new FileOutputStream(file);
- swBitmap.compress(JPEG, QUALITY, fos);
- fos.close();
FileOutputStream reducedFos = new FileOutputStream(reducedFile);
reduced.compress(JPEG, QUALITY, reducedFos);
reducedFos.close();
} catch (IOException e) {
- Slog.e(TAG, "Unable to open " + file + " or " + reducedFile +" for persisting.", e);
+ Slog.e(TAG, "Unable to open " + reducedFile +" for persisting.", e);
+ return false;
+ }
+
+ // For snapshots with reduced resolution, do not create or save full sized bitmaps
+ if (mSnapshot.isReducedResolution()) {
+ return true;
+ }
+
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ swBitmap.compress(JPEG, QUALITY, fos);
+ fos.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
return false;
}
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 0610b945d20e..4698d72567c4 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -320,6 +320,10 @@ class TaskSnapshotSurface implements StartingSurface {
mChildSurfaceControl.show();
mChildSurfaceControl.setWindowCrop(crop);
mChildSurfaceControl.setPosition(frame.left, frame.top);
+
+ // Scale the mismatch dimensions to fill the task bounds
+ final float scale = 1 / mSnapshot.getScale();
+ mChildSurfaceControl.setMatrix(scale, 0, 0, scale);
} finally {
SurfaceControl.closeTransaction();
}
@@ -332,6 +336,11 @@ class TaskSnapshotSurface implements StartingSurface {
mSurface.release();
}
+ /**
+ * Calculates the snapshot crop in snapshot coordinate space.
+ *
+ * @return crop rect in snapshot coordinate space.
+ */
@VisibleForTesting
Rect calculateSnapshotCrop() {
final Rect rect = new Rect();
@@ -340,16 +349,28 @@ class TaskSnapshotSurface implements StartingSurface {
// Let's remove all system decorations except the status bar, but only if the task is at the
// very top of the screen.
- rect.inset(insets.left, mTaskBounds.top != 0 ? insets.top : 0, insets.right, insets.bottom);
+ rect.inset((int) (insets.left * mSnapshot.getScale()),
+ mTaskBounds.top != 0 ? (int) (insets.top * mSnapshot.getScale()) : 0,
+ (int) (insets.right * mSnapshot.getScale()),
+ (int) (insets.bottom * mSnapshot.getScale()));
return rect;
}
+ /**
+ * Calculates the snapshot frame in window coordinate space from crop.
+ *
+ * @param crop rect that is in snapshot coordinate space.
+ */
@VisibleForTesting
Rect calculateSnapshotFrame(Rect crop) {
final Rect frame = new Rect(crop);
+ final float scale = mSnapshot.getScale();
+
+ // Rescale the frame from snapshot to window coordinate space
+ frame.scale(1 / scale);
// By default, offset it to to top/left corner
- frame.offsetTo(-crop.left, -crop.top);
+ frame.offsetTo((int) (-crop.left / scale), (int) (-crop.top / scale));
// However, we also need to make space for the navigation bar on the left side.
final int colorViewLeftInset = getColorViewLeftInset(mStableInsets.left,