summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceParams.java23
-rw-r--r--core/java/android/companion/virtual/flags.aconfig7
-rw-r--r--services/companion/java/com/android/server/companion/virtual/CameraAccessController.java13
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java27
5 files changed, 54 insertions, 17 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 02cd00d0f86a..860089fb326f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3579,6 +3579,7 @@ package android.companion.virtual {
field @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public static final int POLICY_TYPE_BLOCKED_ACTIVITY = 6; // 0x6
field @FlaggedApi("android.companion.virtual.flags.virtual_camera") public static final int POLICY_TYPE_CAMERA = 5; // 0x5
field @FlaggedApi("android.companion.virtual.flags.cross_device_clipboard") public static final int POLICY_TYPE_CLIPBOARD = 4; // 0x4
+ field @FlaggedApi("android.companion.virtualdevice.flags.default_device_camera_access_policy") public static final int POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS = 7; // 0x7
field public static final int POLICY_TYPE_RECENTS = 2; // 0x2
field public static final int POLICY_TYPE_SENSORS = 0; // 0x0
}
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index 65f9cbefb052..6dad015cd63b 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -160,7 +160,7 @@ public final class VirtualDeviceParams implements Parcelable {
*/
@IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO,
POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CLIPBOARD, POLICY_TYPE_CAMERA,
- POLICY_TYPE_BLOCKED_ACTIVITY})
+ POLICY_TYPE_BLOCKED_ACTIVITY, POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface PolicyType {}
@@ -301,6 +301,21 @@ public final class VirtualDeviceParams implements Parcelable {
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
public static final int POLICY_TYPE_BLOCKED_ACTIVITY = 6;
+ /**
+ * Tells the virtual device framework how to handle camera access of the default device by apps
+ * running on the virtual device.
+ *
+ * <ul>
+ * <li>{@link #DEVICE_POLICY_DEFAULT}: Default device camera access will be allowed.
+ * <li>{@link #DEVICE_POLICY_CUSTOM}: Default device camera access will be blocked.
+ * </ul>
+ *
+ * @see Context#DEVICE_ID_DEFAULT
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags
+ .FLAG_DEFAULT_DEVICE_CAMERA_ACCESS_POLICY)
+ public static final int POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS = 7;
+
private final int mLockState;
@NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
@NavigationPolicy
@@ -696,7 +711,7 @@ public final class VirtualDeviceParams implements Parcelable {
@NonNull
public static final Parcelable.Creator<VirtualDeviceParams> CREATOR =
- new Parcelable.Creator<VirtualDeviceParams>() {
+ new Parcelable.Creator<>() {
public VirtualDeviceParams createFromParcel(Parcel in) {
return new VirtualDeviceParams(in);
}
@@ -1213,6 +1228,10 @@ public final class VirtualDeviceParams implements Parcelable {
mDevicePolicies.delete(POLICY_TYPE_CAMERA);
}
+ if (!android.companion.virtualdevice.flags.Flags.defaultDeviceCameraAccessPolicy()) {
+ mDevicePolicies.delete(POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS);
+ }
+
if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
mDevicePolicies.delete(POLICY_TYPE_BLOCKED_ACTIVITY);
}
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index fc9c94dd5b0f..3e6919bac5fa 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -67,13 +67,6 @@ flag {
}
flag {
- name: "stream_camera"
- namespace: "virtual_devices"
- description: "Enable streaming camera to Virtual Devices"
- bug: "291740640"
-}
-
-flag {
name: "persistent_device_id_api"
is_exported: true
namespace: "virtual_devices"
diff --git a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
index ef39846f4750..8a4b1faf2df9 100644
--- a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
+++ b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
@@ -59,14 +59,14 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
private int mObserverCount = 0;
@GuardedBy("mLock")
- private ArrayMap<String, InjectionSessionData> mPackageToSessionData = new ArrayMap<>();
+ private final ArrayMap<String, InjectionSessionData> mPackageToSessionData = new ArrayMap<>();
/**
* Mapping from camera ID to open camera app associations. Key is the camera id, value is the
* information of the app's uid and package name.
*/
@GuardedBy("mLock")
- private ArrayMap<String, OpenCameraInfo> mAppsToBlockOnVirtualDevice = new ArrayMap<>();
+ private final ArrayMap<String, OpenCameraInfo> mAppsToBlockOnVirtualDevice = new ArrayMap<>();
static class InjectionSessionData {
public int appUid;
@@ -179,6 +179,15 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
Slog.w(TAG, "Unexpected close with observers remaining: " + mObserverCount);
}
}
+ // Clean up camera injection sessions (if any).
+ synchronized (mLock) {
+ for (InjectionSessionData sessionData : mPackageToSessionData.values()) {
+ for (CameraInjectionSession session : sessionData.cameraIdToSession.values()) {
+ session.close();
+ }
+ }
+ mPackageToSessionData.clear();
+ }
mCameraManager.unregisterAvailabilityCallback(this);
}
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 f87e3c338df7..604aaa74306f 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.companion.virtual;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
+import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS;
import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE;
import static com.android.server.wm.ActivityInterceptorCallback.VIRTUAL_DEVICE_SERVICE_ORDERED_ID;
@@ -27,6 +28,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
+import android.app.compat.CompatChanges;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
@@ -41,11 +43,14 @@ import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
import android.companion.virtualnative.IVirtualDeviceManagerNative;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManagerInternal;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
@@ -88,7 +93,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
-
@SuppressLint("LongLogTag")
public class VirtualDeviceManagerService extends SystemService {
@@ -101,6 +105,11 @@ public class VirtualDeviceManagerService extends SystemService {
AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING);
+ /** Enable default device camera access for apps running on virtual devices. */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ public static final long ENABLE_DEFAULT_DEVICE_CAMERA_ACCESS = 371173368L;
+
/**
* A virtual device association id corresponding to no CDM association.
*/
@@ -110,7 +119,7 @@ public class VirtualDeviceManagerService extends SystemService {
private final VirtualDeviceManagerImpl mImpl;
private final VirtualDeviceManagerNativeImpl mNativeImpl;
private final VirtualDeviceManagerInternal mLocalService;
- private VirtualDeviceLog mVirtualDeviceLog = new VirtualDeviceLog(getContext());
+ private final VirtualDeviceLog mVirtualDeviceLog = new VirtualDeviceLog(getContext());
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final PendingTrampolineMap mPendingTrampolines = new PendingTrampolineMap(mHandler);
@@ -236,7 +245,7 @@ public class VirtualDeviceManagerService extends SystemService {
}
}
- void onCameraAccessBlocked(int appUid) {
+ private void onCameraAccessBlocked(int appUid) {
ArrayList<VirtualDeviceImpl> virtualDevicesSnapshot = getVirtualDevicesSnapshot();
for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
VirtualDeviceImpl virtualDevice = virtualDevicesSnapshot.get(i);
@@ -248,8 +257,13 @@ public class VirtualDeviceManagerService extends SystemService {
}
}
- CameraAccessController getCameraAccessController(UserHandle userHandle) {
- if (Flags.streamCamera()) {
+ private CameraAccessController getCameraAccessController(UserHandle userHandle,
+ VirtualDeviceParams params, String callingPackage) {
+ if (CompatChanges.isChangeEnabled(ENABLE_DEFAULT_DEVICE_CAMERA_ACCESS, callingPackage,
+ userHandle)
+ && android.companion.virtualdevice.flags.Flags.defaultDeviceCameraAccessPolicy()
+ && (params.getDevicePolicy(POLICY_TYPE_DEFAULT_DEVICE_CAMERA_ACCESS)
+ == DEVICE_POLICY_DEFAULT)) {
return null;
}
int userId = userHandle.getIdentifier();
@@ -496,7 +510,8 @@ public class VirtualDeviceManagerService extends SystemService {
final UserHandle userHandle = getCallingUserHandle();
final CameraAccessController cameraAccessController =
- getCameraAccessController(userHandle);
+ getCameraAccessController(userHandle, params,
+ attributionSource.getPackageName());
final int deviceId = sNextUniqueIndex.getAndIncrement();
final Consumer<ArraySet<Integer>> runningAppsChangedCallback =
runningUids -> notifyRunningAppsChanged(deviceId, runningUids);