From 9189e321ffe5dd6187195467b777d384b1022b91 Mon Sep 17 00:00:00 2001 From: Maurice Lam Date: Tue, 14 Dec 2021 17:41:53 -0800 Subject: [PATCH] Implement VDMInternal.isAppRunningOnAnyVirtualDevice Create a custom subclass of DWPC to allow virtual devices to track which apps are running on their virtual device, and use that to answer isAppRunningOnAnyVirtualDevice. Bug: 194949534 Test: Manual Change-Id: I61d7389c315798e9cb6f5a52771519d8b8ee6935 --- .../GenericWindowPolicyController.java | 14 ++++++++ .../companion/virtual/VirtualDeviceImpl.java | 32 ++++++++++++++++--- .../virtual/VirtualDeviceManagerService.java | 9 +++++- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index a6a87936616b3..e98b63ecd4b56 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -29,6 +29,7 @@ import android.os.Build; import android.os.UserHandle; import android.window.DisplayWindowPolicyController; +import java.util.HashSet; import java.util.List; @@ -45,6 +46,8 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE = 201712607L; + @NonNull final HashSet mRunningUids = new HashSet<>(); + GenericWindowPolicyController(int windowFlags, int systemWindowFlags) { setInterestedWindowFlags(windowFlags, systemWindowFlags); } @@ -89,6 +92,17 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @Override public void onRunningAppsChanged(int[] runningUids) { + mRunningUids.clear(); + for (int i = 0; i < runningUids.length; i++) { + mRunningUids.add(runningUids[i]); + } + } + /** + * Returns true if an app with the given UID has an activity running on the virtual display for + * this controller. + */ + boolean containsUid(int uid) { + return mRunningUids.contains(uid); } } 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 022da4361be41..36edf4fe9787c 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -32,6 +32,7 @@ import android.hardware.input.VirtualTouchEvent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.util.SparseArray; import android.window.DisplayWindowPolicyController; import com.android.internal.annotations.VisibleForTesting; @@ -50,12 +51,18 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final Context mContext; private final AssociationInfo mAssociationInfo; private final int mOwnerUid; - private final GenericWindowPolicyController mGenericWindowPolicyController; private final InputController mInputController; @VisibleForTesting final List mVirtualDisplayIds = new ArrayList<>(); private final OnDeviceCloseListener mListener; + /** + * A mapping from the virtual display ID to its corresponding + * {@link GenericWindowPolicyController}. + */ + private final SparseArray mWindowPolicyControllers = + new SparseArray<>(); + VirtualDeviceImpl(Context context, AssociationInfo associationInfo, IBinder token, int ownerUid, OnDeviceCloseListener listener) { this(context, associationInfo, token, ownerUid, /* inputController= */ null, listener); @@ -66,8 +73,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub int ownerUid, InputController inputController, OnDeviceCloseListener listener) { mContext = context; mAssociationInfo = associationInfo; - mGenericWindowPolicyController = new GenericWindowPolicyController(FLAG_SECURE, - SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); mOwnerUid = ownerUid; if (inputController == null) { mInputController = new InputController(mVirtualDeviceLock); @@ -257,7 +262,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub "Virtual device already have a virtual display with ID " + displayId); } mVirtualDisplayIds.add(displayId); - return mGenericWindowPolicyController; + final GenericWindowPolicyController dwpc = + new GenericWindowPolicyController(FLAG_SECURE, + SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + mWindowPolicyControllers.put(displayId, dwpc); + return dwpc; } void onVirtualDisplayRemovedLocked(int displayId) { @@ -266,12 +275,27 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub "Virtual device doesn't have a virtual display with ID " + displayId); } mVirtualDisplayIds.remove(displayId); + mWindowPolicyControllers.remove(displayId); } int getOwnerUid() { return mOwnerUid; } + /** + * Returns true if an app with the given {@code uid} is currently running on this virtual + * device. + */ + boolean isAppRunningOnVirtualDevice(int uid) { + final int size = mWindowPolicyControllers.size(); + for (int i = 0; i < size; i++) { + if (mWindowPolicyControllers.valueAt(i).containsUid(uid)) { + return true; + } + } + return false; + } + interface OnDeviceCloseListener { void onClose(int associationId); } 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 46e75f75ea9fc..0db670e469092 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -252,7 +252,14 @@ public class VirtualDeviceManagerService extends SystemService { @Override public boolean isAppRunningOnAnyVirtualDevice(int uid) { - // TODO(yukl): Implement this using DWPC.onRunningAppsChanged + synchronized (mVirtualDeviceManagerLock) { + int size = mVirtualDevices.size(); + for (int i = 0; i < size; i++) { + if (mVirtualDevices.valueAt(i).isAppRunningOnVirtualDevice(uid)) { + return true; + } + } + } return false; } }