diff options
| author | 2023-10-10 06:54:34 +0000 | |
|---|---|---|
| committer | 2023-10-10 06:54:34 +0000 | |
| commit | a2a9fbc63cd09f993bdb05afd9a87f5f30d65655 (patch) | |
| tree | 6e8e151ab4d241bc371089dc8c6f9f150774ef13 | |
| parent | 157676249ead7d2f4fa38f353ee6bbe62398893f (diff) | |
| parent | bf90ffd6c2b4a20d42d68fe4a3c07500318f4933 (diff) | |
Merge "Native VDM: base service implementation" into main
5 files changed, 133 insertions, 12 deletions
diff --git a/core/java/Android.bp b/core/java/Android.bp index 13a1bd6ca176..c3f3d875b0e0 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -431,6 +431,16 @@ aidl_interface { }, } +aidl_interface { + name: "android.companion.virtual.virtualdevice_aidl", + unstable: true, + host_supported: true, + srcs: [ + "android/companion/virtualnative/IVirtualDeviceManagerNative.aidl", + ], + local_include_dir: ".", +} + filegroup { name: "frameworks-base-java-overview", srcs: ["overview.html"], diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig index d0e13cd977ef..cf274f5cbbb9 100644 --- a/core/java/android/companion/virtual/flags.aconfig +++ b/core/java/android/companion/virtual/flags.aconfig @@ -8,6 +8,14 @@ flag { } flag { + name: "enable_native_vdm" + namespace: "virtual_devices" + description: "Enable native VDM service" + bug: "303535376" + is_fixed_read_only: true +} + +flag { name: "dynamic_policy" namespace: "virtual_devices" description: "Enable dynamic policy API" diff --git a/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl new file mode 100644 index 000000000000..9f09d043a89b --- /dev/null +++ b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.companion.virtualnative; + +/** + * Parallel implementation of certain VirtualDeviceManager APIs that need to be exposed to native + * code. + * + * <p>These APIs are a parallel definition to the APIs in VirtualDeviceManager and/or + * VirtualDeviceManagerInternal, so they can technically diverge. However, it's good practice to + * keep these APIs in sync with each other.</p> + * + * <p>Even though the name implies otherwise, the implementation is actually in Java. The 'native' + * suffix comes from the intended usage - native framework backends that need to communicate with + * VDM for some reason.</p> + * + * <p>Because these APIs are exposed to native code that runs in the app process, they may be + * accessed by apps directly, even though they're hidden. Care should be taken to avoid exposing + * sensitive data or potential security holes.</p> + * + * @hide + */ +interface IVirtualDeviceManagerNative { + /** + * Counterpart to VirtualDeviceParams#DevicePolicy. + */ + const int DEVICE_POLICY_DEFAULT = 0; + const int DEVICE_POLICY_CUSTOM = 1; + + /** + * Counterpart to VirtualDeviceParams#PolicyType. + */ + const int POLICY_TYPE_SENSORS = 0; + const int POLICY_TYPE_AUDIO = 1; + const int POLICY_TYPE_RECENTS = 2; + const int POLICY_TYPE_ACTIVITY = 3; + + /** + * Returns the IDs for all VirtualDevices where an app with the given is running. + * + * Note that this returns only VirtualDevice IDs: if the app is not running on any virtual + * device, then an an empty array is returned. This does not include information about whether + * the app is running on the default device or not. + */ + int[] getDeviceIdsForUid(int uid); + + /** + * Returns the device policy for the given virtual device and policy type. + */ + int getDevicePolicy(int deviceId, int policyType); +}
\ No newline at end of file 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 cfe56e910b8a..5cb100a1bfa5 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -38,6 +38,7 @@ import android.companion.virtual.VirtualDeviceManager; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; +import android.companion.virtualnative.IVirtualDeviceManagerNative; import android.content.AttributionSource; import android.content.Context; import android.content.Intent; @@ -88,8 +89,11 @@ public class VirtualDeviceManagerService extends SystemService { private static final String TAG = "VirtualDeviceManagerService"; + private static final String VIRTUAL_DEVICE_NATIVE_SERVICE = "virtualdevice_native"; + private final Object mVirtualDeviceManagerLock = new Object(); private final VirtualDeviceManagerImpl mImpl; + private final VirtualDeviceManagerNativeImpl mNativeImpl; private final VirtualDeviceManagerInternal mLocalService; private VirtualDeviceLog mVirtualDeviceLog = new VirtualDeviceLog(getContext()); private final Handler mHandler = new Handler(Looper.getMainLooper()); @@ -125,6 +129,7 @@ public class VirtualDeviceManagerService extends SystemService { public VirtualDeviceManagerService(Context context) { super(context); mImpl = new VirtualDeviceManagerImpl(); + mNativeImpl = Flags.enableNativeVdm() ? new VirtualDeviceManagerNativeImpl() : null; mLocalService = new LocalService(); } @@ -155,6 +160,9 @@ public class VirtualDeviceManagerService extends SystemService { @Override public void onStart() { publishBinderService(Context.VIRTUAL_DEVICE_SERVICE, mImpl); + if (Flags.enableNativeVdm()) { + publishBinderService(VIRTUAL_DEVICE_NATIVE_SERVICE, mNativeImpl); + } publishLocalService(VirtualDeviceManagerInternal.class, mLocalService); ActivityTaskManagerInternal activityTaskManagerInternal = getLocalService( ActivityTaskManagerInternal.class); @@ -590,6 +598,19 @@ public class VirtualDeviceManagerService extends SystemService { } } + final class VirtualDeviceManagerNativeImpl extends IVirtualDeviceManagerNative.Stub { + @Override // Binder call + public int[] getDeviceIdsForUid(int uid) { + return mLocalService + .getDeviceIdsForUid(uid).stream().mapToInt(Integer::intValue).toArray(); + } + + @Override // Binder call + public int getDevicePolicy(int deviceId, int policyType) { + return mImpl.getDevicePolicy(deviceId, policyType); + } + } + private final class LocalService extends VirtualDeviceManagerInternal { @GuardedBy("mVirtualDeviceManagerLock") private final ArrayList<VirtualDisplayListener> diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 61b30a024478..e8cbcf9a6874 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -233,6 +233,7 @@ public class VirtualDeviceManagerServiceTest { private VirtualDeviceManagerService mVdms; private VirtualDeviceManagerInternal mLocalService; private VirtualDeviceManagerService.VirtualDeviceManagerImpl mVdm; + private VirtualDeviceManagerService.VirtualDeviceManagerNativeImpl mVdmNative; private VirtualDeviceLog mVirtualDeviceLog; @Mock private InputController.NativeWrapper mNativeWrapperMock; @@ -340,6 +341,7 @@ public class VirtualDeviceManagerServiceTest { mSetFlagsRule.disableFlags(Flags.FLAG_DYNAMIC_POLICY); mSetFlagsRule.disableFlags(Flags.FLAG_STREAM_PERMISSIONS); mSetFlagsRule.disableFlags(Flags.FLAG_VDM_CUSTOM_HOME); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_NATIVE_VDM); doReturn(true).when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt()); doNothing().when(mInputManagerInternalMock).setPointerAcceleration(anyFloat(), anyInt()); @@ -384,6 +386,7 @@ public class VirtualDeviceManagerServiceTest { mVdms = new VirtualDeviceManagerService(mContext); mLocalService = mVdms.getLocalServiceInstance(); mVdm = mVdms.new VirtualDeviceManagerImpl(); + mVdmNative = mVdms.new VirtualDeviceManagerNativeImpl(); mVirtualDeviceLog = new VirtualDeviceLog(mContext); mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1); mSensorController = mDeviceImpl.getSensorControllerForTest(); @@ -440,24 +443,32 @@ public class VirtualDeviceManagerServiceTest { public void getDevicePolicy_invalidDeviceId_returnsDefault() { assertThat(mVdm.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_DEFAULT); + assertThat(mVdmNative.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS)) + .isEqualTo(DEVICE_POLICY_DEFAULT); } @Test public void getDevicePolicy_defaultDeviceId_returnsDefault() { assertThat(mVdm.getDevicePolicy(DEVICE_ID_DEFAULT, POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_DEFAULT); + assertThat(mVdmNative.getDevicePolicy(DEVICE_ID_DEFAULT, POLICY_TYPE_SENSORS)) + .isEqualTo(DEVICE_POLICY_DEFAULT); } @Test public void getDevicePolicy_nonExistentDeviceId_returnsDefault() { assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId() + 1, POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_DEFAULT); + assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId() + 1, POLICY_TYPE_SENSORS)) + .isEqualTo(DEVICE_POLICY_DEFAULT); } @Test public void getDevicePolicy_unspecifiedPolicy_returnsDefault() { assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_DEFAULT); + assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS)) + .isEqualTo(DEVICE_POLICY_DEFAULT); } @Test @@ -472,6 +483,8 @@ public class VirtualDeviceManagerServiceTest { assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS)) .isEqualTo(DEVICE_POLICY_CUSTOM); + assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS)) + .isEqualTo(DEVICE_POLICY_CUSTOM); } @Test @@ -567,8 +580,8 @@ public class VirtualDeviceManagerServiceTest { @Test public void getDeviceIdsForUid_noRunningApps_returnsNull() { - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).isEmpty(); + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).isEmpty(); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).isEmpty(); } @Test @@ -577,8 +590,8 @@ public class VirtualDeviceManagerServiceTest { mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged( Sets.newArraySet(UID_2)); - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).isEmpty(); + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).isEmpty(); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).isEmpty(); } @Test @@ -587,8 +600,9 @@ public class VirtualDeviceManagerServiceTest { mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged( Sets.newArraySet(UID_1)); - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); + int deviceId = mDeviceImpl.getDeviceId(); + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId); } @Test @@ -598,8 +612,9 @@ public class VirtualDeviceManagerServiceTest { mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged( Sets.newArraySet(UID_1, UID_2)); - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId()); + int deviceId = mDeviceImpl.getDeviceId(); + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId); } @Test @@ -611,8 +626,9 @@ public class VirtualDeviceManagerServiceTest { secondDevice.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_2).onRunningAppsChanged( Sets.newArraySet(UID_1)); - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).containsExactly(secondDevice.getDeviceId()); + int deviceId = secondDevice.getDeviceId(); + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId); } @Test @@ -628,8 +644,9 @@ public class VirtualDeviceManagerServiceTest { secondDevice.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_2).onRunningAppsChanged( Sets.newArraySet(UID_1, UID_2)); - Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1); - assertThat(deviceIds).containsExactly( + assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly( + mDeviceImpl.getDeviceId(), secondDevice.getDeviceId()); + assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly( mDeviceImpl.getDeviceId(), secondDevice.getDeviceId()); } |