Loading core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3253,6 +3253,7 @@ package android.companion.virtual { field @Deprecated public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1 field @FlaggedApi("android.companion.virtual.flags.dynamic_policy") public static final int POLICY_TYPE_ACTIVITY = 3; // 0x3 field public static final int POLICY_TYPE_AUDIO = 1; // 0x1 field @FlaggedApi("android.companion.virtual.flags.cross_device_clipboard") public static final int POLICY_TYPE_CLIPBOARD = 4; // 0x4 field public static final int POLICY_TYPE_RECENTS = 2; // 0x2 field public static final int POLICY_TYPE_SENSORS = 0; // 0x0 } core/java/android/companion/virtual/VirtualDeviceParams.java +20 −1 Original line number Diff line number Diff line Loading @@ -169,7 +169,8 @@ public final class VirtualDeviceParams implements Parcelable { * @see VirtualDeviceManager.VirtualDevice#setDevicePolicy * @hide */ @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY}) @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CLIPBOARD}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface DynamicPolicyType {} Loading Loading @@ -230,6 +231,20 @@ public final class VirtualDeviceParams implements Parcelable { @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY) public static final int POLICY_TYPE_ACTIVITY = 3; /** * Tells the clipboard manager whether this device's clipboard should be shared or not. * * <ul> * <li>{@link #DEVICE_POLICY_DEFAULT}: By default the device's clipboard is its own and is * not shared with other devices' clipboards, including the clipboard of the default device. * <li>{@link #DEVICE_POLICY_CUSTOM}: The device's clipboard is shared with the default * device's clipboard. Any clipboard operation on the virtual device is as if it was done on * the default device. * </ul> */ @FlaggedApi(Flags.FLAG_CROSS_DEVICE_CLIPBOARD) public static final int POLICY_TYPE_CLIPBOARD = 4; private final int mLockState; @NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts; @NavigationPolicy Loading Loading @@ -1086,6 +1101,10 @@ public final class VirtualDeviceParams implements Parcelable { } } if (!Flags.crossDeviceClipboard()) { mDevicePolicies.delete(POLICY_TYPE_CLIPBOARD); } if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE || mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE) && mDevicePolicies.get(POLICY_TYPE_AUDIO, DEVICE_POLICY_DEFAULT) Loading core/java/android/companion/virtual/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,13 @@ flag { bug: "298401780" } flag { name: "cross_device_clipboard" namespace: "virtual_devices" description: "Enable cross-device clipboard API" bug: "306622082" } flag { name: "vdm_custom_home" namespace: "virtual_devices" Loading services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +8 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.companion.virtual.VirtualDeviceParams.ACTIVITY_POLICY_DEFA import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -665,6 +666,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } break; case POLICY_TYPE_CLIPBOARD: if (Flags.crossDeviceClipboard()) { synchronized (mVirtualDeviceLock) { mDevicePolicies.put(policyType, devicePolicy); } } break; default: throw new IllegalArgumentException("Device policy " + policyType + " cannot be changed at runtime. "); Loading services/core/java/com/android/server/clipboard/ClipboardService.java +37 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.clipboard; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.content.Context.DEVICE_ID_INVALID; Loading Loading @@ -409,7 +411,7 @@ public class ClipboardService extends SystemService { /** * Determines which deviceId to use for selecting a Clipboard, depending on where a given app * is running. * is running and the device's clipboard policy. * * @param requestedDeviceId the requested deviceId passed in from the client side * @param uid the intended app uid Loading @@ -431,28 +433,47 @@ public class ClipboardService extends SystemService { } } if (requestedDeviceId != DEVICE_ID_DEFAULT) { // Privileged apps that own the VirtualDevices, or regular apps running on it, can // request it by id. if (mVdmInternal.getDeviceOwnerUid(requestedDeviceId) == uid || virtualDeviceIds.contains(requestedDeviceId)) { return requestedDeviceId; // If an app is running on any VirtualDevice, it isn't clear which clipboard they // should use, unless all of the devices share the default device's clipboard. boolean allDevicesHaveDefaultClipboard = true; for (int deviceId : virtualDeviceIds) { if (!deviceUsesDefaultClipboard(deviceId)) { allDevicesHaveDefaultClipboard = false; break; } return DEVICE_ID_INVALID; } // The common case is apps running normally (not on a VirtualDevice). if (virtualDeviceIds.isEmpty()) { return DEVICE_ID_DEFAULT; // Apps running on a virtual device may get the default clipboard if all the devices the app // runs on share that clipboard. Otherwise it's not clear which clipboard to use. if (requestedDeviceId == DEVICE_ID_DEFAULT) { return allDevicesHaveDefaultClipboard ? DEVICE_ID_DEFAULT : DEVICE_ID_INVALID; } // If an app is running on more than one VirtualDevice, it isn't clear which clipboard they // should use. if (virtualDeviceIds.size() > 1) { return DEVICE_ID_INVALID; // At this point the app wants to access a virtual device clipboard. It may do so if: // 1. The app owns the VirtualDevice // 2. The app is present on the VirtualDevice // 3. The VirtualDevice shares the default device clipboard and all virtual devices that // the app is running on do the same. int clipboardDeviceId = deviceUsesDefaultClipboard(requestedDeviceId) ? DEVICE_ID_DEFAULT : requestedDeviceId; if (mVdmInternal.getDeviceOwnerUid(requestedDeviceId) == uid || virtualDeviceIds.contains(requestedDeviceId) || (clipboardDeviceId == DEVICE_ID_DEFAULT && allDevicesHaveDefaultClipboard)) { return clipboardDeviceId; } // Fallback to the device where the app is running, unless it uses the default clipboard. int fallbackDeviceId = virtualDeviceIds.valueAt(0); return deviceUsesDefaultClipboard(fallbackDeviceId) ? DEVICE_ID_DEFAULT : fallbackDeviceId; } return virtualDeviceIds.valueAt(0); private boolean deviceUsesDefaultClipboard(int deviceId) { if (deviceId == DEVICE_ID_DEFAULT || mVdm == null) { return true; } return mVdm.getDevicePolicy(deviceId, POLICY_TYPE_CLIPBOARD) == DEVICE_POLICY_CUSTOM; } /** Loading Loading
core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3253,6 +3253,7 @@ package android.companion.virtual { field @Deprecated public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1 field @FlaggedApi("android.companion.virtual.flags.dynamic_policy") public static final int POLICY_TYPE_ACTIVITY = 3; // 0x3 field public static final int POLICY_TYPE_AUDIO = 1; // 0x1 field @FlaggedApi("android.companion.virtual.flags.cross_device_clipboard") public static final int POLICY_TYPE_CLIPBOARD = 4; // 0x4 field public static final int POLICY_TYPE_RECENTS = 2; // 0x2 field public static final int POLICY_TYPE_SENSORS = 0; // 0x0 }
core/java/android/companion/virtual/VirtualDeviceParams.java +20 −1 Original line number Diff line number Diff line Loading @@ -169,7 +169,8 @@ public final class VirtualDeviceParams implements Parcelable { * @see VirtualDeviceManager.VirtualDevice#setDevicePolicy * @hide */ @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY}) @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CLIPBOARD}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface DynamicPolicyType {} Loading Loading @@ -230,6 +231,20 @@ public final class VirtualDeviceParams implements Parcelable { @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY) public static final int POLICY_TYPE_ACTIVITY = 3; /** * Tells the clipboard manager whether this device's clipboard should be shared or not. * * <ul> * <li>{@link #DEVICE_POLICY_DEFAULT}: By default the device's clipboard is its own and is * not shared with other devices' clipboards, including the clipboard of the default device. * <li>{@link #DEVICE_POLICY_CUSTOM}: The device's clipboard is shared with the default * device's clipboard. Any clipboard operation on the virtual device is as if it was done on * the default device. * </ul> */ @FlaggedApi(Flags.FLAG_CROSS_DEVICE_CLIPBOARD) public static final int POLICY_TYPE_CLIPBOARD = 4; private final int mLockState; @NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts; @NavigationPolicy Loading Loading @@ -1086,6 +1101,10 @@ public final class VirtualDeviceParams implements Parcelable { } } if (!Flags.crossDeviceClipboard()) { mDevicePolicies.delete(POLICY_TYPE_CLIPBOARD); } if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE || mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE) && mDevicePolicies.get(POLICY_TYPE_AUDIO, DEVICE_POLICY_DEFAULT) Loading
core/java/android/companion/virtual/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,13 @@ flag { bug: "298401780" } flag { name: "cross_device_clipboard" namespace: "virtual_devices" description: "Enable cross-device clipboard API" bug: "306622082" } flag { name: "vdm_custom_home" namespace: "virtual_devices" Loading
services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +8 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.companion.virtual.VirtualDeviceParams.ACTIVITY_POLICY_DEFA import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -665,6 +666,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } break; case POLICY_TYPE_CLIPBOARD: if (Flags.crossDeviceClipboard()) { synchronized (mVirtualDeviceLock) { mDevicePolicies.put(policyType, devicePolicy); } } break; default: throw new IllegalArgumentException("Device policy " + policyType + " cannot be changed at runtime. "); Loading
services/core/java/com/android/server/clipboard/ClipboardService.java +37 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.clipboard; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.content.Context.DEVICE_ID_INVALID; Loading Loading @@ -409,7 +411,7 @@ public class ClipboardService extends SystemService { /** * Determines which deviceId to use for selecting a Clipboard, depending on where a given app * is running. * is running and the device's clipboard policy. * * @param requestedDeviceId the requested deviceId passed in from the client side * @param uid the intended app uid Loading @@ -431,28 +433,47 @@ public class ClipboardService extends SystemService { } } if (requestedDeviceId != DEVICE_ID_DEFAULT) { // Privileged apps that own the VirtualDevices, or regular apps running on it, can // request it by id. if (mVdmInternal.getDeviceOwnerUid(requestedDeviceId) == uid || virtualDeviceIds.contains(requestedDeviceId)) { return requestedDeviceId; // If an app is running on any VirtualDevice, it isn't clear which clipboard they // should use, unless all of the devices share the default device's clipboard. boolean allDevicesHaveDefaultClipboard = true; for (int deviceId : virtualDeviceIds) { if (!deviceUsesDefaultClipboard(deviceId)) { allDevicesHaveDefaultClipboard = false; break; } return DEVICE_ID_INVALID; } // The common case is apps running normally (not on a VirtualDevice). if (virtualDeviceIds.isEmpty()) { return DEVICE_ID_DEFAULT; // Apps running on a virtual device may get the default clipboard if all the devices the app // runs on share that clipboard. Otherwise it's not clear which clipboard to use. if (requestedDeviceId == DEVICE_ID_DEFAULT) { return allDevicesHaveDefaultClipboard ? DEVICE_ID_DEFAULT : DEVICE_ID_INVALID; } // If an app is running on more than one VirtualDevice, it isn't clear which clipboard they // should use. if (virtualDeviceIds.size() > 1) { return DEVICE_ID_INVALID; // At this point the app wants to access a virtual device clipboard. It may do so if: // 1. The app owns the VirtualDevice // 2. The app is present on the VirtualDevice // 3. The VirtualDevice shares the default device clipboard and all virtual devices that // the app is running on do the same. int clipboardDeviceId = deviceUsesDefaultClipboard(requestedDeviceId) ? DEVICE_ID_DEFAULT : requestedDeviceId; if (mVdmInternal.getDeviceOwnerUid(requestedDeviceId) == uid || virtualDeviceIds.contains(requestedDeviceId) || (clipboardDeviceId == DEVICE_ID_DEFAULT && allDevicesHaveDefaultClipboard)) { return clipboardDeviceId; } // Fallback to the device where the app is running, unless it uses the default clipboard. int fallbackDeviceId = virtualDeviceIds.valueAt(0); return deviceUsesDefaultClipboard(fallbackDeviceId) ? DEVICE_ID_DEFAULT : fallbackDeviceId; } return virtualDeviceIds.valueAt(0); private boolean deviceUsesDefaultClipboard(int deviceId) { if (deviceId == DEVICE_ID_DEFAULT || mVdm == null) { return true; } return mVdm.getDevicePolicy(deviceId, POLICY_TYPE_CLIPBOARD) == DEVICE_POLICY_CUSTOM; } /** Loading