Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9189e321 authored by Maurice Lam's avatar Maurice Lam
Browse files

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
parent fcedd7e1
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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<Integer> 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);
    }
}
+28 −4
Original line number Diff line number Diff line
@@ -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<Integer> mVirtualDisplayIds = new ArrayList<>();
    private final OnDeviceCloseListener mListener;

    /**
     * A mapping from the virtual display ID to its corresponding
     * {@link GenericWindowPolicyController}.
     */
    private final SparseArray<GenericWindowPolicyController> 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);
    }
+8 −1
Original line number Diff line number Diff line
@@ -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;
        }
    }