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