Loading services/core/java/com/android/server/wm/TaskSnapshotSurface.java +32 −14 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATIO import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES; Loading Loading @@ -129,6 +130,7 @@ class TaskSnapshotSurface implements StartingSurface { private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; private final WindowManagerService mService; private final int mDisplayId; private final Rect mTaskBounds; private final Rect mFrame = new Rect(); private final Rect mSystemBarInsets = new Rect(); Loading @@ -151,10 +153,15 @@ class TaskSnapshotSurface implements StartingSurface { static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity, TaskSnapshot snapshot) { return create(service, activity, snapshot, WindowManagerGlobal.getWindowSession()); } @VisibleForTesting static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity, TaskSnapshot snapshot, IWindowSession session) { final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); final Window window = new Window(); final IWindowSession session = WindowManagerGlobal.getWindowSession(); window.setSession(session); final SurfaceControl surfaceControl = new SurfaceControl(); final ClientWindowFrames tmpFrames = new ClientWindowFrames(); Loading Loading @@ -215,7 +222,10 @@ class TaskSnapshotSurface implements StartingSurface { layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES) | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE; layoutParams.privateFlags = windowPrivateFlags & PRIVATE_FLAG_INHERITS; // Setting as trusted overlay to let touches pass through. This is safe because this // window is controlled by the system. layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_INHERITS) | PRIVATE_FLAG_TRUSTED_OVERLAY; layoutParams.token = activity.token; layoutParams.width = LayoutParams.MATCH_PARENT; layoutParams.height = LayoutParams.MATCH_PARENT; Loading @@ -239,11 +249,11 @@ class TaskSnapshotSurface implements StartingSurface { insetsState = getInsetsStateWithVisibilityOverride(topFullscreenOpaqueWindow); } int displayId = activity.getDisplayContent().getDisplayId(); try { final int res = session.addToDisplay(window, layoutParams, View.GONE, activity.getDisplayContent().getDisplayId(), mTmpInsetsState, tmpFrames.frame, tmpFrames.displayCutout, null /* outInputChannel */, mTmpInsetsState, mTempControls); View.GONE, displayId, mTmpInsetsState, tmpFrames.frame, tmpFrames.displayCutout, null /* outInputChannel */, mTmpInsetsState, mTempControls); if (res < 0) { Slog.w(TAG, "Failed to add snapshot starting window res=" + res); return null; Loading @@ -251,10 +261,10 @@ class TaskSnapshotSurface implements StartingSurface { } catch (RemoteException e) { // Local call. } final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType, insetsState); final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, displayId, window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType, insetsState); window.setOuter(snapshotSurface); try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, Loading @@ -271,11 +281,13 @@ class TaskSnapshotSurface implements StartingSurface { } @VisibleForTesting TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState insetsState) { TaskSnapshotSurface(WindowManagerService service, int displayId, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState insetsState) { mService = service; mDisplayId = displayId; mSurface = service.mSurfaceFactory.get(); mHandler = new Handler(mService.mH.getLooper()); mSession = WindowManagerGlobal.getWindowSession(); Loading Loading @@ -368,8 +380,9 @@ class TaskSnapshotSurface implements StartingSurface { - ((float) mFrame.width() / mFrame.height())) > 0.01f; // Keep a reference to it such that it doesn't get destroyed when finalized. final String name = mTitle + " - task-snapshot-surface"; mChildSurfaceControl = mService.mSurfaceControlFactory.apply(session) .setName(mTitle + " - task-snapshot-surface") .setName(name) .setBufferSize(buffer.getWidth(), buffer.getHeight()) .setFormat(buffer.getFormat()) .setParent(mSurfaceControl) Loading Loading @@ -401,6 +414,11 @@ class TaskSnapshotSurface implements StartingSurface { mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL); mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9); // This is the way to tell the input system to exclude this surface from occlusion // detection since we don't have a window for it. We do this because this window is // generated by the system as well as its content (the snapshot of the app). InputMonitor.setTrustedOverlayInputInfo(mChildSurfaceControl, mTransaction, mDisplayId, name); mTransaction.apply(); surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace()); surface.release(); Loading services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +7 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import org.mockito.quality.Strictness; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; /** * JUnit test rule to correctly setting up system services like {@link WindowManagerService} Loading @@ -112,6 +113,7 @@ public class SystemServicesTestRule implements TestRule { private WindowState.PowerManagerWrapper mPowerManagerWrapper; private InputManagerService mImService; private InputChannel mInputChannel; private Supplier<Surface> mSurfaceFactory = () -> mock(Surface.class); /** * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. */ Loading Loading @@ -286,7 +288,7 @@ public class SystemServicesTestRule implements TestRule { DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); mWmService = WindowManagerService.main( mContext, mImService, false, false, mWMPolicy, mAtmService, StubTransaction::new, () -> mock(Surface.class), (unused) -> new MockSurfaceControlBuilder()); () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder()); spyOn(mWmService); spyOn(mWmService.mRoot); // Invoked during {@link ActivityStack} creation. Loading Loading @@ -396,6 +398,10 @@ public class SystemServicesTestRule implements TestRule { return mPowerManagerWrapper; } void setSurfaceFactory(Supplier<Surface> factory) { mSurfaceFactory = factory; } void cleanupWindowManagerHandlers() { final WindowManagerService wm = getWindowManagerService(); if (wm == null) { Loading services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +51 −7 Original line number Diff line number Diff line Loading @@ -20,17 +20,23 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import android.app.ActivityManager; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskSnapshot; import android.content.ComponentName; Loading @@ -41,14 +47,18 @@ import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.platform.test.annotations.Presubmit; import android.view.Display; import android.view.IWindowSession; import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.server.wm.TaskSnapshotSurface.Window; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -67,9 +77,6 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { private void setupSurface(int width, int height, Rect contentInsets, int sysuiVis, int windowFlags, Rect taskBounds) { final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_READ_RARELY); // Previously when constructing TaskSnapshots for this test, scale was 1.0f, so to mimic // this behavior set the taskSize to be the same as the taskBounds width and height. The // taskBounds passed here are assumed to be the same task bounds as when the snapshot was Loading @@ -79,16 +86,24 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { assertEquals(height, taskBounds.height()); Point taskSize = new Point(taskBounds.width(), taskBounds.height()); final TaskSnapshot snapshot = new TaskSnapshot( final TaskSnapshot snapshot = createTaskSnapshot(width, height, taskSize, contentInsets); mSurface = new TaskSnapshotSurface(mWm, Display.DEFAULT_DISPLAY, new Window(), new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState()); } private ActivityManager.TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, Rect contentInsets) { final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_READ_RARELY); return new TaskSnapshot( System.currentTimeMillis(), new ComponentName("", ""), buffer, ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, Surface.ROTATION_0, taskSize, contentInsets, false, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */); mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState()); } private static TaskDescription createTaskDescription(int background, int statusBar, Loading @@ -105,6 +120,35 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { new Rect(0, 0, width, height)); } private boolean isTrustedOverlay(WindowManager.LayoutParams params) { return (params.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0; } @Before public void setUp() throws Exception { mSystemServicesTestRule.setSurfaceFactory(() -> { Surface surface = mock(Surface.class); when(surface.isValid()).thenReturn(true); return surface; }); } @Test public void createSurface_asTrustedOverlay() throws Exception { Point task = new Point(200, 100); ActivityRecord activityRecord = createActivityRecord(mDisplayContent); createWindow(null, TYPE_BASE_APPLICATION, activityRecord, "window"); TaskSnapshot taskSnapshot = createTaskSnapshot(task.x, task.y, task, new Rect()); IWindowSession session = mock(IWindowSession.class); TaskSnapshotSurface surface = TaskSnapshotSurface.create(mWm, activityRecord, taskSnapshot, session); assertThat(surface).isNotNull(); verify(session).addToDisplay(any(), argThat(this::isTrustedOverlay), anyInt(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test public void fillEmptyBackground_fillHorizontally() { setupSurface(200, 100); Loading Loading
services/core/java/com/android/server/wm/TaskSnapshotSurface.java +32 −14 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATIO import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES; Loading Loading @@ -129,6 +130,7 @@ class TaskSnapshotSurface implements StartingSurface { private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; private final WindowManagerService mService; private final int mDisplayId; private final Rect mTaskBounds; private final Rect mFrame = new Rect(); private final Rect mSystemBarInsets = new Rect(); Loading @@ -151,10 +153,15 @@ class TaskSnapshotSurface implements StartingSurface { static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity, TaskSnapshot snapshot) { return create(service, activity, snapshot, WindowManagerGlobal.getWindowSession()); } @VisibleForTesting static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity, TaskSnapshot snapshot, IWindowSession session) { final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); final Window window = new Window(); final IWindowSession session = WindowManagerGlobal.getWindowSession(); window.setSession(session); final SurfaceControl surfaceControl = new SurfaceControl(); final ClientWindowFrames tmpFrames = new ClientWindowFrames(); Loading Loading @@ -215,7 +222,10 @@ class TaskSnapshotSurface implements StartingSurface { layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES) | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE; layoutParams.privateFlags = windowPrivateFlags & PRIVATE_FLAG_INHERITS; // Setting as trusted overlay to let touches pass through. This is safe because this // window is controlled by the system. layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_INHERITS) | PRIVATE_FLAG_TRUSTED_OVERLAY; layoutParams.token = activity.token; layoutParams.width = LayoutParams.MATCH_PARENT; layoutParams.height = LayoutParams.MATCH_PARENT; Loading @@ -239,11 +249,11 @@ class TaskSnapshotSurface implements StartingSurface { insetsState = getInsetsStateWithVisibilityOverride(topFullscreenOpaqueWindow); } int displayId = activity.getDisplayContent().getDisplayId(); try { final int res = session.addToDisplay(window, layoutParams, View.GONE, activity.getDisplayContent().getDisplayId(), mTmpInsetsState, tmpFrames.frame, tmpFrames.displayCutout, null /* outInputChannel */, mTmpInsetsState, mTempControls); View.GONE, displayId, mTmpInsetsState, tmpFrames.frame, tmpFrames.displayCutout, null /* outInputChannel */, mTmpInsetsState, mTempControls); if (res < 0) { Slog.w(TAG, "Failed to add snapshot starting window res=" + res); return null; Loading @@ -251,10 +261,10 @@ class TaskSnapshotSurface implements StartingSurface { } catch (RemoteException e) { // Local call. } final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType, insetsState); final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, displayId, window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType, insetsState); window.setOuter(snapshotSurface); try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, Loading @@ -271,11 +281,13 @@ class TaskSnapshotSurface implements StartingSurface { } @VisibleForTesting TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState insetsState) { TaskSnapshotSurface(WindowManagerService service, int displayId, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState insetsState) { mService = service; mDisplayId = displayId; mSurface = service.mSurfaceFactory.get(); mHandler = new Handler(mService.mH.getLooper()); mSession = WindowManagerGlobal.getWindowSession(); Loading Loading @@ -368,8 +380,9 @@ class TaskSnapshotSurface implements StartingSurface { - ((float) mFrame.width() / mFrame.height())) > 0.01f; // Keep a reference to it such that it doesn't get destroyed when finalized. final String name = mTitle + " - task-snapshot-surface"; mChildSurfaceControl = mService.mSurfaceControlFactory.apply(session) .setName(mTitle + " - task-snapshot-surface") .setName(name) .setBufferSize(buffer.getWidth(), buffer.getHeight()) .setFormat(buffer.getFormat()) .setParent(mSurfaceControl) Loading Loading @@ -401,6 +414,11 @@ class TaskSnapshotSurface implements StartingSurface { mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL); mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9); // This is the way to tell the input system to exclude this surface from occlusion // detection since we don't have a window for it. We do this because this window is // generated by the system as well as its content (the snapshot of the app). InputMonitor.setTrustedOverlayInputInfo(mChildSurfaceControl, mTransaction, mDisplayId, name); mTransaction.apply(); surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace()); surface.release(); Loading
services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +7 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import org.mockito.quality.Strictness; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; /** * JUnit test rule to correctly setting up system services like {@link WindowManagerService} Loading @@ -112,6 +113,7 @@ public class SystemServicesTestRule implements TestRule { private WindowState.PowerManagerWrapper mPowerManagerWrapper; private InputManagerService mImService; private InputChannel mInputChannel; private Supplier<Surface> mSurfaceFactory = () -> mock(Surface.class); /** * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. */ Loading Loading @@ -286,7 +288,7 @@ public class SystemServicesTestRule implements TestRule { DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); mWmService = WindowManagerService.main( mContext, mImService, false, false, mWMPolicy, mAtmService, StubTransaction::new, () -> mock(Surface.class), (unused) -> new MockSurfaceControlBuilder()); () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder()); spyOn(mWmService); spyOn(mWmService.mRoot); // Invoked during {@link ActivityStack} creation. Loading Loading @@ -396,6 +398,10 @@ public class SystemServicesTestRule implements TestRule { return mPowerManagerWrapper; } void setSurfaceFactory(Supplier<Surface> factory) { mSurfaceFactory = factory; } void cleanupWindowManagerHandlers() { final WindowManagerService wm = getWindowManagerService(); if (wm == null) { Loading
services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +51 −7 Original line number Diff line number Diff line Loading @@ -20,17 +20,23 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import android.app.ActivityManager; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskSnapshot; import android.content.ComponentName; Loading @@ -41,14 +47,18 @@ import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.platform.test.annotations.Presubmit; import android.view.Display; import android.view.IWindowSession; import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.server.wm.TaskSnapshotSurface.Window; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -67,9 +77,6 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { private void setupSurface(int width, int height, Rect contentInsets, int sysuiVis, int windowFlags, Rect taskBounds) { final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_READ_RARELY); // Previously when constructing TaskSnapshots for this test, scale was 1.0f, so to mimic // this behavior set the taskSize to be the same as the taskBounds width and height. The // taskBounds passed here are assumed to be the same task bounds as when the snapshot was Loading @@ -79,16 +86,24 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { assertEquals(height, taskBounds.height()); Point taskSize = new Point(taskBounds.width(), taskBounds.height()); final TaskSnapshot snapshot = new TaskSnapshot( final TaskSnapshot snapshot = createTaskSnapshot(width, height, taskSize, contentInsets); mSurface = new TaskSnapshotSurface(mWm, Display.DEFAULT_DISPLAY, new Window(), new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState()); } private ActivityManager.TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, Rect contentInsets) { final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_READ_RARELY); return new TaskSnapshot( System.currentTimeMillis(), new ComponentName("", ""), buffer, ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, Surface.ROTATION_0, taskSize, contentInsets, false, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */); mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState()); } private static TaskDescription createTaskDescription(int background, int statusBar, Loading @@ -105,6 +120,35 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { new Rect(0, 0, width, height)); } private boolean isTrustedOverlay(WindowManager.LayoutParams params) { return (params.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0; } @Before public void setUp() throws Exception { mSystemServicesTestRule.setSurfaceFactory(() -> { Surface surface = mock(Surface.class); when(surface.isValid()).thenReturn(true); return surface; }); } @Test public void createSurface_asTrustedOverlay() throws Exception { Point task = new Point(200, 100); ActivityRecord activityRecord = createActivityRecord(mDisplayContent); createWindow(null, TYPE_BASE_APPLICATION, activityRecord, "window"); TaskSnapshot taskSnapshot = createTaskSnapshot(task.x, task.y, task, new Rect()); IWindowSession session = mock(IWindowSession.class); TaskSnapshotSurface surface = TaskSnapshotSurface.create(mWm, activityRecord, taskSnapshot, session); assertThat(surface).isNotNull(); verify(session).addToDisplay(any(), argThat(this::isTrustedOverlay), anyInt(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test public void fillEmptyBackground_fillHorizontally() { setupSurface(200, 100); Loading