From 2a017cdc0898ba337a73f2e5fa41a3007efba895 Mon Sep 17 00:00:00 2001 From: Christine Franks Date: Wed, 2 Feb 2022 09:21:26 -0800 Subject: [PATCH] Guard VirtualDevice#close by permission If the permission is not already held by the caller through other means, this causes unregistration failures, since the unique id disassociation requires a signature permission. Clear the binding identity if the permission is found, allowing use of the permisson. This is especially important for CTS tests, and for access by non-signature apps. Bug: 217275682 Test: atest CtsHardwareTestCases:android.hardware.input.cts.tests Change-Id: Ide5232e5b5b5b1b3ca96e5cbfb997e4a1001a583 --- core/api/system-current.txt | 2 +- .../companion/virtual/VirtualDeviceManager.java | 1 + .../server/companion/virtual/VirtualDeviceImpl.java | 12 +++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 6267dbf376f77..075dd9f3bae3e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2754,7 +2754,7 @@ package android.companion.virtual { public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable { method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener); method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener, @NonNull java.util.concurrent.Executor); - method public void close(); + method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close(); method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(int, int, int, @Nullable android.view.Surface, int, @Nullable android.os.Handler, @Nullable android.hardware.display.VirtualDisplay.Callback); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 69033a686351d..1dbe04cfda8e7 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -249,6 +249,7 @@ public final class VirtualDeviceManager { * Closes the virtual device, stopping and tearing down any virtual displays, * audio policies, and event injection that's currently in progress. */ + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close() { try { mVirtualDevice.close(); diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 47e218b48c093..7d0440fe12d35 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -212,6 +212,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @Override // Binder call public void close() { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CREATE_VIRTUAL_DEVICE, + "Permission required to close the virtual device"); + synchronized (mVirtualDeviceLock) { if (!mPerDisplayWakelocks.isEmpty()) { mPerDisplayWakelocks.forEach((displayId, wakeLock) -> { @@ -224,7 +228,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } mListener.onClose(mAssociationInfo.getId()); mAppToken.unlinkToDeath(this, 0); - mInputController.close(); + + final long token = Binder.clearCallingIdentity(); + try { + mInputController.close(); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override