Loading services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +31 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Parcel; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; Loading @@ -62,6 +63,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; Loading Loading @@ -494,6 +496,35 @@ public class VirtualDeviceManagerService extends SystemService { } } @Override public int getDeviceOwnerUid(int deviceId) { synchronized (mVirtualDeviceManagerLock) { int size = mVirtualDevices.size(); for (int i = 0; i < size; i++) { VirtualDeviceImpl device = mVirtualDevices.valueAt(i); if (device.getDeviceId() == deviceId) { return device.getOwnerUid(); } } } return Process.INVALID_UID; } @Override public @NonNull Set<Integer> getDeviceIdsForUid(int uid) { ArraySet<Integer> result = new ArraySet<>(); synchronized (mVirtualDeviceManagerLock) { int size = mVirtualDevices.size(); for (int i = 0; i < size; i++) { VirtualDeviceImpl device = mVirtualDevices.valueAt(i); if (device.isAppRunningOnVirtualDevice(uid)) { result.add(device.getDeviceId()); } } } return result; } @Override public void onVirtualDisplayCreated(int displayId) { final VirtualDisplayListener[] listeners; Loading services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java +19 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ public abstract class VirtualDeviceManagerInternal { void onVirtualDisplayRemoved(int displayId); } /** Interface to listen to the changes on the list of app UIDs running on any virtual device. */ public interface AppsOnVirtualDeviceListener { /** Notifies that running apps on any virtual device has changed */ Loading Loading @@ -71,6 +70,25 @@ public abstract class VirtualDeviceManagerInternal { */ public abstract boolean isValidVirtualDevice(IVirtualDevice virtualDevice); /** * Gets the owner uid for a deviceId. * * @param deviceId which device we're asking about * @return the uid of the app which created and owns the VirtualDevice with the given deviceId, * or {@link android.os.Process#INVALID_UID} if no such device exists. */ public abstract int getDeviceOwnerUid(int deviceId); /** * Finds VirtualDevices where an app is running. * * @param uid - the app's uid * @return a set of id's of VirtualDevices where the app with the given uid is running. * *Note* this only checks VirtualDevices, and does not include information about whether * the app is running on the default device or not. */ public abstract @NonNull Set<Integer> getDeviceIdsForUid(int uid); /** * Notifies that a virtual display is created. * Loading services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +129 −12 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ import com.android.server.LocalServices; import com.android.server.input.InputManagerInternal; import com.android.server.sensors.SensorManagerInternal; import com.google.android.collect.Sets; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -108,6 +110,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.function.Consumer; @Presubmit Loading @@ -124,6 +127,9 @@ public class VirtualDeviceManagerServiceTest { private static final String GOOGLE_MAPS_PACKAGE_NAME = "com.google.android.apps.maps"; private static final String DEVICE_NAME = "device name"; private static final int DISPLAY_ID = 2; private static final int DISPLAY_ID_2 = 3; private static final int DEVICE_OWNER_UID_1 = 50; private static final int DEVICE_OWNER_UID_2 = 51; private static final int UID_1 = 0; private static final int UID_2 = 10; private static final int UID_3 = 10000; Loading Loading @@ -301,22 +307,13 @@ public class VirtualDeviceManagerServiceTest { mContext.getSystemService(WindowManager.class), threadVerifier); mSensorController = new SensorController(new Object(), VIRTUAL_DEVICE_ID); mAssociationInfo = new AssociationInfo(1, 0, null, mAssociationInfo = new AssociationInfo(ASSOCIATION_ID_1, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0); mVdms = new VirtualDeviceManagerService(mContext); mLocalService = mVdms.getLocalServiceInstance(); mVdm = mVdms.new VirtualDeviceManagerImpl(); VirtualDeviceParams params = new VirtualDeviceParams .Builder() .setBlockedActivities(getBlockedActivities()) .build(); mDeviceImpl = new VirtualDeviceImpl(mContext, mAssociationInfo, new Binder(), /* ownerUid= */ 0, VIRTUAL_DEVICE_ID, mInputController, mSensorController, (int associationId) -> {}, mPendingTrampolineCallback, mActivityListener, mRunningAppsChangedCallback, params); mVdms.addVirtualDevice(mDeviceImpl); mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID, DEVICE_OWNER_UID_1, mAssociationInfo); } @Test Loading Loading @@ -388,6 +385,112 @@ public class VirtualDeviceManagerServiceTest { .isEqualTo(DEVICE_POLICY_CUSTOM); } @Test public void getDeviceOwnerUid_oneDevice_returnsCorrectId() { int ownerUid = mLocalService.getDeviceOwnerUid(mDeviceImpl.getDeviceId()); assertThat(ownerUid).isEqualTo(mDeviceImpl.getOwnerUid()); } @Test public void getDeviceOwnerUid_twoDevices_returnsCorrectId() { int firstDeviceId = mDeviceImpl.getDeviceId(); int secondDeviceId = VIRTUAL_DEVICE_ID + 1; createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); int secondDeviceOwner = mLocalService.getDeviceOwnerUid(secondDeviceId); assertThat(secondDeviceOwner).isEqualTo(DEVICE_OWNER_UID_2); int firstDeviceOwner = mLocalService.getDeviceOwnerUid(firstDeviceId); assertThat(firstDeviceOwner).isEqualTo(DEVICE_OWNER_UID_1); } @Test public void getDeviceOwnerUid_nonExistentDevice_returnsInvalidUid() { int nonExistentDeviceId = DEVICE_ID_DEFAULT; int ownerUid = mLocalService.getDeviceOwnerUid(nonExistentDeviceId); assertThat(ownerUid).isEqualTo(Process.INVALID_UID); } @Test public void getDeviceIdsForUid_noRunningApps_returnsNull() { Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).isEmpty(); } @Test public void getDeviceIdsForUid_differentUidOnDevice_returnsNull() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).isEmpty(); } @Test public void getDeviceIdsForUid_oneUidOnDevice_returnsCorrectId() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); } @Test public void getDeviceIdsForUid_twoUidsOnDevice_returnsCorrectId() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1, UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); } @Test public void getDeviceIdsForUid_twoDevicesUidOnOne_returnsCorrectId() { int secondDeviceId = VIRTUAL_DEVICE_ID + 1; VirtualDeviceImpl secondDevice = createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); GenericWindowPolicyController gwpc = secondDevice.createWindowPolicyController(new ArrayList<>()); secondDevice.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID_2); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(secondDevice.getDeviceId()); } @Test public void getDeviceIdsForUid_twoDevicesUidOnBoth_returnsCorrectId() { int secondDeviceId = VIRTUAL_DEVICE_ID + 1; VirtualDeviceImpl secondDevice = createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); GenericWindowPolicyController gwpc1 = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); GenericWindowPolicyController gwpc2 = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc1, DISPLAY_ID); secondDevice.onVirtualDisplayCreatedLocked(gwpc2, DISPLAY_ID_2); gwpc1.onRunningAppsChanged(Sets.newArraySet(UID_1)); gwpc2.onRunningAppsChanged(Sets.newArraySet(UID_1, UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly( mDeviceImpl.getDeviceId(), secondDevice.getDeviceId()); } @Test public void onVirtualDisplayRemovedLocked_doesNotThrowException() { mDeviceImpl.onVirtualDisplayCreatedLocked( Loading Loading @@ -1160,7 +1263,6 @@ public class VirtualDeviceManagerServiceTest { /* targetDisplayCategory= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); } @Test Loading @@ -1185,4 +1287,19 @@ public class VirtualDeviceManagerServiceTest { verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); } private VirtualDeviceImpl createVirtualDevice(int virtualDeviceId, int ownerUid, AssociationInfo associationInfo) { VirtualDeviceParams params = new VirtualDeviceParams .Builder() .setBlockedActivities(getBlockedActivities()) .build(); VirtualDeviceImpl virtualDeviceImpl = new VirtualDeviceImpl(mContext, associationInfo, new Binder(), ownerUid, virtualDeviceId, mInputController, mSensorController, (int associationId) -> {}, mPendingTrampolineCallback, mActivityListener, mRunningAppsChangedCallback, params); mVdms.addVirtualDevice(virtualDeviceImpl); return virtualDeviceImpl; } } Loading
services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +31 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Parcel; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; Loading @@ -62,6 +63,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; Loading Loading @@ -494,6 +496,35 @@ public class VirtualDeviceManagerService extends SystemService { } } @Override public int getDeviceOwnerUid(int deviceId) { synchronized (mVirtualDeviceManagerLock) { int size = mVirtualDevices.size(); for (int i = 0; i < size; i++) { VirtualDeviceImpl device = mVirtualDevices.valueAt(i); if (device.getDeviceId() == deviceId) { return device.getOwnerUid(); } } } return Process.INVALID_UID; } @Override public @NonNull Set<Integer> getDeviceIdsForUid(int uid) { ArraySet<Integer> result = new ArraySet<>(); synchronized (mVirtualDeviceManagerLock) { int size = mVirtualDevices.size(); for (int i = 0; i < size; i++) { VirtualDeviceImpl device = mVirtualDevices.valueAt(i); if (device.isAppRunningOnVirtualDevice(uid)) { result.add(device.getDeviceId()); } } } return result; } @Override public void onVirtualDisplayCreated(int displayId) { final VirtualDisplayListener[] listeners; Loading
services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java +19 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ public abstract class VirtualDeviceManagerInternal { void onVirtualDisplayRemoved(int displayId); } /** Interface to listen to the changes on the list of app UIDs running on any virtual device. */ public interface AppsOnVirtualDeviceListener { /** Notifies that running apps on any virtual device has changed */ Loading Loading @@ -71,6 +70,25 @@ public abstract class VirtualDeviceManagerInternal { */ public abstract boolean isValidVirtualDevice(IVirtualDevice virtualDevice); /** * Gets the owner uid for a deviceId. * * @param deviceId which device we're asking about * @return the uid of the app which created and owns the VirtualDevice with the given deviceId, * or {@link android.os.Process#INVALID_UID} if no such device exists. */ public abstract int getDeviceOwnerUid(int deviceId); /** * Finds VirtualDevices where an app is running. * * @param uid - the app's uid * @return a set of id's of VirtualDevices where the app with the given uid is running. * *Note* this only checks VirtualDevices, and does not include information about whether * the app is running on the default device or not. */ public abstract @NonNull Set<Integer> getDeviceIdsForUid(int uid); /** * Notifies that a virtual display is created. * Loading
services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +129 −12 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ import com.android.server.LocalServices; import com.android.server.input.InputManagerInternal; import com.android.server.sensors.SensorManagerInternal; import com.google.android.collect.Sets; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -108,6 +110,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.function.Consumer; @Presubmit Loading @@ -124,6 +127,9 @@ public class VirtualDeviceManagerServiceTest { private static final String GOOGLE_MAPS_PACKAGE_NAME = "com.google.android.apps.maps"; private static final String DEVICE_NAME = "device name"; private static final int DISPLAY_ID = 2; private static final int DISPLAY_ID_2 = 3; private static final int DEVICE_OWNER_UID_1 = 50; private static final int DEVICE_OWNER_UID_2 = 51; private static final int UID_1 = 0; private static final int UID_2 = 10; private static final int UID_3 = 10000; Loading Loading @@ -301,22 +307,13 @@ public class VirtualDeviceManagerServiceTest { mContext.getSystemService(WindowManager.class), threadVerifier); mSensorController = new SensorController(new Object(), VIRTUAL_DEVICE_ID); mAssociationInfo = new AssociationInfo(1, 0, null, mAssociationInfo = new AssociationInfo(ASSOCIATION_ID_1, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0); mVdms = new VirtualDeviceManagerService(mContext); mLocalService = mVdms.getLocalServiceInstance(); mVdm = mVdms.new VirtualDeviceManagerImpl(); VirtualDeviceParams params = new VirtualDeviceParams .Builder() .setBlockedActivities(getBlockedActivities()) .build(); mDeviceImpl = new VirtualDeviceImpl(mContext, mAssociationInfo, new Binder(), /* ownerUid= */ 0, VIRTUAL_DEVICE_ID, mInputController, mSensorController, (int associationId) -> {}, mPendingTrampolineCallback, mActivityListener, mRunningAppsChangedCallback, params); mVdms.addVirtualDevice(mDeviceImpl); mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID, DEVICE_OWNER_UID_1, mAssociationInfo); } @Test Loading Loading @@ -388,6 +385,112 @@ public class VirtualDeviceManagerServiceTest { .isEqualTo(DEVICE_POLICY_CUSTOM); } @Test public void getDeviceOwnerUid_oneDevice_returnsCorrectId() { int ownerUid = mLocalService.getDeviceOwnerUid(mDeviceImpl.getDeviceId()); assertThat(ownerUid).isEqualTo(mDeviceImpl.getOwnerUid()); } @Test public void getDeviceOwnerUid_twoDevices_returnsCorrectId() { int firstDeviceId = mDeviceImpl.getDeviceId(); int secondDeviceId = VIRTUAL_DEVICE_ID + 1; createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); int secondDeviceOwner = mLocalService.getDeviceOwnerUid(secondDeviceId); assertThat(secondDeviceOwner).isEqualTo(DEVICE_OWNER_UID_2); int firstDeviceOwner = mLocalService.getDeviceOwnerUid(firstDeviceId); assertThat(firstDeviceOwner).isEqualTo(DEVICE_OWNER_UID_1); } @Test public void getDeviceOwnerUid_nonExistentDevice_returnsInvalidUid() { int nonExistentDeviceId = DEVICE_ID_DEFAULT; int ownerUid = mLocalService.getDeviceOwnerUid(nonExistentDeviceId); assertThat(ownerUid).isEqualTo(Process.INVALID_UID); } @Test public void getDeviceIdsForUid_noRunningApps_returnsNull() { Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).isEmpty(); } @Test public void getDeviceIdsForUid_differentUidOnDevice_returnsNull() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).isEmpty(); } @Test public void getDeviceIdsForUid_oneUidOnDevice_returnsCorrectId() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); } @Test public void getDeviceIdsForUid_twoUidsOnDevice_returnsCorrectId() { GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1, UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); } @Test public void getDeviceIdsForUid_twoDevicesUidOnOne_returnsCorrectId() { int secondDeviceId = VIRTUAL_DEVICE_ID + 1; VirtualDeviceImpl secondDevice = createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); GenericWindowPolicyController gwpc = secondDevice.createWindowPolicyController(new ArrayList<>()); secondDevice.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID_2); gwpc.onRunningAppsChanged(Sets.newArraySet(UID_1)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly(secondDevice.getDeviceId()); } @Test public void getDeviceIdsForUid_twoDevicesUidOnBoth_returnsCorrectId() { int secondDeviceId = VIRTUAL_DEVICE_ID + 1; VirtualDeviceImpl secondDevice = createVirtualDevice(secondDeviceId, DEVICE_OWNER_UID_2, new AssociationInfo(ASSOCIATION_ID_2, 0, null, MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0)); GenericWindowPolicyController gwpc1 = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); GenericWindowPolicyController gwpc2 = mDeviceImpl.createWindowPolicyController(new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc1, DISPLAY_ID); secondDevice.onVirtualDisplayCreatedLocked(gwpc2, DISPLAY_ID_2); gwpc1.onRunningAppsChanged(Sets.newArraySet(UID_1)); gwpc2.onRunningAppsChanged(Sets.newArraySet(UID_1, UID_2)); Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); assertThat(deviceIds).containsExactly( mDeviceImpl.getDeviceId(), secondDevice.getDeviceId()); } @Test public void onVirtualDisplayRemovedLocked_doesNotThrowException() { mDeviceImpl.onVirtualDisplayCreatedLocked( Loading Loading @@ -1160,7 +1263,6 @@ public class VirtualDeviceManagerServiceTest { /* targetDisplayCategory= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); } @Test Loading @@ -1185,4 +1287,19 @@ public class VirtualDeviceManagerServiceTest { verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); } private VirtualDeviceImpl createVirtualDevice(int virtualDeviceId, int ownerUid, AssociationInfo associationInfo) { VirtualDeviceParams params = new VirtualDeviceParams .Builder() .setBlockedActivities(getBlockedActivities()) .build(); VirtualDeviceImpl virtualDeviceImpl = new VirtualDeviceImpl(mContext, associationInfo, new Binder(), ownerUid, virtualDeviceId, mInputController, mSensorController, (int associationId) -> {}, mPendingTrampolineCallback, mActivityListener, mRunningAppsChangedCallback, params); mVdms.addVirtualDevice(virtualDeviceImpl); return virtualDeviceImpl; } }