Loading services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -453,6 +453,78 @@ public class ContentRecorderTests extends WindowTestsBase { displayAreaBounds.width(), displayAreaBounds.height()); displayAreaBounds.width(), displayAreaBounds.height()); } } @Test public void testDisplayContentUpdatesRecording_withoutSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // WHEN getting the DisplayContent for the new virtual display without providing a valid // size from getDisplaySurfaceDefaultSize, i.e. the case of null surface. final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); doReturn(null).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(anyInt()); mWm.mContentRecordingController.setContentRecordingSessionLocked(mDisplaySession, mWm); virtualDisplay.updateRecording(); // THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off. assertThat(virtualDisplay.isCurrentlyRecording()).isFalse(); } @Test public void testDisplayContentUpdatesRecording_withSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // WHEN getting the DisplayContent for the virtual display with a valid size from // getDisplaySurfaceDefaultSize (done by surfaceControlMirrors in setUp). final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); mWm.mContentRecordingController.setContentRecordingSessionLocked(mDisplaySession, mWm); virtualDisplay.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. assertThat(virtualDisplay.isCurrentlyRecording()).isTrue(); } @Test public void testDisplayContentUpdatesRecording_displayMirroring() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. surfaceControlMirrors(sSurfaceSize); // Initially disable getDisplayIdToMirror since the DMS may create the DC outside the direct // call in the test. We need to spy on the DC before updateRecording is called or we can't // verify setDisplayMirroring is called doReturn(INVALID_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); // WHEN getting the DisplayContent for the new virtual display. final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); // Return the default display as the value to mirror to ensure the VD with flag mirroring // creates a ContentRecordingSession automatically. doReturn(DEFAULT_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); virtualDisplay.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. verify(virtualDisplay).setDisplayMirroring(); assertThat(virtualDisplay.isCurrentlyRecording()).isTrue(); } /** * Creates a WindowToken associated with the default task DisplayArea, in order for that * DisplayArea to be mirrored. */ private void setUpDefaultTaskDisplayAreaWindowToken() { // GIVEN the default task display area is represented by the WindowToken. spyOn(mWm.mWindowContextListenerController); doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when( mWm.mWindowContextListenerController).getContainer(any()); } /** /** * Creates a {@link android.window.WindowContainerToken} associated with a task, in order for * Creates a {@link android.window.WindowContainerToken} associated with a task, in order for * that task to be recorded. * that task to be recorded. Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +0 −137 Original line number Original line Diff line number Diff line Loading @@ -27,12 +27,10 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; import static android.os.Build.VERSION_CODES.P; import static android.os.Build.VERSION_CODES.P; import static android.os.Build.VERSION_CODES.Q; import static android.os.Build.VERSION_CODES.Q; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.INVALID_DISPLAY; import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; import static android.view.DisplayCutout.fromBoundingRect; import static android.view.DisplayCutout.fromBoundingRect; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_0; Loading Loading @@ -112,11 +110,9 @@ import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.HardwareBuffer; import android.hardware.display.VirtualDisplay; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.os.Binder; import android.os.Binder; import android.os.RemoteException; import android.os.RemoteException; Loading @@ -124,7 +120,6 @@ import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.DisplayMetrics; import android.view.ContentRecordingSession; import android.view.Display; import android.view.Display; import android.view.DisplayCutout; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.DisplayInfo; Loading Loading @@ -2654,138 +2649,6 @@ public class DisplayContentTests extends WindowTestsBase { assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); } } @Test public void testVirtualDisplayContent_withoutSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl does not mirror a null surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, null /* surface */); final int displayId = display.getDisplay().getDisplayId(); mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); ContentRecordingSession session = ContentRecordingSession.createDisplaySession( DEFAULT_DISPLAY); session.setVirtualDisplayId(displayId); mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm); actualDC.updateRecording(); // THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off. assertThat(actualDC.isCurrentlyRecording()).isFalse(); display.release(); } @Test public void testVirtualDisplayContent_withSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); surfaceControlMirrors(surfaceSize); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, new Surface()); final int displayId = display.getDisplay().getDisplayId(); // GIVEN a session for this display. ContentRecordingSession session = ContentRecordingSession.createDisplaySession( DEFAULT_DISPLAY); session.setVirtualDisplayId(displayId); mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm); mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); actualDC.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. assertThat(actualDC.isCurrentlyRecording()).isTrue(); display.release(); } @Test public void testVirtualDisplayContent_displayMirroring() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); surfaceControlMirrors(surfaceSize); // Initially disable getDisplayIdToMirror since the DMS may create the DC outside the direct // call in the test. We need to spy on the DC before updateRecording is called or we can't // verify setDisplayMirroring is called doReturn(INVALID_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, new Surface()); final int displayId = display.getDisplay().getDisplayId(); // GIVEN a session for this display. mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); spyOn(actualDC); // Return the default display as the value to mirror to ensure the VD with flag mirroring // creates a ContentRecordingSession automatically. doReturn(DEFAULT_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); actualDC.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. verify(actualDC).setDisplayMirroring(); assertThat(actualDC.isCurrentlyRecording()).isTrue(); display.release(); } /** * Creates a WindowToken associated with the default task DisplayArea, in order for that * DisplayArea to be mirrored. */ private void setUpDefaultTaskDisplayAreaWindowToken() { // GIVEN the default task display area is represented by the WindowToken. spyOn(mWm.mWindowContextListenerController); doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when( mWm.mWindowContextListenerController).getContainer(any()); } /** * SurfaceControl successfully creates a mirrored surface of the given size. */ private SurfaceControl surfaceControlMirrors(Point surfaceSize) { // Do not set the parent, since the mirrored surface is the root of a new surface hierarchy. SurfaceControl mirroredSurface = new SurfaceControl.Builder() .setName("mirroredSurface") .setBufferSize(surfaceSize.x, surfaceSize.y) .setCallsite("mirrorSurface") .build(); doReturn(mirroredSurface).when(() -> SurfaceControl.mirrorSurface(any())); doReturn(surfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize( anyInt()); return mirroredSurface; } private VirtualDisplay createVirtualDisplay(Point size, Surface surface) { return mWm.mDisplayManager.createVirtualDisplay("VirtualDisplay", size.x, size.y, DisplayMetrics.DENSITY_140, surface, VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR); } @Test @Test public void testKeepClearAreasMultipleWindows() { public void testKeepClearAreasMultipleWindows() { final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1"); final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1"); Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +42 −80 Original line number Original line Diff line number Diff line Loading @@ -21,9 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY; Loading Loading @@ -63,6 +60,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.description; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify; Loading @@ -71,9 +70,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityThread; import android.app.ActivityThread; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.hardware.display.VirtualDisplay; import android.os.Binder; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.IBinder; import android.os.IBinder; Loading @@ -82,7 +79,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.util.MergedConfiguration; import android.util.MergedConfiguration; import android.view.ContentRecordingSession; import android.view.ContentRecordingSession; import android.view.IWindow; import android.view.IWindow; Loading @@ -90,7 +86,6 @@ import android.view.IWindowSessionCallback; import android.view.InputChannel; import android.view.InputChannel; import android.view.InsetsSourceControl; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl; import android.view.View; import android.view.View; import android.view.WindowInsets; import android.view.WindowInsets; Loading Loading @@ -575,13 +570,14 @@ public class WindowManagerServiceTests extends WindowTestsBase { mWm.mPerDisplayFocusEnabled = false; mWm.mPerDisplayFocusEnabled = false; // Create one extra display // Create one extra display final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent display = createMockSimulatedDisplay(); final VirtualDisplay virtualDisplayOwnTouchMode = display.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; createVirtualDisplay(/* ownFocus= */ true); final DisplayContent displayOwnTouchMode = createMockSimulatedDisplay(); displayOwnTouchMode.getDisplayInfo().flags |= FLAG_OWN_FOCUS; final int numberOfDisplays = mWm.mRoot.mChildren.size(); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(3); assertThat(numberOfDisplays).isAtLeast(3); final int numberOfGlobalTouchModeDisplays = (int) mWm.mRoot.mChildren.stream() final int numberOfGlobalTouchModeDisplays = (int) mWm.mRoot.mChildren.stream() .filter(d -> (d.getDisplay().getFlags() & FLAG_OWN_FOCUS) == 0) .filter(d -> (d.getDisplayInfo().flags & FLAG_OWN_FOCUS) == 0) .count(); .count(); assertThat(numberOfGlobalTouchModeDisplays).isAtLeast(2); assertThat(numberOfGlobalTouchModeDisplays).isAtLeast(2); Loading @@ -601,12 +597,13 @@ public class WindowManagerServiceTests extends WindowTestsBase { } } @Test @Test public void testSetInTouchMode_multiDisplay_perDisplayFocus_singleDisplayTouchModeUpdate() { public void testSetInTouchMode_multiDisplay_singleDisplayTouchModeUpdate() { // Enable global touch mode // Enable global touch mode mWm.mPerDisplayFocusEnabled = true; mWm.mPerDisplayFocusEnabled = true; // Create one extra display // Create one extra display final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent virtualDisplay = createMockSimulatedDisplay(); virtualDisplay.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; final int numberOfDisplays = mWm.mRoot.mChildren.size(); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(2); assertThat(numberOfDisplays).isAtLeast(2); Loading @@ -618,99 +615,64 @@ public class WindowManagerServiceTests extends WindowTestsBase { when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.getDisplay().getDisplayId()); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.mDisplayId); // Ensure that new display touch mode state has changed. // Ensure that new display touch mode state has changed. verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager).setInTouchMode( !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, virtualDisplay.getDisplay().getDisplayId()); virtualDisplay.mDisplayId); } @Test // Disable global touch mode and make the virtual display own focus. public void testSetInTouchMode_multiDisplay_ownTouchMode_singleDisplayTouchModeUpdate() { // Disable global touch mode mWm.mPerDisplayFocusEnabled = false; mWm.mPerDisplayFocusEnabled = false; virtualDisplay.getDisplayInfo().flags |= FLAG_OWN_FOCUS; // Create one extra display clearInvocations(mWm.mInputManager); final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.mDisplayId); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(2); // Get current touch mode state and setup WMS to run setInTouchMode boolean currentTouchMode = mWm.isInTouchMode(DEFAULT_DISPLAY); int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.getDisplay().getDisplayId()); // Ensure that new display touch mode state has changed. // Ensure that new display touch mode state has changed. verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager).setInTouchMode( !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, virtualDisplay.getDisplay().getDisplayId()); virtualDisplay.mDisplayId); } } @Test @Test public void testSetInTouchModeOnAllDisplays_perDisplayFocusDisabled() { public void testSetInTouchModeOnAllDisplays() { testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ false); } @Test public void testSetInTouchModeOnAllDisplays_perDisplayFocusEnabled() { testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ true); } private void testSetInTouchModeOnAllDisplays(boolean perDisplayFocusEnabled) { // Set global touch mode with the value passed as argument. mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled; // Create a couple of extra displays. // Create a couple of extra displays. // setInTouchModeOnAllDisplays should ignore the ownFocus setting. // setInTouchModeOnAllDisplays should ignore the ownFocus setting. final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent display = createMockSimulatedDisplay(); final VirtualDisplay virtualDisplayOwnFocus = createVirtualDisplay(/* ownFocus= */ true); display.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; final DisplayContent displayOwnTouchMode = createMockSimulatedDisplay(); displayOwnTouchMode.getDisplayInfo().flags |= FLAG_OWN_FOCUS; int callingPid = Binder.getCallingPid(); int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid(); doReturn(true).when(mWm.mInputManager).setInTouchMode(anyBoolean(), anyInt(), anyInt(), anyBoolean(), anyInt()); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); final Runnable verification = () -> { for (boolean inTouchMode : new boolean[] { true, false }) { for (boolean inTouchMode : new boolean[] { true, false }) { mWm.setInTouchModeOnAllDisplays(inTouchMode); mWm.setInTouchModeOnAllDisplays(inTouchMode); for (int i = 0; i < mWm.mRoot.mChildren.size(); ++i) { for (int i = 0; i < mRootWindowContainer.getChildCount(); ++i) { DisplayContent dc = mWm.mRoot.mChildren.get(i); final DisplayContent dc = mRootWindowContainer.getChildAt(i); // All displays that are not already in the desired touch mode are requested to // All displays that are not already in the desired touch mode are requested to // change their touch mode. // change their touch mode. if (dc.isInTouchMode() != inTouchMode) { if (dc.isInTouchMode() != inTouchMode) { verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager, description("perDisplayFocusEnabled=" true, callingPid, callingUid, /* hasPermission= */ true, + mWm.mPerDisplayFocusEnabled)).setInTouchMode(true, dc.getDisplay().getDisplayId()); callingPid, callingUid, /* hasPermission= */ true, dc.mDisplayId); } } } } } } } }; private VirtualDisplay createVirtualDisplay(boolean ownFocus) { mWm.mPerDisplayFocusEnabled = false; // Create virtual display verification.run(); Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); int flags = VIRTUAL_DISPLAY_FLAG_PUBLIC; if (ownFocus) { flags |= VIRTUAL_DISPLAY_FLAG_OWN_FOCUS | VIRTUAL_DISPLAY_FLAG_TRUSTED; } VirtualDisplay virtualDisplay = mWm.mDisplayManager.createVirtualDisplay("VirtualDisplay", surfaceSize.x, surfaceSize.y, DisplayMetrics.DENSITY_140, new Surface(), flags); final int displayId = virtualDisplay.getDisplay().getDisplayId(); mWm.mRoot.onDisplayAdded(displayId); // Ensure that virtual display was properly created and stored in WRC assertThat(mWm.mRoot.getDisplayContent( virtualDisplay.getDisplay().getDisplayId())).isNotNull(); return virtualDisplay; clearInvocations(mWm.mInputManager); mWm.mPerDisplayFocusEnabled = true; verification.run(); } } @Test @Test Loading services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -901,6 +901,7 @@ class WindowTestsBase extends SystemServiceTestsBase { DisplayInfo displayInfo = new DisplayInfo(); DisplayInfo displayInfo = new DisplayInfo(); displayInfo.copyFrom(mDisplayInfo); displayInfo.copyFrom(mDisplayInfo); displayInfo.type = Display.TYPE_VIRTUAL; displayInfo.type = Display.TYPE_VIRTUAL; displayInfo.state = Display.STATE_ON; displayInfo.ownerUid = SYSTEM_UID; displayInfo.ownerUid = SYSTEM_UID; return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings); return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings); } } Loading Loading
services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -453,6 +453,78 @@ public class ContentRecorderTests extends WindowTestsBase { displayAreaBounds.width(), displayAreaBounds.height()); displayAreaBounds.width(), displayAreaBounds.height()); } } @Test public void testDisplayContentUpdatesRecording_withoutSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // WHEN getting the DisplayContent for the new virtual display without providing a valid // size from getDisplaySurfaceDefaultSize, i.e. the case of null surface. final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); doReturn(null).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(anyInt()); mWm.mContentRecordingController.setContentRecordingSessionLocked(mDisplaySession, mWm); virtualDisplay.updateRecording(); // THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off. assertThat(virtualDisplay.isCurrentlyRecording()).isFalse(); } @Test public void testDisplayContentUpdatesRecording_withSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // WHEN getting the DisplayContent for the virtual display with a valid size from // getDisplaySurfaceDefaultSize (done by surfaceControlMirrors in setUp). final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); mWm.mContentRecordingController.setContentRecordingSessionLocked(mDisplaySession, mWm); virtualDisplay.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. assertThat(virtualDisplay.isCurrentlyRecording()).isTrue(); } @Test public void testDisplayContentUpdatesRecording_displayMirroring() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. surfaceControlMirrors(sSurfaceSize); // Initially disable getDisplayIdToMirror since the DMS may create the DC outside the direct // call in the test. We need to spy on the DC before updateRecording is called or we can't // verify setDisplayMirroring is called doReturn(INVALID_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); // WHEN getting the DisplayContent for the new virtual display. final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); // Return the default display as the value to mirror to ensure the VD with flag mirroring // creates a ContentRecordingSession automatically. doReturn(DEFAULT_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); virtualDisplay.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. verify(virtualDisplay).setDisplayMirroring(); assertThat(virtualDisplay.isCurrentlyRecording()).isTrue(); } /** * Creates a WindowToken associated with the default task DisplayArea, in order for that * DisplayArea to be mirrored. */ private void setUpDefaultTaskDisplayAreaWindowToken() { // GIVEN the default task display area is represented by the WindowToken. spyOn(mWm.mWindowContextListenerController); doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when( mWm.mWindowContextListenerController).getContainer(any()); } /** /** * Creates a {@link android.window.WindowContainerToken} associated with a task, in order for * Creates a {@link android.window.WindowContainerToken} associated with a task, in order for * that task to be recorded. * that task to be recorded. Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +0 −137 Original line number Original line Diff line number Diff line Loading @@ -27,12 +27,10 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; import static android.os.Build.VERSION_CODES.P; import static android.os.Build.VERSION_CODES.P; import static android.os.Build.VERSION_CODES.Q; import static android.os.Build.VERSION_CODES.Q; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.INVALID_DISPLAY; import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; import static android.view.DisplayCutout.fromBoundingRect; import static android.view.DisplayCutout.fromBoundingRect; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_0; Loading Loading @@ -112,11 +110,9 @@ import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.HardwareBuffer; import android.hardware.display.VirtualDisplay; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.os.Binder; import android.os.Binder; import android.os.RemoteException; import android.os.RemoteException; Loading @@ -124,7 +120,6 @@ import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.DisplayMetrics; import android.view.ContentRecordingSession; import android.view.Display; import android.view.Display; import android.view.DisplayCutout; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.DisplayInfo; Loading Loading @@ -2654,138 +2649,6 @@ public class DisplayContentTests extends WindowTestsBase { assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); } } @Test public void testVirtualDisplayContent_withoutSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl does not mirror a null surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, null /* surface */); final int displayId = display.getDisplay().getDisplayId(); mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); ContentRecordingSession session = ContentRecordingSession.createDisplaySession( DEFAULT_DISPLAY); session.setVirtualDisplayId(displayId); mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm); actualDC.updateRecording(); // THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off. assertThat(actualDC.isCurrentlyRecording()).isFalse(); display.release(); } @Test public void testVirtualDisplayContent_withSurface() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); surfaceControlMirrors(surfaceSize); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, new Surface()); final int displayId = display.getDisplay().getDisplayId(); // GIVEN a session for this display. ContentRecordingSession session = ContentRecordingSession.createDisplaySession( DEFAULT_DISPLAY); session.setVirtualDisplayId(displayId); mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm); mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); actualDC.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. assertThat(actualDC.isCurrentlyRecording()).isTrue(); display.release(); } @Test public void testVirtualDisplayContent_displayMirroring() { // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); // GIVEN SurfaceControl can successfully mirror the provided surface. Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); surfaceControlMirrors(surfaceSize); // Initially disable getDisplayIdToMirror since the DMS may create the DC outside the direct // call in the test. We need to spy on the DC before updateRecording is called or we can't // verify setDisplayMirroring is called doReturn(INVALID_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); // GIVEN a new VirtualDisplay with an associated surface. final VirtualDisplay display = createVirtualDisplay(surfaceSize, new Surface()); final int displayId = display.getDisplay().getDisplayId(); // GIVEN a session for this display. mWm.mRoot.onDisplayAdded(displayId); // WHEN getting the DisplayContent for the new virtual display. DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId); spyOn(actualDC); // Return the default display as the value to mirror to ensure the VD with flag mirroring // creates a ContentRecordingSession automatically. doReturn(DEFAULT_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); actualDC.updateRecording(); // THEN mirroring is initiated for the default display's DisplayArea. verify(actualDC).setDisplayMirroring(); assertThat(actualDC.isCurrentlyRecording()).isTrue(); display.release(); } /** * Creates a WindowToken associated with the default task DisplayArea, in order for that * DisplayArea to be mirrored. */ private void setUpDefaultTaskDisplayAreaWindowToken() { // GIVEN the default task display area is represented by the WindowToken. spyOn(mWm.mWindowContextListenerController); doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when( mWm.mWindowContextListenerController).getContainer(any()); } /** * SurfaceControl successfully creates a mirrored surface of the given size. */ private SurfaceControl surfaceControlMirrors(Point surfaceSize) { // Do not set the parent, since the mirrored surface is the root of a new surface hierarchy. SurfaceControl mirroredSurface = new SurfaceControl.Builder() .setName("mirroredSurface") .setBufferSize(surfaceSize.x, surfaceSize.y) .setCallsite("mirrorSurface") .build(); doReturn(mirroredSurface).when(() -> SurfaceControl.mirrorSurface(any())); doReturn(surfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize( anyInt()); return mirroredSurface; } private VirtualDisplay createVirtualDisplay(Point size, Surface surface) { return mWm.mDisplayManager.createVirtualDisplay("VirtualDisplay", size.x, size.y, DisplayMetrics.DENSITY_140, surface, VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR); } @Test @Test public void testKeepClearAreasMultipleWindows() { public void testKeepClearAreasMultipleWindows() { final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1"); final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1"); Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +42 −80 Original line number Original line Diff line number Diff line Loading @@ -21,9 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY; Loading Loading @@ -63,6 +60,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.description; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify; Loading @@ -71,9 +70,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityThread; import android.app.ActivityThread; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.hardware.display.VirtualDisplay; import android.os.Binder; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.IBinder; import android.os.IBinder; Loading @@ -82,7 +79,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.util.MergedConfiguration; import android.util.MergedConfiguration; import android.view.ContentRecordingSession; import android.view.ContentRecordingSession; import android.view.IWindow; import android.view.IWindow; Loading @@ -90,7 +86,6 @@ import android.view.IWindowSessionCallback; import android.view.InputChannel; import android.view.InputChannel; import android.view.InsetsSourceControl; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl; import android.view.View; import android.view.View; import android.view.WindowInsets; import android.view.WindowInsets; Loading Loading @@ -575,13 +570,14 @@ public class WindowManagerServiceTests extends WindowTestsBase { mWm.mPerDisplayFocusEnabled = false; mWm.mPerDisplayFocusEnabled = false; // Create one extra display // Create one extra display final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent display = createMockSimulatedDisplay(); final VirtualDisplay virtualDisplayOwnTouchMode = display.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; createVirtualDisplay(/* ownFocus= */ true); final DisplayContent displayOwnTouchMode = createMockSimulatedDisplay(); displayOwnTouchMode.getDisplayInfo().flags |= FLAG_OWN_FOCUS; final int numberOfDisplays = mWm.mRoot.mChildren.size(); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(3); assertThat(numberOfDisplays).isAtLeast(3); final int numberOfGlobalTouchModeDisplays = (int) mWm.mRoot.mChildren.stream() final int numberOfGlobalTouchModeDisplays = (int) mWm.mRoot.mChildren.stream() .filter(d -> (d.getDisplay().getFlags() & FLAG_OWN_FOCUS) == 0) .filter(d -> (d.getDisplayInfo().flags & FLAG_OWN_FOCUS) == 0) .count(); .count(); assertThat(numberOfGlobalTouchModeDisplays).isAtLeast(2); assertThat(numberOfGlobalTouchModeDisplays).isAtLeast(2); Loading @@ -601,12 +597,13 @@ public class WindowManagerServiceTests extends WindowTestsBase { } } @Test @Test public void testSetInTouchMode_multiDisplay_perDisplayFocus_singleDisplayTouchModeUpdate() { public void testSetInTouchMode_multiDisplay_singleDisplayTouchModeUpdate() { // Enable global touch mode // Enable global touch mode mWm.mPerDisplayFocusEnabled = true; mWm.mPerDisplayFocusEnabled = true; // Create one extra display // Create one extra display final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent virtualDisplay = createMockSimulatedDisplay(); virtualDisplay.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; final int numberOfDisplays = mWm.mRoot.mChildren.size(); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(2); assertThat(numberOfDisplays).isAtLeast(2); Loading @@ -618,99 +615,64 @@ public class WindowManagerServiceTests extends WindowTestsBase { when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.getDisplay().getDisplayId()); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.mDisplayId); // Ensure that new display touch mode state has changed. // Ensure that new display touch mode state has changed. verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager).setInTouchMode( !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, virtualDisplay.getDisplay().getDisplayId()); virtualDisplay.mDisplayId); } @Test // Disable global touch mode and make the virtual display own focus. public void testSetInTouchMode_multiDisplay_ownTouchMode_singleDisplayTouchModeUpdate() { // Disable global touch mode mWm.mPerDisplayFocusEnabled = false; mWm.mPerDisplayFocusEnabled = false; virtualDisplay.getDisplayInfo().flags |= FLAG_OWN_FOCUS; // Create one extra display clearInvocations(mWm.mInputManager); final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.mDisplayId); final int numberOfDisplays = mWm.mRoot.mChildren.size(); assertThat(numberOfDisplays).isAtLeast(2); // Get current touch mode state and setup WMS to run setInTouchMode boolean currentTouchMode = mWm.isInTouchMode(DEFAULT_DISPLAY); int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); mWm.setInTouchMode(!currentTouchMode, virtualDisplay.getDisplay().getDisplayId()); // Ensure that new display touch mode state has changed. // Ensure that new display touch mode state has changed. verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager).setInTouchMode( !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true, virtualDisplay.getDisplay().getDisplayId()); virtualDisplay.mDisplayId); } } @Test @Test public void testSetInTouchModeOnAllDisplays_perDisplayFocusDisabled() { public void testSetInTouchModeOnAllDisplays() { testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ false); } @Test public void testSetInTouchModeOnAllDisplays_perDisplayFocusEnabled() { testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ true); } private void testSetInTouchModeOnAllDisplays(boolean perDisplayFocusEnabled) { // Set global touch mode with the value passed as argument. mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled; // Create a couple of extra displays. // Create a couple of extra displays. // setInTouchModeOnAllDisplays should ignore the ownFocus setting. // setInTouchModeOnAllDisplays should ignore the ownFocus setting. final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false); final DisplayContent display = createMockSimulatedDisplay(); final VirtualDisplay virtualDisplayOwnFocus = createVirtualDisplay(/* ownFocus= */ true); display.getDisplayInfo().flags &= ~FLAG_OWN_FOCUS; final DisplayContent displayOwnTouchMode = createMockSimulatedDisplay(); displayOwnTouchMode.getDisplayInfo().flags |= FLAG_OWN_FOCUS; int callingPid = Binder.getCallingPid(); int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid(); doReturn(true).when(mWm.mInputManager).setInTouchMode(anyBoolean(), anyInt(), anyInt(), anyBoolean(), anyInt()); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean()); when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid, android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true); final Runnable verification = () -> { for (boolean inTouchMode : new boolean[] { true, false }) { for (boolean inTouchMode : new boolean[] { true, false }) { mWm.setInTouchModeOnAllDisplays(inTouchMode); mWm.setInTouchModeOnAllDisplays(inTouchMode); for (int i = 0; i < mWm.mRoot.mChildren.size(); ++i) { for (int i = 0; i < mRootWindowContainer.getChildCount(); ++i) { DisplayContent dc = mWm.mRoot.mChildren.get(i); final DisplayContent dc = mRootWindowContainer.getChildAt(i); // All displays that are not already in the desired touch mode are requested to // All displays that are not already in the desired touch mode are requested to // change their touch mode. // change their touch mode. if (dc.isInTouchMode() != inTouchMode) { if (dc.isInTouchMode() != inTouchMode) { verify(mWm.mInputManager).setInTouchMode( verify(mWm.mInputManager, description("perDisplayFocusEnabled=" true, callingPid, callingUid, /* hasPermission= */ true, + mWm.mPerDisplayFocusEnabled)).setInTouchMode(true, dc.getDisplay().getDisplayId()); callingPid, callingUid, /* hasPermission= */ true, dc.mDisplayId); } } } } } } } }; private VirtualDisplay createVirtualDisplay(boolean ownFocus) { mWm.mPerDisplayFocusEnabled = false; // Create virtual display verification.run(); Point surfaceSize = new Point( mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); int flags = VIRTUAL_DISPLAY_FLAG_PUBLIC; if (ownFocus) { flags |= VIRTUAL_DISPLAY_FLAG_OWN_FOCUS | VIRTUAL_DISPLAY_FLAG_TRUSTED; } VirtualDisplay virtualDisplay = mWm.mDisplayManager.createVirtualDisplay("VirtualDisplay", surfaceSize.x, surfaceSize.y, DisplayMetrics.DENSITY_140, new Surface(), flags); final int displayId = virtualDisplay.getDisplay().getDisplayId(); mWm.mRoot.onDisplayAdded(displayId); // Ensure that virtual display was properly created and stored in WRC assertThat(mWm.mRoot.getDisplayContent( virtualDisplay.getDisplay().getDisplayId())).isNotNull(); return virtualDisplay; clearInvocations(mWm.mInputManager); mWm.mPerDisplayFocusEnabled = true; verification.run(); } } @Test @Test Loading
services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -901,6 +901,7 @@ class WindowTestsBase extends SystemServiceTestsBase { DisplayInfo displayInfo = new DisplayInfo(); DisplayInfo displayInfo = new DisplayInfo(); displayInfo.copyFrom(mDisplayInfo); displayInfo.copyFrom(mDisplayInfo); displayInfo.type = Display.TYPE_VIRTUAL; displayInfo.type = Display.TYPE_VIRTUAL; displayInfo.state = Display.STATE_ON; displayInfo.ownerUid = SYSTEM_UID; displayInfo.ownerUid = SYSTEM_UID; return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings); return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings); } } Loading