1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.companion.virtual; 18 19 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; 20 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA; 21 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_SENSORS; 22 23 import android.annotation.FlaggedApi; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.SystemApi; 27 import android.companion.virtual.flags.Flags; 28 import android.content.Context; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.os.RemoteException; 32 33 /** 34 * Details of a particular virtual device. 35 * 36 * <p>Read-only device representation exposing the properties of an existing virtual device. 37 */ 38 // TODO(b/310912420): Link to VirtualDeviceManager#registerVirtualDeviceListener from the docs 39 public final class VirtualDevice implements Parcelable { 40 41 private final @NonNull IVirtualDevice mVirtualDevice; 42 private final int mId; 43 private final @Nullable String mPersistentId; 44 private final @Nullable String mName; 45 private final @Nullable CharSequence mDisplayName; 46 47 /** 48 * Creates a new instance of {@link VirtualDevice}. 49 * Only to be used by the VirtualDeviceManagerService. 50 * 51 * @hide 52 */ VirtualDevice(@onNull IVirtualDevice virtualDevice, int id, @Nullable String persistentId, @Nullable String name)53 public VirtualDevice(@NonNull IVirtualDevice virtualDevice, int id, 54 @Nullable String persistentId, @Nullable String name) { 55 this(virtualDevice, id, persistentId, name, null); 56 } 57 58 /** 59 * Creates a new instance of {@link VirtualDevice}. Only to be used by the 60 * VirtualDeviceManagerService. 61 * 62 * @hide 63 */ VirtualDevice(@onNull IVirtualDevice virtualDevice, int id, @Nullable String persistentId, @Nullable String name, @Nullable CharSequence displayName)64 public VirtualDevice(@NonNull IVirtualDevice virtualDevice, int id, 65 @Nullable String persistentId, @Nullable String name, 66 @Nullable CharSequence displayName) { 67 if (id <= Context.DEVICE_ID_DEFAULT) { 68 throw new IllegalArgumentException("VirtualDevice ID must be greater than " 69 + Context.DEVICE_ID_DEFAULT); 70 } 71 mVirtualDevice = virtualDevice; 72 mId = id; 73 mPersistentId = persistentId; 74 mName = name; 75 mDisplayName = displayName; 76 } 77 VirtualDevice(@onNull Parcel parcel)78 private VirtualDevice(@NonNull Parcel parcel) { 79 mVirtualDevice = IVirtualDevice.Stub.asInterface(parcel.readStrongBinder()); 80 mId = parcel.readInt(); 81 mPersistentId = parcel.readString8(); 82 mName = parcel.readString8(); 83 mDisplayName = parcel.readCharSequence(); 84 } 85 86 /** 87 * Returns the unique ID of the virtual device. 88 * 89 * <p>This identifier corresponds to {@link Context#getDeviceId()} and can be used to access 90 * device-specific system capabilities. 91 * 92 * <p class="note">This identifier is ephemeral and should not be used for persisting any data 93 * per device. 94 * 95 * @see Context#createDeviceContext 96 */ 97 // TODO(b/310912420): Link to #getPersistentDeviceId from the docs getDeviceId()98 public int getDeviceId() { 99 return mId; 100 } 101 102 /** 103 * Returns the persistent identifier of this virtual device, if any. 104 * 105 * <p> If there is no stable identifier for this virtual device, then this returns {@code null}. 106 107 * <p>This identifier may correspond to a physical device. In that case it remains valid for as 108 * long as that physical device is associated with the host device and may be used to persist 109 * data per device. 110 * 111 * <p class="note">This identifier may not be unique across virtual devices, in case there are 112 * more than one virtual devices corresponding to the same physical device. 113 */ 114 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) getPersistentDeviceId()115 public @Nullable String getPersistentDeviceId() { 116 return mPersistentId; 117 } 118 119 /** 120 * Returns the name of the virtual device (optionally) provided during its creation. 121 */ getName()122 public @Nullable String getName() { 123 return mName; 124 } 125 126 /** 127 * Returns the human-readable name of the virtual device, if defined, which is suitable to be 128 * shown in UI. 129 */ 130 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) getDisplayName()131 public @Nullable CharSequence getDisplayName() { 132 return mDisplayName; 133 } 134 135 /** 136 * Returns the IDs of all virtual displays that belong to this device, if any. 137 * 138 * <p>The actual {@link android.view.Display} objects can be obtained by passing the returned 139 * IDs to {@link android.hardware.display.DisplayManager#getDisplay(int)}.</p> 140 */ 141 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) getDisplayIds()142 public @NonNull int[] getDisplayIds() { 143 try { 144 return mVirtualDevice.getDisplayIds(); 145 } catch (RemoteException e) { 146 throw e.rethrowFromSystemServer(); 147 } 148 } 149 150 /** 151 * Returns whether this device may have custom sensors. 152 * 153 * <p>Returning {@code true} does not necessarily mean that this device has sensors, it only 154 * means that a {@link android.hardware.SensorManager} instance created from a {@link Context} 155 * associated with this device will return this device's sensors, if any.</p> 156 * 157 * @see Context#getDeviceId() 158 * @see Context#createDeviceContext(int) 159 */ 160 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) hasCustomSensorSupport()161 public boolean hasCustomSensorSupport() { 162 try { 163 return mVirtualDevice.getDevicePolicy(POLICY_TYPE_SENSORS) == DEVICE_POLICY_CUSTOM; 164 } catch (RemoteException e) { 165 throw e.rethrowFromSystemServer(); 166 } 167 } 168 169 /** 170 * Returns whether this device may have custom audio input device. 171 * 172 * @hide 173 */ 174 @SystemApi 175 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) hasCustomAudioInputSupport()176 public boolean hasCustomAudioInputSupport() { 177 try { 178 return mVirtualDevice.hasCustomAudioInputSupport(); 179 } catch (RemoteException e) { 180 throw e.rethrowFromSystemServer(); 181 } 182 } 183 184 /** 185 * Returns whether this device may have custom cameras. 186 * 187 * <p>Returning {@code true} does not necessarily mean that this device has cameras, it only 188 * means that a {@link android.hardware.camera2.CameraManager} instance created from a 189 * {@link Context} associated with this device will return this device's cameras, if any.</p> 190 * 191 * @see Context#getDeviceId() 192 * @see Context#createDeviceContext(int) 193 * 194 * @hide 195 */ 196 @SystemApi 197 @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) hasCustomCameraSupport()198 public boolean hasCustomCameraSupport() { 199 try { 200 return mVirtualDevice.getDevicePolicy(POLICY_TYPE_CAMERA) == DEVICE_POLICY_CUSTOM; 201 } catch (RemoteException e) { 202 throw e.rethrowFromSystemServer(); 203 } 204 } 205 206 @Override describeContents()207 public int describeContents() { 208 return 0; 209 } 210 211 @Override writeToParcel(@onNull Parcel dest, int flags)212 public void writeToParcel(@NonNull Parcel dest, int flags) { 213 dest.writeStrongBinder(mVirtualDevice.asBinder()); 214 dest.writeInt(mId); 215 dest.writeString8(mPersistentId); 216 dest.writeString8(mName); 217 dest.writeCharSequence(mDisplayName); 218 } 219 220 @Override 221 @NonNull toString()222 public String toString() { 223 return "VirtualDevice(" 224 + " mId=" + mId 225 + " mPersistentId=" + mPersistentId 226 + " mName=" + mName 227 + " mDisplayName=" + mDisplayName 228 + ")"; 229 } 230 231 @NonNull 232 public static final Parcelable.Creator<VirtualDevice> CREATOR = 233 new Parcelable.Creator<VirtualDevice>() { 234 public VirtualDevice createFromParcel(Parcel in) { 235 return new VirtualDevice(in); 236 } 237 238 public VirtualDevice[] newArray(int size) { 239 return new VirtualDevice[size]; 240 } 241 }; 242 } 243