summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Komsiyski <vladokom@google.com> 2024-11-25 13:48:17 +0100
committer Vladimir Komsiyski <vladokom@google.com> 2024-11-26 12:58:18 +0100
commit7ab4751a2a90c473e81d044a6772b4203a94370c (patch)
tree182e9a323af62f910bd2674712a50abc1357197f
parent115142b26cd48344d39e4b0bfe7f610e04a9e9cc (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
-rw-r--r--core/java/android/companion/virtual/IVirtualDevice.aidl6
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java9
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java49
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.