Merge "Public API for getting a persistent VD ID."

This commit is contained in:
Vladimir Komsiyski
2023-06-16 09:07:47 +00:00
committed by Android (Google) Code Review
9 changed files with 78 additions and 11 deletions

View File

@@ -9609,6 +9609,7 @@ package android.companion.virtual {
method public int describeContents();
method public int getDeviceId();
method @Nullable public String getName();
method @Nullable public String getPersistentDeviceId();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.VirtualDevice> CREATOR;
}

View File

@@ -3200,6 +3200,7 @@ package android.companion.virtual {
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
method public int getDeviceId();
method @Nullable public String getPersistentDeviceId();
method @NonNull public java.util.List<android.companion.virtual.sensor.VirtualSensor> getVirtualSensorList();
method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);

View File

@@ -58,6 +58,11 @@ interface IVirtualDevice {
*/
int getDeviceId();
/**
* Returns the persistent ID of this virtual device.
*/
String getPersistentDeviceId();
/**
* Closes the virtual device and frees all associated resources.
*/

View File

@@ -35,6 +35,7 @@ import java.util.Objects;
public final class VirtualDevice implements Parcelable {
private final int mId;
private final @Nullable String mPersistentId;
private final @Nullable String mName;
/**
@@ -43,27 +44,54 @@ public final class VirtualDevice implements Parcelable {
*
* @hide
*/
public VirtualDevice(int id, @Nullable String name) {
public VirtualDevice(int id, @Nullable String persistentId, @Nullable String name) {
if (id <= Context.DEVICE_ID_DEFAULT) {
throw new IllegalArgumentException("VirtualDevice ID mist be greater than "
throw new IllegalArgumentException("VirtualDevice ID must be greater than "
+ Context.DEVICE_ID_DEFAULT);
}
mId = id;
mPersistentId = persistentId;
mName = name;
}
private VirtualDevice(@NonNull Parcel parcel) {
mId = parcel.readInt();
mPersistentId = parcel.readString8();
mName = parcel.readString8();
}
/**
* Returns the unique ID of the virtual device.
*
* <p>This identifier corresponds to {@link Context#getDeviceId()} and can be used to access
* device-specific system capabilities.
*
* <p class="note">This identifier is ephemeral and should not be used for persisting any data
* per device.
*
* @see Context#createDeviceContext
* @see #getPersistentDeviceId
*/
public int getDeviceId() {
return mId;
}
/**
* Returns the persistent identifier of this virtual device, if any.
*
* <p> If there is no stable identifier for this virtual device, then this returns {@code null}.
* <p>This identifier may correspond to a physical device. In that case it remains valid for as
* long as that physical device is associated with the host device and may be used to persist
* data per device.
*
* <p class="note">This identifier may not be unique across virtual devices, in case there are
* more than one virtual devices corresponding to the same physical device.
*/
public @Nullable String getPersistentDeviceId() {
return mPersistentId;
}
/**
* Returns the name of the virtual device (optionally) provided during its creation.
*
@@ -81,6 +109,7 @@ public final class VirtualDevice implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mId);
dest.writeString8(mPersistentId);
dest.writeString8(mName);
}
@@ -94,12 +123,13 @@ public final class VirtualDevice implements Parcelable {
}
VirtualDevice that = (VirtualDevice) o;
return mId == that.mId
&& Objects.equals(mPersistentId, that.mPersistentId)
&& Objects.equals(mName, that.mName);
}
@Override
public int hashCode() {
return Objects.hash(mId, mName);
return Objects.hash(mId, mPersistentId, mName);
}
@Override
@@ -107,6 +137,7 @@ public final class VirtualDevice implements Parcelable {
public String toString() {
return "VirtualDevice("
+ " mId=" + mId
+ " mPersistentId=" + mPersistentId
+ " mName=" + mName
+ ")";
}

View File

@@ -160,6 +160,14 @@ public class VirtualDeviceInternal {
}
}
@Nullable String getPersistentDeviceId() {
try {
return mVirtualDevice.getPersistentDeviceId();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@NonNull Context createContext() {
try {
return mContext.createDeviceContext(mVirtualDevice.getDeviceId());

View File

@@ -366,6 +366,13 @@ public final class VirtualDeviceManager {
return mVirtualDeviceInternal.getDeviceId();
}
/**
* Returns the persistent ID of this virtual device.
*/
public @Nullable String getPersistentDeviceId() {
return mVirtualDeviceInternal.getPersistentDeviceId();
}
/**
* Returns a new context bound to this device.
*

View File

@@ -113,6 +113,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
| DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:";
/**
* Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched.
*/
@@ -126,6 +128,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
private final PendingTrampolineCallback mPendingTrampolineCallback;
private final int mOwnerUid;
private int mDeviceId;
private @Nullable String mPersistentDeviceId;
// Thou shall not hold the mVirtualDeviceLock over the mInputController calls.
// Holding the lock can lead to lock inversion with GlobalWindowManagerLock.
// 1. After display is created the window manager calls into VDM during construction
@@ -240,6 +243,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(ownerUid);
mContext = context.createContextAsUser(ownerUserHandle, 0);
mAssociationInfo = associationInfo;
mPersistentDeviceId = PERSISTENT_ID_PREFIX_CDM_ASSOCIATION + associationInfo.getId();
mService = service;
mPendingTrampolineCallback = pendingTrampolineCallback;
mActivityListener = activityListener;
@@ -329,6 +333,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
return mDeviceId;
}
/** Returns the unique device ID of this device. */
@Override // Binder call
public @Nullable String getPersistentDeviceId() {
return mPersistentDeviceId;
}
@Override // Binder call
public int getAssociationId() {
return mAssociationInfo.getId();

View File

@@ -396,7 +396,8 @@ public class VirtualDeviceManagerService extends SystemService {
for (int i = 0; i < mVirtualDevices.size(); i++) {
final VirtualDeviceImpl device = mVirtualDevices.valueAt(i);
virtualDevices.add(
new VirtualDevice(device.getDeviceId(), device.getDeviceName()));
new VirtualDevice(device.getDeviceId(), device.getPersistentDeviceId(),
device.getDeviceName()));
}
}
return virtualDevices;

View File

@@ -37,34 +37,36 @@ import org.junit.runner.RunWith;
public class VirtualDeviceTest {
private static final int VIRTUAL_DEVICE_ID = 42;
private static final String VIRTUAL_DEVICE_NAME = "VirtualDeviceName";
private static final String PERSISTENT_ID = "persistentId";
private static final String DEVICE_NAME = "VirtualDeviceName";
@Test
public void build_invalidId_shouldThrowIllegalArgumentException() {
assertThrows(
IllegalArgumentException.class,
() -> new VirtualDevice(DEVICE_ID_INVALID, VIRTUAL_DEVICE_NAME));
() -> new VirtualDevice(DEVICE_ID_INVALID, PERSISTENT_ID, DEVICE_NAME));
}
@Test
public void build_defaultId_shouldThrowIllegalArgumentException() {
assertThrows(
IllegalArgumentException.class,
() -> new VirtualDevice(DEVICE_ID_DEFAULT, VIRTUAL_DEVICE_NAME));
() -> new VirtualDevice(DEVICE_ID_DEFAULT, PERSISTENT_ID, DEVICE_NAME));
}
@Test
public void build_nameIsOptional() {
public void build_onlyRequiredFields() {
VirtualDevice virtualDevice =
new VirtualDevice(VIRTUAL_DEVICE_ID, /* name= */ null);
new VirtualDevice(VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null);
assertThat(virtualDevice.getDeviceId()).isEqualTo(VIRTUAL_DEVICE_ID);
assertThat(virtualDevice.getPersistentDeviceId()).isNull();
assertThat(virtualDevice.getName()).isNull();
}
@Test
public void parcelable_shouldRecreateSuccessfully() {
VirtualDevice originalDevice =
new VirtualDevice(VIRTUAL_DEVICE_ID, VIRTUAL_DEVICE_NAME);
new VirtualDevice(VIRTUAL_DEVICE_ID, PERSISTENT_ID, DEVICE_NAME);
Parcel parcel = Parcel.obtain();
originalDevice.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
@@ -72,6 +74,7 @@ public class VirtualDeviceTest {
VirtualDevice device = VirtualDevice.CREATOR.createFromParcel(parcel);
assertThat(device).isEqualTo(originalDevice);
assertThat(device.getDeviceId()).isEqualTo(VIRTUAL_DEVICE_ID);
assertThat(device.getName()).isEqualTo(VIRTUAL_DEVICE_NAME);
assertThat(device.getPersistentDeviceId()).isEqualTo(PERSISTENT_ID);
assertThat(device.getName()).isEqualTo(DEVICE_NAME);
}
}