Loading core/java/android/companion/virtual/VirtualDeviceManager.java +3 −0 Original line number Diff line number Diff line Loading @@ -1135,8 +1135,11 @@ public final class VirtualDeviceManager { /** * Sets the visibility of the pointer icon for this VirtualDevice's associated displays. * * <p>Only applicable to trusted displays.</p> * * @param showPointerIcon True if the pointer should be shown; false otherwise. The default * visibility is true. * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean showPointerIcon) { Loading core/java/android/companion/virtual/VirtualDeviceParams.java +14 −6 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public final class VirtualDeviceParams implements Parcelable { * @hide */ @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO, POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CAMERA, POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CLIPBOARD, POLICY_TYPE_CAMERA, POLICY_TYPE_BLOCKED_ACTIVITY}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) Loading Loading @@ -220,11 +220,16 @@ public final class VirtualDeviceParams implements Parcelable { * Tells the activity manager how to handle recents entries for activities run on this device. * * <ul> * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on VirtualDisplays owned by this * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on trusted displays owned by this * device will appear in the host device recents. * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on VirtualDisplays owned by this * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on trusted displays owned by this * device will not appear in recents. * </ul> * * <p>Activities launched on untrusted displays will always show in the host device recents, * regardless of the policy.</p> * * @see android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED */ public static final int POLICY_TYPE_RECENTS = 2; Loading Loading @@ -254,8 +259,10 @@ public final class VirtualDeviceParams implements Parcelable { * 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. * the default device. Requires all displays of the virtual device to be trusted. * </ul> * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED */ @FlaggedApi(Flags.FLAG_CROSS_DEVICE_CLIPBOARD) public static final int POLICY_TYPE_CLIPBOARD = 4; Loading Loading @@ -821,8 +828,8 @@ public final class VirtualDeviceParams implements Parcelable { } /** * Specifies a component to be used as input method on all displays owned by this virtual * device. * Specifies a component to be used as input method on all trusted displays owned by this * virtual device. * * @param inputMethodComponent The component name to be used as input method. Must comply to * all general input method requirements described in the guide to Loading @@ -831,6 +838,7 @@ public final class VirtualDeviceParams implements Parcelable { * may interact with the virtual device, then there will effectively be no IME on this * device's displays for that user. * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED * @see android.inputmethodservice.InputMethodService * @attr ref android.R.styleable#InputMethod_isVirtualDeviceOnly * @attr ref android.R.styleable#InputMethod_showInInputMethodPicker Loading core/java/android/hardware/input/VirtualInputDeviceConfig.java +4 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,6 @@ public abstract class VirtualInputDeviceConfig { return self(); } /** * Sets the product id of the device, uniquely identifying the device within the address * space of a given vendor, identified by the device's vendor id. Loading @@ -179,6 +178,10 @@ public abstract class VirtualInputDeviceConfig { * * <p>The input device is restricted to the display with the given ID and may not send * events to any other display.</p> * <p>The corresponding display must be trusted or mirror display.</p> * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR */ @NonNull public T setAssociatedDisplayId(int displayId) { Loading services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +78 −22 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.server.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_ENABLED; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY; import static android.companion.virtual.VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; 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; Loading Loading @@ -425,6 +428,27 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mDisplayManager = displayManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mPowerManager = context.getSystemService(PowerManager.class); if (mDevicePolicies.get(POLICY_TYPE_CLIPBOARD, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_DEFAULT) { if (mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "set a custom clipboard policy."); } } int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { if (mContext.checkCallingOrSelfPermission(ADD_ALWAYS_UNLOCKED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_ALWAYS_UNLOCKED_DISPLAY permission to " + "create an always unlocked virtual device."); } flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; } mBaseVirtualDisplayFlags = flags; if (inputController == null) { mInputController = new InputController( context.getMainThreadHandler(), Loading Loading @@ -467,12 +491,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub : mParams.getAllowedActivities(); } int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; } mBaseVirtualDisplayFlags = flags; if (Flags.vdmCustomIme() && mParams.getInputMethodComponent() != null) { final String imeId = mParams.getInputMethodComponent().flattenToShortString(); Slog.d(TAG, "Setting custom input method " + imeId + " as default for virtual device " Loading Loading @@ -884,8 +902,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub synchronized (mVirtualDeviceLock) { mDevicePolicies.put(policyType, devicePolicy); for (int i = 0; i < mVirtualDisplays.size(); i++) { mVirtualDisplays.valueAt(i).getWindowPolicyController() .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (wrapper.isTrusted()) { wrapper.getWindowPolicyController() .setShowInHostDeviceRecents( devicePolicy == DEVICE_POLICY_DEFAULT); } } } break; Loading @@ -905,7 +927,20 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub break; case POLICY_TYPE_CLIPBOARD: if (Flags.crossDeviceClipboard()) { if (policyType == DEVICE_POLICY_CUSTOM && mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "set a custom clipboard policy."); } synchronized (mVirtualDeviceLock) { for (int i = 0; i < mVirtualDisplays.size(); i++) { VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (!wrapper.isTrusted() && !wrapper.isMirror()) { throw new SecurityException("All displays must be trusted for " + "devices with custom clipboard policy."); } } mDevicePolicies.put(policyType, devicePolicy); } } Loading Loading @@ -936,8 +971,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub checkDisplayOwnedByVirtualDeviceLocked(displayId); switch (policyType) { case POLICY_TYPE_RECENTS: mVirtualDisplays.get(displayId).getWindowPolicyController() VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); if (wrapper.isTrusted()) { wrapper.getWindowPolicyController() .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); } break; case POLICY_TYPE_ACTIVITY: mVirtualDisplays.get(displayId).getWindowPolicyController() Loading Loading @@ -1247,10 +1285,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub try { synchronized (mVirtualDeviceLock) { mDefaultShowPointerIcon = showPointerIcon; for (int i = 0; i < mVirtualDisplays.size(); i++) { VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (wrapper.isTrusted() || wrapper.isMirror()) { mInputController.setShowPointerIcon( mDefaultShowPointerIcon, mVirtualDisplays.keyAt(i)); } } final int[] displayIds = getDisplayIds(); for (int i = 0; i < displayIds.length; ++i) { mInputController.setShowPointerIcon(showPointerIcon, displayIds[i]); } } finally { Binder.restoreCallingIdentity(ident); Loading Loading @@ -1491,6 +1532,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub boolean isTrustedDisplay = (mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED) == Display.FLAG_TRUSTED; if (!isTrustedDisplay) { if (getDevicePolicy(POLICY_TYPE_CLIPBOARD) != DEVICE_POLICY_DEFAULT) { throw new SecurityException("All displays must be trusted for devices with custom" + "clipboard policy."); } } boolean showPointer; synchronized (mVirtualDeviceLock) { Loading @@ -1500,7 +1547,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub "Virtual device already has a virtual display with ID " + displayId); } PowerManager.WakeLock wakeLock = createAndAcquireWakeLockForDisplay(displayId); PowerManager.WakeLock wakeLock = isTrustedDisplay ? createAndAcquireWakeLockForDisplay(displayId) : null; mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock, isTrustedDisplay, isMirrorDisplay)); showPointer = mDefaultShowPointerIcon; Loading @@ -1508,14 +1556,15 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub final long token = Binder.clearCallingIdentity(); try { mInputController.setShowPointerIcon(showPointer, displayId); mInputController.setMousePointerAccelerationEnabled(false, displayId); mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false, displayId); // WM throws a SecurityException if the display is untrusted. if (isTrustedDisplay) { mInputController.setShowPointerIcon(showPointer, displayId); mInputController.setDisplayImePolicy(displayId, WindowManager.DISPLAY_IME_POLICY_LOCAL); } else { gwpc.setShowInHostDeviceRecents(true); } } finally { Binder.restoreCallingIdentity(token); Loading Loading @@ -1616,6 +1665,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub != PackageManager.PERMISSION_GRANTED) { synchronized (mVirtualDeviceLock) { checkDisplayOwnedByVirtualDeviceLocked(displayId); VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); if (!wrapper.isTrusted() && !wrapper.isMirror()) { throw new SecurityException( "Cannot create input device associated with an untrusted display"); } } } } Loading Loading @@ -1665,7 +1719,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub * @param virtualDisplayWrapper - VirtualDisplayWrapper to release resources for. */ private void releaseOwnedVirtualDisplayResources(VirtualDisplayWrapper virtualDisplayWrapper) { virtualDisplayWrapper.getWakeLock().release(); virtualDisplayWrapper.releaseWakeLock(); virtualDisplayWrapper.getWindowPolicyController().unregisterRunningAppsChangedListener( this); } Loading Loading @@ -1833,10 +1887,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub VirtualDisplayWrapper(@NonNull IVirtualDisplayCallback token, @NonNull GenericWindowPolicyController windowPolicyController, @NonNull PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { @Nullable PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { mToken = Objects.requireNonNull(token); mWindowPolicyController = Objects.requireNonNull(windowPolicyController); mWakeLock = Objects.requireNonNull(wakeLock); mWakeLock = wakeLock; mIsTrusted = isTrusted; mIsMirror = isMirror; } Loading @@ -1845,8 +1899,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return mWindowPolicyController; } PowerManager.WakeLock getWakeLock() { return mWakeLock; void releaseWakeLock() { if (mWakeLock != null && mWakeLock.isHeld()) { mWakeLock.release(); } } boolean isTrusted() { Loading services/core/java/com/android/server/display/DisplayManagerService.java +4 −5 Original line number Diff line number Diff line Loading @@ -1769,10 +1769,11 @@ public final class DisplayManagerService extends SystemService { flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; } // Put the display in the virtual device's display group only if it's not a mirror display, // and if it doesn't need its own display group. So effectively, mirror displays go into the // default display group. // it is a trusted display, and it doesn't need its own display group. So effectively, // mirror and untrusted displays go into the default display group. if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) == 0 && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0 && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == VIRTUAL_DISPLAY_FLAG_TRUSTED && virtualDevice != null) { flags |= VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP; } Loading Loading @@ -1848,9 +1849,7 @@ public final class DisplayManagerService extends SystemService { if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { // The virtualDevice instance has been validated above using isValidVirtualDevice if (virtualDevice == null && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "create a virtual display which is not in the default DisplayGroup."); } Loading Loading
core/java/android/companion/virtual/VirtualDeviceManager.java +3 −0 Original line number Diff line number Diff line Loading @@ -1135,8 +1135,11 @@ public final class VirtualDeviceManager { /** * Sets the visibility of the pointer icon for this VirtualDevice's associated displays. * * <p>Only applicable to trusted displays.</p> * * @param showPointerIcon True if the pointer should be shown; false otherwise. The default * visibility is true. * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean showPointerIcon) { Loading
core/java/android/companion/virtual/VirtualDeviceParams.java +14 −6 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public final class VirtualDeviceParams implements Parcelable { * @hide */ @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO, POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CAMERA, POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY, POLICY_TYPE_CLIPBOARD, POLICY_TYPE_CAMERA, POLICY_TYPE_BLOCKED_ACTIVITY}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) Loading Loading @@ -220,11 +220,16 @@ public final class VirtualDeviceParams implements Parcelable { * Tells the activity manager how to handle recents entries for activities run on this device. * * <ul> * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on VirtualDisplays owned by this * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on trusted displays owned by this * device will appear in the host device recents. * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on VirtualDisplays owned by this * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on trusted displays owned by this * device will not appear in recents. * </ul> * * <p>Activities launched on untrusted displays will always show in the host device recents, * regardless of the policy.</p> * * @see android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED */ public static final int POLICY_TYPE_RECENTS = 2; Loading Loading @@ -254,8 +259,10 @@ public final class VirtualDeviceParams implements Parcelable { * 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. * the default device. Requires all displays of the virtual device to be trusted. * </ul> * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED */ @FlaggedApi(Flags.FLAG_CROSS_DEVICE_CLIPBOARD) public static final int POLICY_TYPE_CLIPBOARD = 4; Loading Loading @@ -821,8 +828,8 @@ public final class VirtualDeviceParams implements Parcelable { } /** * Specifies a component to be used as input method on all displays owned by this virtual * device. * Specifies a component to be used as input method on all trusted displays owned by this * virtual device. * * @param inputMethodComponent The component name to be used as input method. Must comply to * all general input method requirements described in the guide to Loading @@ -831,6 +838,7 @@ public final class VirtualDeviceParams implements Parcelable { * may interact with the virtual device, then there will effectively be no IME on this * device's displays for that user. * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED * @see android.inputmethodservice.InputMethodService * @attr ref android.R.styleable#InputMethod_isVirtualDeviceOnly * @attr ref android.R.styleable#InputMethod_showInInputMethodPicker Loading
core/java/android/hardware/input/VirtualInputDeviceConfig.java +4 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,6 @@ public abstract class VirtualInputDeviceConfig { return self(); } /** * Sets the product id of the device, uniquely identifying the device within the address * space of a given vendor, identified by the device's vendor id. Loading @@ -179,6 +178,10 @@ public abstract class VirtualInputDeviceConfig { * * <p>The input device is restricted to the display with the given ID and may not send * events to any other display.</p> * <p>The corresponding display must be trusted or mirror display.</p> * * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR */ @NonNull public T setAssociatedDisplayId(int displayId) { Loading
services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +78 −22 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.server.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_ENABLED; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY; import static android.companion.virtual.VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; 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; Loading Loading @@ -425,6 +428,27 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mDisplayManager = displayManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mPowerManager = context.getSystemService(PowerManager.class); if (mDevicePolicies.get(POLICY_TYPE_CLIPBOARD, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_DEFAULT) { if (mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "set a custom clipboard policy."); } } int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { if (mContext.checkCallingOrSelfPermission(ADD_ALWAYS_UNLOCKED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_ALWAYS_UNLOCKED_DISPLAY permission to " + "create an always unlocked virtual device."); } flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; } mBaseVirtualDisplayFlags = flags; if (inputController == null) { mInputController = new InputController( context.getMainThreadHandler(), Loading Loading @@ -467,12 +491,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub : mParams.getAllowedActivities(); } int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; } mBaseVirtualDisplayFlags = flags; if (Flags.vdmCustomIme() && mParams.getInputMethodComponent() != null) { final String imeId = mParams.getInputMethodComponent().flattenToShortString(); Slog.d(TAG, "Setting custom input method " + imeId + " as default for virtual device " Loading Loading @@ -884,8 +902,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub synchronized (mVirtualDeviceLock) { mDevicePolicies.put(policyType, devicePolicy); for (int i = 0; i < mVirtualDisplays.size(); i++) { mVirtualDisplays.valueAt(i).getWindowPolicyController() .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (wrapper.isTrusted()) { wrapper.getWindowPolicyController() .setShowInHostDeviceRecents( devicePolicy == DEVICE_POLICY_DEFAULT); } } } break; Loading @@ -905,7 +927,20 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub break; case POLICY_TYPE_CLIPBOARD: if (Flags.crossDeviceClipboard()) { if (policyType == DEVICE_POLICY_CUSTOM && mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "set a custom clipboard policy."); } synchronized (mVirtualDeviceLock) { for (int i = 0; i < mVirtualDisplays.size(); i++) { VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (!wrapper.isTrusted() && !wrapper.isMirror()) { throw new SecurityException("All displays must be trusted for " + "devices with custom clipboard policy."); } } mDevicePolicies.put(policyType, devicePolicy); } } Loading Loading @@ -936,8 +971,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub checkDisplayOwnedByVirtualDeviceLocked(displayId); switch (policyType) { case POLICY_TYPE_RECENTS: mVirtualDisplays.get(displayId).getWindowPolicyController() VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); if (wrapper.isTrusted()) { wrapper.getWindowPolicyController() .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); } break; case POLICY_TYPE_ACTIVITY: mVirtualDisplays.get(displayId).getWindowPolicyController() Loading Loading @@ -1247,10 +1285,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub try { synchronized (mVirtualDeviceLock) { mDefaultShowPointerIcon = showPointerIcon; for (int i = 0; i < mVirtualDisplays.size(); i++) { VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); if (wrapper.isTrusted() || wrapper.isMirror()) { mInputController.setShowPointerIcon( mDefaultShowPointerIcon, mVirtualDisplays.keyAt(i)); } } final int[] displayIds = getDisplayIds(); for (int i = 0; i < displayIds.length; ++i) { mInputController.setShowPointerIcon(showPointerIcon, displayIds[i]); } } finally { Binder.restoreCallingIdentity(ident); Loading Loading @@ -1491,6 +1532,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub boolean isTrustedDisplay = (mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED) == Display.FLAG_TRUSTED; if (!isTrustedDisplay) { if (getDevicePolicy(POLICY_TYPE_CLIPBOARD) != DEVICE_POLICY_DEFAULT) { throw new SecurityException("All displays must be trusted for devices with custom" + "clipboard policy."); } } boolean showPointer; synchronized (mVirtualDeviceLock) { Loading @@ -1500,7 +1547,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub "Virtual device already has a virtual display with ID " + displayId); } PowerManager.WakeLock wakeLock = createAndAcquireWakeLockForDisplay(displayId); PowerManager.WakeLock wakeLock = isTrustedDisplay ? createAndAcquireWakeLockForDisplay(displayId) : null; mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock, isTrustedDisplay, isMirrorDisplay)); showPointer = mDefaultShowPointerIcon; Loading @@ -1508,14 +1556,15 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub final long token = Binder.clearCallingIdentity(); try { mInputController.setShowPointerIcon(showPointer, displayId); mInputController.setMousePointerAccelerationEnabled(false, displayId); mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false, displayId); // WM throws a SecurityException if the display is untrusted. if (isTrustedDisplay) { mInputController.setShowPointerIcon(showPointer, displayId); mInputController.setDisplayImePolicy(displayId, WindowManager.DISPLAY_IME_POLICY_LOCAL); } else { gwpc.setShowInHostDeviceRecents(true); } } finally { Binder.restoreCallingIdentity(token); Loading Loading @@ -1616,6 +1665,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub != PackageManager.PERMISSION_GRANTED) { synchronized (mVirtualDeviceLock) { checkDisplayOwnedByVirtualDeviceLocked(displayId); VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); if (!wrapper.isTrusted() && !wrapper.isMirror()) { throw new SecurityException( "Cannot create input device associated with an untrusted display"); } } } } Loading Loading @@ -1665,7 +1719,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub * @param virtualDisplayWrapper - VirtualDisplayWrapper to release resources for. */ private void releaseOwnedVirtualDisplayResources(VirtualDisplayWrapper virtualDisplayWrapper) { virtualDisplayWrapper.getWakeLock().release(); virtualDisplayWrapper.releaseWakeLock(); virtualDisplayWrapper.getWindowPolicyController().unregisterRunningAppsChangedListener( this); } Loading Loading @@ -1833,10 +1887,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub VirtualDisplayWrapper(@NonNull IVirtualDisplayCallback token, @NonNull GenericWindowPolicyController windowPolicyController, @NonNull PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { @Nullable PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { mToken = Objects.requireNonNull(token); mWindowPolicyController = Objects.requireNonNull(windowPolicyController); mWakeLock = Objects.requireNonNull(wakeLock); mWakeLock = wakeLock; mIsTrusted = isTrusted; mIsMirror = isMirror; } Loading @@ -1845,8 +1899,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return mWindowPolicyController; } PowerManager.WakeLock getWakeLock() { return mWakeLock; void releaseWakeLock() { if (mWakeLock != null && mWakeLock.isHeld()) { mWakeLock.release(); } } boolean isTrusted() { Loading
services/core/java/com/android/server/display/DisplayManagerService.java +4 −5 Original line number Diff line number Diff line Loading @@ -1769,10 +1769,11 @@ public final class DisplayManagerService extends SystemService { flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; } // Put the display in the virtual device's display group only if it's not a mirror display, // and if it doesn't need its own display group. So effectively, mirror displays go into the // default display group. // it is a trusted display, and it doesn't need its own display group. So effectively, // mirror and untrusted displays go into the default display group. if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) == 0 && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0 && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == VIRTUAL_DISPLAY_FLAG_TRUSTED && virtualDevice != null) { flags |= VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP; } Loading Loading @@ -1848,9 +1849,7 @@ public final class DisplayManagerService extends SystemService { if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { // The virtualDevice instance has been validated above using isValidVirtualDevice if (virtualDevice == null && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + "create a virtual display which is not in the default DisplayGroup."); } Loading