diff options
| author | 2024-11-25 13:48:17 +0100 | |
|---|---|---|
| committer | 2024-11-26 12:58:18 +0100 | |
| commit | 7ab4751a2a90c473e81d044a6772b4203a94370c (patch) | |
| tree | 182e9a323af62f910bd2674712a50abc1357197f | |
| parent | 115142b26cd48344d39e4b0bfe7f610e04a9e9cc (diff) | |
Add back the role-dependent VDM mirror display logic.
It was removed in favor of the new ADD_MIRROR_DISPLAY permission
but that permission is not launching in 25Q2 and we want to only
allow APP_STREAMING role holders to create mirror displays before
that.
Bug: 368573883
Fix: 380473997
Test: presubmit
Flag: EXEMPT bugfix
Change-Id: Ic10f74c43a3263d3a8590e752af9ca737dec096f
4 files changed, 54 insertions, 17 deletions
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl index 367f1afc912b..f8ac27de1754 100644 --- a/core/java/android/companion/virtual/IVirtualDevice.aidl +++ b/core/java/android/companion/virtual/IVirtualDevice.aidl @@ -90,6 +90,12 @@ interface IVirtualDevice { */ boolean hasCustomAudioInputSupport(); + /** + * Returns whether this device is allowed to create mirror displays. + */ + boolean canCreateMirrorDisplays(); + + /* /* * Turns off all trusted non-mirror displays of the virtual device. */ diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index d4beb019e049..8b5b93e96494 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -44,6 +44,7 @@ import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.app.compat.CompatChanges; import android.companion.AssociationInfo; +import android.companion.AssociationRequest; import android.companion.virtual.ActivityPolicyExemption; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.IVirtualDeviceActivityListener; @@ -155,6 +156,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:"; + private static final List<String> DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS = List.of( + AssociationRequest.DEVICE_PROFILE_APP_STREAMING); + /** * Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched. */ @@ -1348,6 +1352,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return hasCustomAudioInputSupportInternal(); } + @Override + public boolean canCreateMirrorDisplays() { + return DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS.contains(getDeviceProfile()); + } + private boolean hasCustomAudioInputSupportInternal() { if (!Flags.vdmPublicApis()) { return false; diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 3871f2a57f76..c3cb913db679 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1681,7 +1681,12 @@ public final class DisplayManagerService extends SystemService { if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { return checkCallingPermission(ADD_MIRROR_DISPLAY, "canCreateMirrorDisplays"); } - return virtualDevice != null; + try { + return virtualDevice.canCreateMirrorDisplays(); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to query virtual device for permissions", e); + return false; + } } private boolean canProjectVideo(IMediaProjection projection) { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index 47e96d378149..1b56b3ff0654 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -123,7 +123,6 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserManager; import android.os.test.FakePermissionEnforcer; -import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -1387,21 +1386,23 @@ public class DisplayManagerServiceTest { } /** - * Tests that it's not allowed to create an auto-mirror virtual display without - * CAPTURE_VIDEO_OUTPUT permission or a virtual device that can mirror displays + * Tests that it is not allowed to create an auto-mirror virtual display for a virtual device + * without ADD_MIRROR_DISPLAY permission / without the mirror display capability. */ - @EnableFlags(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE) @Test - public void createAutoMirrorDisplay_withoutPermissionOrAllowedVirtualDevice_throwsException() - throws Exception { + public void createAutoMirrorDisplay_withoutPermission_throwsException() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); - when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) - .thenReturn(PackageManager.PERMISSION_DENIED); + if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { + when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) + .thenReturn(PackageManager.PERMISSION_DENIED); + } else { + when(virtualDevice.canCreateMirrorDisplays()).thenReturn(false); + } when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); when(mContext.checkCallingPermission(CAPTURE_VIDEO_OUTPUT)).thenReturn( PackageManager.PERMISSION_DENIED); @@ -1432,8 +1433,12 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); - when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) - .thenReturn(PackageManager.PERMISSION_GRANTED); + if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { + when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + } else { + when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true); + } when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Create an auto-mirror virtual display using a virtual device. @@ -1466,8 +1471,12 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); - when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) - .thenReturn(PackageManager.PERMISSION_GRANTED); + if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { + when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + } else { + when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true); + } when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Create an auto-mirror virtual display using a virtual device. @@ -1534,8 +1543,12 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); - when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) - .thenReturn(PackageManager.PERMISSION_GRANTED); + if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { + when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + } else { + when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true); + } when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); when(mContext.checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY)) .thenReturn(PackageManager.PERMISSION_GRANTED); @@ -1571,8 +1584,12 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); - when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) - .thenReturn(PackageManager.PERMISSION_GRANTED); + if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) { + when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + } else { + when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true); + } when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Create an auto-mirror virtual display using a virtual device. |