Loading core/java/android/app/ActivityManager.java +107 −0 Original line number Diff line number Diff line Loading @@ -2097,6 +2097,113 @@ public class ActivityManager { return new TaskSnapshot[size]; } }; /** Builder for a {@link TaskSnapshot} object */ public static final class Builder { private long mId; private ComponentName mTopActivity; private GraphicBuffer mSnapshot; private ColorSpace mColorSpace; private int mOrientation; private Rect mContentInsets; private boolean mReducedResolution; private float mScaleFraction; private boolean mIsRealSnapshot; private int mWindowingMode; private int mSystemUiVisibility; private boolean mIsTranslucent; private int mPixelFormat; public Builder setId(long id) { mId = id; return this; } public Builder setTopActivityComponent(ComponentName name) { mTopActivity = name; return this; } public Builder setSnapshot(GraphicBuffer buffer) { mSnapshot = buffer; return this; } public Builder setColorSpace(ColorSpace colorSpace) { mColorSpace = colorSpace; return this; } public Builder setOrientation(int orientation) { mOrientation = orientation; return this; } public Builder setContentInsets(Rect contentInsets) { mContentInsets = contentInsets; return this; } public Builder setReducedResolution(boolean reducedResolution) { mReducedResolution = reducedResolution; return this; } public float getScaleFraction() { return mScaleFraction; } public Builder setScaleFraction(float scaleFraction) { mScaleFraction = scaleFraction; return this; } public Builder setIsRealSnapshot(boolean realSnapshot) { mIsRealSnapshot = realSnapshot; return this; } public Builder setWindowingMode(int windowingMode) { mWindowingMode = windowingMode; return this; } public Builder setSystemUiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; return this; } public Builder setIsTranslucent(boolean isTranslucent) { mIsTranslucent = isTranslucent; return this; } public int getPixelFormat() { return mPixelFormat; } public Builder setPixelFormat(int pixelFormat) { mPixelFormat = pixelFormat; return this; } public TaskSnapshot build() { return new TaskSnapshot( mId, mTopActivity, mSnapshot, mColorSpace, mOrientation, mContentInsets, mReducedResolution, mScaleFraction, mIsRealSnapshot, mWindowingMode, mSystemUiVisibility, mIsTranslucent); } } } /** @hide */ Loading services/core/java/com/android/server/wm/TaskSnapshotController.java +102 −48 Original line number Diff line number Diff line Loading @@ -89,6 +89,14 @@ class TaskSnapshotController { @VisibleForTesting static final int SNAPSHOT_MODE_NONE = 2; /** * Constant for <code>scaleFactor</code> when calling {@link #snapshotTask} which is * interpreted as using the most appropriate scale ratio for the system. * This may yield a smaller ratio on low memory devices. */ @VisibleForTesting static final float SNAPSHOT_SCALE_AUTO = -1f; private final WindowManagerService mService; private final TaskSnapshotCache mCache; Loading Loading @@ -260,6 +268,84 @@ class TaskSnapshotController { }); } /** * Validates the state of the Task is appropriate to capture a snapshot, collects * information from the task and populates the builder. * * @param task the task to capture * @param scaleFraction the scale fraction between 0-1.0, or {@link #SNAPSHOT_SCALE_AUTO} * to automatically select * @param pixelFormat the desired pixel format, or {@link PixelFormat#UNKNOWN} to * automatically select * @param builder the snapshot builder to populate * * @return true if the state of the task is ok to proceed */ private boolean prepareTaskSnapshot(Task task, float scaleFraction, int pixelFormat, TaskSnapshot.Builder builder) { if (!mService.mPolicy.isScreenOn()) { if (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Attempted to take screenshot while display was off."); } return false; } final ActivityRecord activity = findAppTokenForSnapshot(task); if (activity == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. No visible windows for " + task); } return false; } if (activity.hasCommittedReparentToAnimationLeash()) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity); } return false; } final WindowState mainWindow = activity.findMainWindow(); if (mainWindow == null) { Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task); return false; } builder.setIsRealSnapshot(true); builder.setId(System.currentTimeMillis()); builder.setContentInsets(getInsets(mainWindow)); final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); if (scaleFraction == SNAPSHOT_SCALE_AUTO) { builder.setScaleFraction(isLowRamDevice ? mPersister.getReducedScale() : mFullSnapshotScale); builder.setReducedResolution(isLowRamDevice); } else { builder.setScaleFraction(scaleFraction); builder.setReducedResolution(scaleFraction < 1.0f); } final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE; final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0; if (pixelFormat == PixelFormat.UNKNOWN) { pixelFormat = mPersister.use16BitFormat() && activity.fillsParent() && !(isWindowTranslucent && isShowWallpaper) ? PixelFormat.RGB_565 : PixelFormat.RGBA_8888; } final boolean isTranslucent = PixelFormat.formatHasAlpha(pixelFormat) && (!activity.fillsParent() || isWindowTranslucent); builder.setTopActivityComponent(activity.mActivityComponent); builder.setIsTranslucent(isTranslucent); builder.setOrientation(activity.getTask().getConfiguration().orientation); builder.setWindowingMode(task.getWindowingMode()); builder.setSystemUiVisibility(getSystemUiVisibility(task)); return true; } @Nullable SurfaceControl.ScreenshotGraphicBuffer createTaskSnapshot(@NonNull Task task, float scaleFraction) { Loading Loading @@ -288,63 +374,31 @@ class TaskSnapshotController { return screenshotBuffer; } @Nullable private TaskSnapshot snapshotTask(Task task) { if (!mService.mPolicy.isScreenOn()) { if (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Attempted to take screenshot while display was off."); } return null; } final ActivityRecord activity = findAppTokenForSnapshot(task); if (activity == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. No visible windows for " + task); } return null; } if (activity.hasCommittedReparentToAnimationLeash()) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity); } return null; @Nullable TaskSnapshot snapshotTask(Task task) { return snapshotTask(task, SNAPSHOT_SCALE_AUTO, PixelFormat.UNKNOWN); } final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); final float scaleFraction = isLowRamDevice ? mPersister.getReducedScale() : mFullSnapshotScale; @Nullable TaskSnapshot snapshotTask(Task task, float scaleFraction, int pixelFormat) { TaskSnapshot.Builder builder = new TaskSnapshot.Builder(); final WindowState mainWindow = activity.findMainWindow(); if (mainWindow == null) { Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task); if (!prepareTaskSnapshot(task, scaleFraction, pixelFormat, builder)) { // Failed some pre-req. Has been logged. return null; } final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE; final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0; final int pixelFormat = mPersister.use16BitFormat() && activity.fillsParent() && !(isWindowTranslucent && isShowWallpaper) ? PixelFormat.RGB_565 : PixelFormat.RGBA_8888; final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer = createTaskSnapshot(task, scaleFraction, pixelFormat); createTaskSnapshot(task, builder.getScaleFraction(), builder.getPixelFormat()); if (screenshotBuffer == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot for " + task); } // Failed to acquire image. Has been logged. return null; } final boolean isTranslucent = PixelFormat.formatHasAlpha(pixelFormat) && (!activity.fillsParent() || isWindowTranslucent); return new TaskSnapshot( System.currentTimeMillis() /* id */, activity.mActivityComponent, screenshotBuffer.getGraphicBuffer(), screenshotBuffer.getColorSpace(), activity.getTask().getConfiguration().orientation, getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), isTranslucent); builder.setSnapshot(screenshotBuffer.getGraphicBuffer()); builder.setColorSpace(screenshotBuffer.getColorSpace()); return builder.build(); } private boolean shouldDisableSnapshots() { Loading services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java +65 −0 Original line number Diff line number Diff line Loading @@ -23,9 +23,20 @@ import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THE import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import android.app.ActivityManager; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.res.Configuration; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; import android.view.View; import androidx.test.filters.SmallTest; Loading @@ -33,6 +44,7 @@ import com.google.android.collect.Sets; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; /** * Test class for {@link TaskSnapshotController}. Loading Loading @@ -110,4 +122,57 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { assertEquals(SNAPSHOT_MODE_APP_THEME, mWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask())); } @Test public void testSnapshotBuilder() { final GraphicBuffer buffer = Mockito.mock(GraphicBuffer.class); final ColorSpace sRGB = ColorSpace.get(ColorSpace.Named.SRGB); final long id = 1234L; final ComponentName activityComponent = new ComponentName("package", ".Class"); final int windowingMode = WindowConfiguration.WINDOWING_MODE_FULLSCREEN; final int systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN; final int pixelFormat = PixelFormat.RGBA_8888; final int orientation = Configuration.ORIENTATION_PORTRAIT; final float scaleFraction = 0.25f; final Rect contentInsets = new Rect(1, 2, 3, 4); try { ActivityManager.TaskSnapshot.Builder builder = new ActivityManager.TaskSnapshot.Builder(); builder.setId(id); builder.setTopActivityComponent(activityComponent); builder.setSystemUiVisibility(systemUiVisibility); builder.setWindowingMode(windowingMode); builder.setColorSpace(sRGB); builder.setReducedResolution(true); builder.setOrientation(orientation); builder.setContentInsets(contentInsets); builder.setIsTranslucent(true); builder.setScaleFraction(0.25f); builder.setSnapshot(buffer); builder.setIsRealSnapshot(true); builder.setPixelFormat(pixelFormat); // Not part of TaskSnapshot itself, used in screenshot process assertEquals(pixelFormat, builder.getPixelFormat()); ActivityManager.TaskSnapshot snapshot = builder.build(); assertEquals(id, snapshot.getId()); assertEquals(activityComponent, snapshot.getTopActivityComponent()); assertEquals(systemUiVisibility, snapshot.getSystemUiVisibility()); assertEquals(windowingMode, snapshot.getWindowingMode()); assertEquals(sRGB, snapshot.getColorSpace()); assertTrue(snapshot.isReducedResolution()); assertEquals(orientation, snapshot.getOrientation()); assertEquals(contentInsets, snapshot.getContentInsets()); assertTrue(snapshot.isTranslucent()); assertEquals(scaleFraction, builder.getScaleFraction(), 0.001f); assertSame(buffer, snapshot.getSnapshot()); assertTrue(snapshot.isRealSnapshot()); } finally { if (buffer != null) { buffer.destroy(); } } } } Loading
core/java/android/app/ActivityManager.java +107 −0 Original line number Diff line number Diff line Loading @@ -2097,6 +2097,113 @@ public class ActivityManager { return new TaskSnapshot[size]; } }; /** Builder for a {@link TaskSnapshot} object */ public static final class Builder { private long mId; private ComponentName mTopActivity; private GraphicBuffer mSnapshot; private ColorSpace mColorSpace; private int mOrientation; private Rect mContentInsets; private boolean mReducedResolution; private float mScaleFraction; private boolean mIsRealSnapshot; private int mWindowingMode; private int mSystemUiVisibility; private boolean mIsTranslucent; private int mPixelFormat; public Builder setId(long id) { mId = id; return this; } public Builder setTopActivityComponent(ComponentName name) { mTopActivity = name; return this; } public Builder setSnapshot(GraphicBuffer buffer) { mSnapshot = buffer; return this; } public Builder setColorSpace(ColorSpace colorSpace) { mColorSpace = colorSpace; return this; } public Builder setOrientation(int orientation) { mOrientation = orientation; return this; } public Builder setContentInsets(Rect contentInsets) { mContentInsets = contentInsets; return this; } public Builder setReducedResolution(boolean reducedResolution) { mReducedResolution = reducedResolution; return this; } public float getScaleFraction() { return mScaleFraction; } public Builder setScaleFraction(float scaleFraction) { mScaleFraction = scaleFraction; return this; } public Builder setIsRealSnapshot(boolean realSnapshot) { mIsRealSnapshot = realSnapshot; return this; } public Builder setWindowingMode(int windowingMode) { mWindowingMode = windowingMode; return this; } public Builder setSystemUiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; return this; } public Builder setIsTranslucent(boolean isTranslucent) { mIsTranslucent = isTranslucent; return this; } public int getPixelFormat() { return mPixelFormat; } public Builder setPixelFormat(int pixelFormat) { mPixelFormat = pixelFormat; return this; } public TaskSnapshot build() { return new TaskSnapshot( mId, mTopActivity, mSnapshot, mColorSpace, mOrientation, mContentInsets, mReducedResolution, mScaleFraction, mIsRealSnapshot, mWindowingMode, mSystemUiVisibility, mIsTranslucent); } } } /** @hide */ Loading
services/core/java/com/android/server/wm/TaskSnapshotController.java +102 −48 Original line number Diff line number Diff line Loading @@ -89,6 +89,14 @@ class TaskSnapshotController { @VisibleForTesting static final int SNAPSHOT_MODE_NONE = 2; /** * Constant for <code>scaleFactor</code> when calling {@link #snapshotTask} which is * interpreted as using the most appropriate scale ratio for the system. * This may yield a smaller ratio on low memory devices. */ @VisibleForTesting static final float SNAPSHOT_SCALE_AUTO = -1f; private final WindowManagerService mService; private final TaskSnapshotCache mCache; Loading Loading @@ -260,6 +268,84 @@ class TaskSnapshotController { }); } /** * Validates the state of the Task is appropriate to capture a snapshot, collects * information from the task and populates the builder. * * @param task the task to capture * @param scaleFraction the scale fraction between 0-1.0, or {@link #SNAPSHOT_SCALE_AUTO} * to automatically select * @param pixelFormat the desired pixel format, or {@link PixelFormat#UNKNOWN} to * automatically select * @param builder the snapshot builder to populate * * @return true if the state of the task is ok to proceed */ private boolean prepareTaskSnapshot(Task task, float scaleFraction, int pixelFormat, TaskSnapshot.Builder builder) { if (!mService.mPolicy.isScreenOn()) { if (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Attempted to take screenshot while display was off."); } return false; } final ActivityRecord activity = findAppTokenForSnapshot(task); if (activity == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. No visible windows for " + task); } return false; } if (activity.hasCommittedReparentToAnimationLeash()) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity); } return false; } final WindowState mainWindow = activity.findMainWindow(); if (mainWindow == null) { Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task); return false; } builder.setIsRealSnapshot(true); builder.setId(System.currentTimeMillis()); builder.setContentInsets(getInsets(mainWindow)); final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); if (scaleFraction == SNAPSHOT_SCALE_AUTO) { builder.setScaleFraction(isLowRamDevice ? mPersister.getReducedScale() : mFullSnapshotScale); builder.setReducedResolution(isLowRamDevice); } else { builder.setScaleFraction(scaleFraction); builder.setReducedResolution(scaleFraction < 1.0f); } final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE; final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0; if (pixelFormat == PixelFormat.UNKNOWN) { pixelFormat = mPersister.use16BitFormat() && activity.fillsParent() && !(isWindowTranslucent && isShowWallpaper) ? PixelFormat.RGB_565 : PixelFormat.RGBA_8888; } final boolean isTranslucent = PixelFormat.formatHasAlpha(pixelFormat) && (!activity.fillsParent() || isWindowTranslucent); builder.setTopActivityComponent(activity.mActivityComponent); builder.setIsTranslucent(isTranslucent); builder.setOrientation(activity.getTask().getConfiguration().orientation); builder.setWindowingMode(task.getWindowingMode()); builder.setSystemUiVisibility(getSystemUiVisibility(task)); return true; } @Nullable SurfaceControl.ScreenshotGraphicBuffer createTaskSnapshot(@NonNull Task task, float scaleFraction) { Loading Loading @@ -288,63 +374,31 @@ class TaskSnapshotController { return screenshotBuffer; } @Nullable private TaskSnapshot snapshotTask(Task task) { if (!mService.mPolicy.isScreenOn()) { if (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Attempted to take screenshot while display was off."); } return null; } final ActivityRecord activity = findAppTokenForSnapshot(task); if (activity == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. No visible windows for " + task); } return null; } if (activity.hasCommittedReparentToAnimationLeash()) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity); } return null; @Nullable TaskSnapshot snapshotTask(Task task) { return snapshotTask(task, SNAPSHOT_SCALE_AUTO, PixelFormat.UNKNOWN); } final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); final float scaleFraction = isLowRamDevice ? mPersister.getReducedScale() : mFullSnapshotScale; @Nullable TaskSnapshot snapshotTask(Task task, float scaleFraction, int pixelFormat) { TaskSnapshot.Builder builder = new TaskSnapshot.Builder(); final WindowState mainWindow = activity.findMainWindow(); if (mainWindow == null) { Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task); if (!prepareTaskSnapshot(task, scaleFraction, pixelFormat, builder)) { // Failed some pre-req. Has been logged. return null; } final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE; final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0; final int pixelFormat = mPersister.use16BitFormat() && activity.fillsParent() && !(isWindowTranslucent && isShowWallpaper) ? PixelFormat.RGB_565 : PixelFormat.RGBA_8888; final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer = createTaskSnapshot(task, scaleFraction, pixelFormat); createTaskSnapshot(task, builder.getScaleFraction(), builder.getPixelFormat()); if (screenshotBuffer == null) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot for " + task); } // Failed to acquire image. Has been logged. return null; } final boolean isTranslucent = PixelFormat.formatHasAlpha(pixelFormat) && (!activity.fillsParent() || isWindowTranslucent); return new TaskSnapshot( System.currentTimeMillis() /* id */, activity.mActivityComponent, screenshotBuffer.getGraphicBuffer(), screenshotBuffer.getColorSpace(), activity.getTask().getConfiguration().orientation, getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), isTranslucent); builder.setSnapshot(screenshotBuffer.getGraphicBuffer()); builder.setColorSpace(screenshotBuffer.getColorSpace()); return builder.build(); } private boolean shouldDisableSnapshots() { Loading
services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java +65 −0 Original line number Diff line number Diff line Loading @@ -23,9 +23,20 @@ import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THE import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import android.app.ActivityManager; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.res.Configuration; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; import android.view.View; import androidx.test.filters.SmallTest; Loading @@ -33,6 +44,7 @@ import com.google.android.collect.Sets; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; /** * Test class for {@link TaskSnapshotController}. Loading Loading @@ -110,4 +122,57 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { assertEquals(SNAPSHOT_MODE_APP_THEME, mWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask())); } @Test public void testSnapshotBuilder() { final GraphicBuffer buffer = Mockito.mock(GraphicBuffer.class); final ColorSpace sRGB = ColorSpace.get(ColorSpace.Named.SRGB); final long id = 1234L; final ComponentName activityComponent = new ComponentName("package", ".Class"); final int windowingMode = WindowConfiguration.WINDOWING_MODE_FULLSCREEN; final int systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN; final int pixelFormat = PixelFormat.RGBA_8888; final int orientation = Configuration.ORIENTATION_PORTRAIT; final float scaleFraction = 0.25f; final Rect contentInsets = new Rect(1, 2, 3, 4); try { ActivityManager.TaskSnapshot.Builder builder = new ActivityManager.TaskSnapshot.Builder(); builder.setId(id); builder.setTopActivityComponent(activityComponent); builder.setSystemUiVisibility(systemUiVisibility); builder.setWindowingMode(windowingMode); builder.setColorSpace(sRGB); builder.setReducedResolution(true); builder.setOrientation(orientation); builder.setContentInsets(contentInsets); builder.setIsTranslucent(true); builder.setScaleFraction(0.25f); builder.setSnapshot(buffer); builder.setIsRealSnapshot(true); builder.setPixelFormat(pixelFormat); // Not part of TaskSnapshot itself, used in screenshot process assertEquals(pixelFormat, builder.getPixelFormat()); ActivityManager.TaskSnapshot snapshot = builder.build(); assertEquals(id, snapshot.getId()); assertEquals(activityComponent, snapshot.getTopActivityComponent()); assertEquals(systemUiVisibility, snapshot.getSystemUiVisibility()); assertEquals(windowingMode, snapshot.getWindowingMode()); assertEquals(sRGB, snapshot.getColorSpace()); assertTrue(snapshot.isReducedResolution()); assertEquals(orientation, snapshot.getOrientation()); assertEquals(contentInsets, snapshot.getContentInsets()); assertTrue(snapshot.isTranslucent()); assertEquals(scaleFraction, builder.getScaleFraction(), 0.001f); assertSame(buffer, snapshot.getSnapshot()); assertTrue(snapshot.isRealSnapshot()); } finally { if (buffer != null) { buffer.destroy(); } } } }