Loading core/java/android/companion/virtual/VirtualDeviceManager.java +1 −3 Original line number Diff line number Diff line Loading @@ -194,9 +194,7 @@ public final class VirtualDeviceManager { /** * Creates a virtual display for this virtual device. All displays created on the same * device belongs to the same display group. Requires the ADD_TRUSTED_DISPLAY permission * to create a virtual display which is not in the default DisplayGroup, and to create * trusted displays. * device belongs to the same display group. * * @param width The width of the virtual display in pixels, must be greater than 0. * @param height The height of the virtual display in pixels, must be greater than 0. Loading services/core/java/com/android/server/display/DisplayManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -1318,7 +1318,9 @@ public final class DisplayManagerService extends SystemService { if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { // The virtualDevice instance has been validated above using isValidVirtualDevice if (virtualDevice == null && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "create a virtual display which is not in the default DisplayGroup."); } Loading services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +101 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; import android.companion.virtual.IVirtualDevice; import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.ContextWrapper; Loading Loading @@ -73,6 +74,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.lights.LightsManager; import com.android.server.sensors.SensorManagerInternal; Loading Loading @@ -167,6 +169,7 @@ public class DisplayManagerServiceTest { }; @Mock InputManagerInternal mMockInputManagerInternal; @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock IVirtualDisplayCallback.Stub mMockAppToken2; @Mock WindowManagerInternal mMockWindowManagerInternal; Loading @@ -187,6 +190,9 @@ public class DisplayManagerServiceTest { LocalServices.addService(LightsManager.class, mMockLightsManager); LocalServices.removeServiceForTest(SensorManagerInternal.class); LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal); LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class); LocalServices.addService( VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal); mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mDeviceConfig = new FakeDeviceConfigInterface(); Loading Loading @@ -660,6 +666,101 @@ public class DisplayManagerServiceTest { /*deviceConfigAllows*/ false, /*flagExpected*/ false); } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission * ADD_TRUSTED_DISPLAY is granted. */ @Test public void testOwnDisplayGroup_allowCreationWithAddTrustedDisplayPermission() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_GRANTED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME); displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is blocked when the permission * ADD_TRUSTED_DISPLAY is denied. */ @Test public void testOwnDisplayGroup_withoutAddTrustedDisplayPermission_throwsSecurityException() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_DENIED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); try { bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME); fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without " + "ADD_TRUSTED_DISPLAY permission should throw SecurityException."); } catch (SecurityException e) { // SecurityException is expected } } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when called with * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted. */ @Test public void testOwnDisplayGroup_allowCreationWithVirtualDevice() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_DENIED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) .thenReturn(true); int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, virtualDevice /* virtualDeviceToken */, PACKAGE_NAME); displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); } /** * Tests that there is a display change notification if the frame rate override * list is updated. Loading Loading
core/java/android/companion/virtual/VirtualDeviceManager.java +1 −3 Original line number Diff line number Diff line Loading @@ -194,9 +194,7 @@ public final class VirtualDeviceManager { /** * Creates a virtual display for this virtual device. All displays created on the same * device belongs to the same display group. Requires the ADD_TRUSTED_DISPLAY permission * to create a virtual display which is not in the default DisplayGroup, and to create * trusted displays. * device belongs to the same display group. * * @param width The width of the virtual display in pixels, must be greater than 0. * @param height The height of the virtual display in pixels, must be greater than 0. Loading
services/core/java/com/android/server/display/DisplayManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -1318,7 +1318,9 @@ public final class DisplayManagerService extends SystemService { if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { // The virtualDevice instance has been validated above using isValidVirtualDevice if (virtualDevice == null && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "create a virtual display which is not in the default DisplayGroup."); } Loading
services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +101 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; import android.companion.virtual.IVirtualDevice; import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.ContextWrapper; Loading Loading @@ -73,6 +74,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.lights.LightsManager; import com.android.server.sensors.SensorManagerInternal; Loading Loading @@ -167,6 +169,7 @@ public class DisplayManagerServiceTest { }; @Mock InputManagerInternal mMockInputManagerInternal; @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock IVirtualDisplayCallback.Stub mMockAppToken2; @Mock WindowManagerInternal mMockWindowManagerInternal; Loading @@ -187,6 +190,9 @@ public class DisplayManagerServiceTest { LocalServices.addService(LightsManager.class, mMockLightsManager); LocalServices.removeServiceForTest(SensorManagerInternal.class); LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal); LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class); LocalServices.addService( VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal); mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mDeviceConfig = new FakeDeviceConfigInterface(); Loading Loading @@ -660,6 +666,101 @@ public class DisplayManagerServiceTest { /*deviceConfigAllows*/ false, /*flagExpected*/ false); } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission * ADD_TRUSTED_DISPLAY is granted. */ @Test public void testOwnDisplayGroup_allowCreationWithAddTrustedDisplayPermission() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_GRANTED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME); displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is blocked when the permission * ADD_TRUSTED_DISPLAY is denied. */ @Test public void testOwnDisplayGroup_withoutAddTrustedDisplayPermission_throwsSecurityException() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_DENIED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); try { bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME); fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without " + "ADD_TRUSTED_DISPLAY permission should throw SecurityException."); } catch (SecurityException e) { // SecurityException is expected } } /** * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when called with * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted. */ @Test public void testOwnDisplayGroup_allowCreationWithVirtualDevice() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); DisplayManagerService.BinderService bs = displayManager.new BinderService(); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( PackageManager.PERMISSION_DENIED); final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( VIRTUAL_DISPLAY_NAME, 600, 800, 320); builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) .thenReturn(true); int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, null /* projection */, virtualDevice /* virtualDeviceToken */, PACKAGE_NAME); displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); } /** * Tests that there is a display change notification if the frame rate override * list is updated. Loading