diff options
author | 2023-01-11 10:54:02 +0000 | |
---|---|---|
committer | 2023-01-11 10:54:02 +0000 | |
commit | 7cc40702af9f5a0ea3b858d12102f887b59ad977 (patch) | |
tree | 15c1c748d8db9701a071658eaa2e589060b07acb | |
parent | 00c3793fd4a4373ef1dc328aa0fdd6103eddcbea (diff) | |
parent | 7de5897932275af2223de287ee0b1134bf6f6991 (diff) |
Merge "Add isValidVirtualDeviceId api to VDM"
8 files changed, 88 insertions, 70 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 240dbe1eea24..befe833a6a11 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -26,9 +26,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiContext; -import android.companion.virtual.VirtualDevice; import android.companion.virtual.VirtualDeviceManager; -import android.companion.virtual.VirtualDeviceParams; import android.compat.annotation.UnsupportedAppUsage; import android.content.AttributionSource; import android.content.AutofillOptions; @@ -2742,9 +2740,12 @@ class ContextImpl extends Context { @Override public @NonNull Context createDeviceContext(int deviceId) { - if (!isValidDeviceId(deviceId)) { - throw new IllegalArgumentException( - "Not a valid ID of the default device or any virtual device: " + deviceId); + if (deviceId != VirtualDeviceManager.DEVICE_ID_DEFAULT) { + VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class); + if (!vdm.isValidVirtualDeviceId(deviceId)) { + throw new IllegalArgumentException( + "Not a valid ID of the default device or any virtual device: " + deviceId); + } } ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, @@ -2757,31 +2758,6 @@ class ContextImpl extends Context { return context; } - /** - * Checks whether the passed {@code deviceId} is valid or not. - * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is valid as it is the ID of the default - * device when no additional virtual devices exist. If {@code deviceId} is the id of - * a virtual device, it should correspond to a virtual device created by - * {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}. - */ - private boolean isValidDeviceId(int deviceId) { - if (deviceId == VirtualDeviceManager.DEVICE_ID_DEFAULT) { - return true; - } - if (deviceId > VirtualDeviceManager.DEVICE_ID_DEFAULT) { - VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class); - if (vdm != null) { - List<VirtualDevice> virtualDevices = vdm.getVirtualDevices(); - for (int i = 0; i < virtualDevices.size(); i++) { - if (virtualDevices.get(i).getDeviceId() == deviceId) { - return true; - } - } - } - } - return false; - } - @NonNull @Override public WindowContext createWindowContext(@WindowType int type, @@ -3044,10 +3020,13 @@ class ContextImpl extends Context { @Override public void updateDeviceId(int updatedDeviceId) { - if (!isValidDeviceId(updatedDeviceId)) { - throw new IllegalArgumentException( - "Not a valid ID of the default device or any virtual device: " - + updatedDeviceId); + if (updatedDeviceId != VirtualDeviceManager.DEVICE_ID_DEFAULT) { + VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class); + if (!vdm.isValidVirtualDeviceId(updatedDeviceId)) { + throw new IllegalArgumentException( + "Not a valid ID of the default device or any virtual device: " + + updatedDeviceId); + } } if (mIsExplicitDeviceId) { throw new UnsupportedOperationException( diff --git a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl index f0d23ac8374f..e96a2c18037b 100644 --- a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl +++ b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl @@ -56,6 +56,14 @@ interface IVirtualDeviceManager { */ int getDeviceIdForDisplayId(int displayId); + /** + * Checks whether the passed {@code deviceId} is a valid virtual device ID or not. + * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is not valid as it is the ID of the default + * device which is not a virtual device. {@code deviceId} must correspond to a virtual device + * created by {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}. + */ + boolean isValidVirtualDeviceId(int deviceId); + /** * Returns the device policy for the given virtual device and policy type. */ diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 6ad18d545a6d..3bc1628d3576 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -258,6 +258,26 @@ public final class VirtualDeviceManager { } /** + * Checks whether the passed {@code deviceId} is a valid virtual device ID or not. + * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is not valid as it is the ID of the default + * device which is not a virtual device. {@code deviceId} must correspond to a virtual device + * created by {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}. + * + * @hide + */ + public boolean isValidVirtualDeviceId(int deviceId) { + if (mService == null) { + Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service."); + return false; + } + try { + return mService.isValidVirtualDeviceId(deviceId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns device-specific audio session id for audio playback. * * @param deviceId - id of the virtual audio device diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java index 758345f716c3..b0f2464ff52a 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -139,15 +139,6 @@ public class VirtualDeviceManagerService extends SystemService { mActivityInterceptorCallback); } - @GuardedBy("mVirtualDeviceManagerLock") - private boolean isValidVirtualDeviceLocked(IVirtualDevice virtualDevice) { - try { - return mVirtualDevices.contains(virtualDevice.getDeviceId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - void onCameraAccessBlocked(int appUid) { synchronized (mVirtualDeviceManagerLock) { for (int i = 0; i < mVirtualDevices.size(); i++) { @@ -347,6 +338,14 @@ public class VirtualDeviceManagerService extends SystemService { return VirtualDeviceManager.DEVICE_ID_DEFAULT; } + // Binder call + @Override + public boolean isValidVirtualDeviceId(int deviceId) { + synchronized (mVirtualDeviceManagerLock) { + return mVirtualDevices.contains(deviceId); + } + } + @Override // Binder call public int getAudioPlaybackSessionId(int deviceId) { synchronized (mVirtualDeviceManagerLock) { @@ -445,13 +444,6 @@ public class VirtualDeviceManagerService extends SystemService { private final ArraySet<Integer> mAllUidsOnVirtualDevice = new ArraySet<>(); @Override - public boolean isValidVirtualDevice(IVirtualDevice virtualDevice) { - synchronized (mVirtualDeviceManagerLock) { - return isValidVirtualDeviceLocked(virtualDevice); - } - } - - @Override public int getDeviceOwnerUid(int deviceId) { synchronized (mVirtualDeviceManagerLock) { VirtualDeviceImpl virtualDevice = mVirtualDevices.get(deviceId); diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java index e3ea1a6a3de7..974c04bc45f5 100644 --- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java +++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java @@ -68,11 +68,6 @@ public abstract class VirtualDeviceManagerInternal { public abstract void onAppsOnVirtualDeviceChanged(); /** - * Validate the virtual device. - */ - public abstract boolean isValidVirtualDevice(IVirtualDevice virtualDevice); - - /** * Gets the owner uid for a deviceId. * * @param deviceId which device we're asking about diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index d44e1dc121c9..06b99f82362a 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -47,6 +47,7 @@ import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.companion.virtual.IVirtualDevice; +import android.companion.virtual.VirtualDeviceManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.BroadcastReceiver; @@ -1281,12 +1282,17 @@ public final class DisplayManagerService extends SystemService { final Surface surface = virtualDisplayConfig.getSurface(); int flags = virtualDisplayConfig.getFlags(); if (virtualDevice != null) { - final VirtualDeviceManagerInternal vdm = - getLocalService(VirtualDeviceManagerInternal.class); - if (!vdm.isValidVirtualDevice(virtualDevice)) { - throw new SecurityException("Invalid virtual device"); + final VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class); + try { + if (!vdm.isValidVirtualDeviceId(virtualDevice.getDeviceId())) { + throw new SecurityException("Invalid virtual device"); + } + } catch (RemoteException ex) { + throw new SecurityException("Unable to validate virtual device"); } - flags |= vdm.getBaseVirtualDisplayFlags(virtualDevice); + final VirtualDeviceManagerInternal localVdm = + getLocalService(VirtualDeviceManagerInternal.class); + flags |= localVdm.getBaseVirtualDisplayFlags(virtualDevice); } if (surface != null && surface.isSingleBuffered()) { diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 759b0497044f..eb99e30b58ec 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -369,6 +369,21 @@ public class VirtualDeviceManagerServiceTest { } @Test + public void isDeviceIdValid_defaultDeviceId_returnsFalse() { + assertThat(mVdm.isValidVirtualDeviceId(DEVICE_ID_DEFAULT)).isFalse(); + } + + @Test + public void isDeviceIdValid_validVirtualDeviceId_returnsTrue() { + assertThat(mVdm.isValidVirtualDeviceId(mDeviceImpl.getDeviceId())).isTrue(); + } + + @Test + public void isDeviceIdValid_nonExistentDeviceId_returnsFalse() { + assertThat(mVdm.isValidVirtualDeviceId(mDeviceImpl.getDeviceId() + 1)).isFalse(); + } + + @Test public void getDevicePolicy_invalidDeviceId_returnsDefault() { assertThat(mVdm.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_DEFAULT); diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index f676a3f84c0f..2d252cbbbd9c 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -39,6 +39,8 @@ import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; import android.companion.virtual.IVirtualDevice; +import android.companion.virtual.IVirtualDeviceManager; +import android.companion.virtual.VirtualDeviceManager; import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.ContextWrapper; @@ -173,6 +175,7 @@ public class DisplayManagerServiceTest { private final DisplayManagerService.Injector mBasicInjector = new BasicInjector(); + @Mock IVirtualDeviceManager mIVirtualDeviceManager; @Mock InputManagerInternal mMockInputManagerInternal; @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @@ -202,6 +205,8 @@ public class DisplayManagerServiceTest { mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); + VirtualDeviceManager vdm = new VirtualDeviceManager(mIVirtualDeviceManager, mContext); + when(mContext.getSystemService(VirtualDeviceManager.class)).thenReturn(vdm); // Disable binder caches in this process. PropertyInvalidatedCache.disableForTestMode(); setUpDisplay(); @@ -727,10 +732,8 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); - when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) - .thenReturn(true); when(virtualDevice.getDeviceId()).thenReturn(1); - + when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Create a first virtual display. A display group should be created for this display on the // virtual device. final VirtualDisplayConfig.Builder builder1 = @@ -780,9 +783,8 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); - when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) - .thenReturn(true); when(virtualDevice.getDeviceId()).thenReturn(1); + when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Create a first virtual display. A display group should be created for this display on the // virtual device. @@ -806,6 +808,8 @@ public class DisplayManagerServiceTest { .setFlags(VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) .setUniqueId("uniqueId --- own display group"); + when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); + int displayId2 = localService.createVirtualDisplay( builder2.build(), @@ -832,9 +836,8 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); - when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) - .thenReturn(true); when(virtualDevice.getDeviceId()).thenReturn(1); + when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); // Allow an ALWAYS_UNLOCKED display to be created. when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)) @@ -1062,7 +1065,7 @@ public class DisplayManagerServiceTest { * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted. */ @Test - public void testOwnDisplayGroup_allowCreationWithVirtualDevice() { + public void testOwnDisplayGroup_allowCreationWithVirtualDevice() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); @@ -1081,8 +1084,8 @@ public class DisplayManagerServiceTest { builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); - when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice)) - .thenReturn(true); + when(virtualDevice.getDeviceId()).thenReturn(1); + when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); int displayId = localService.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, virtualDevice /* virtualDeviceToken */, |