Add isValidVirtualDeviceId api to VDM
Remove equivalent method from LocalService and use this one instead. Also update ContextImpl to use the API Bug: 263355088 Test: atest VirtualDeviceManagerServiceTest Change-Id: Ic2721d5104cbaa2ddaa6b51e8a4734fc0606c1c2
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -257,6 +257,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.
|
||||
*
|
||||
|
||||
@@ -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) {
|
||||
@@ -444,13 +443,6 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
@GuardedBy("mVirtualDeviceManagerLock")
|
||||
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) {
|
||||
|
||||
@@ -67,11 +67,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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
@@ -1273,12 +1274,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()) {
|
||||
|
||||
@@ -368,6 +368,21 @@ public class VirtualDeviceManagerServiceTest {
|
||||
.isEqualTo(mDeviceImpl.getDeviceId());
|
||||
}
|
||||
|
||||
@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))
|
||||
|
||||
@@ -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 */,
|
||||
|
||||
Reference in New Issue
Block a user