summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Komsiyski <vladokom@google.com> 2024-09-03 11:37:19 +0200
committer Vladimir Komsiyski <vladokom@google.com> 2024-09-03 13:57:32 +0200
commit07cf22e07d2dc9668773d731ebb7aaed61ecf71c (patch)
tree43e0376391005c0af4241b852795452df32d16a2
parentefad7c1645ca6d15b981e15ea442d04d3c7d7f2f (diff)
New VDM callback API onSecureSurfaceShown
Fix: 311101667 Test: CTS Flag: android.companion.virtualdevice.flags.activity_control_api Change-Id: Id0cf7bb3317f53f80bf096e245f4e949fcb02d0e
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl9
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceInternal.java23
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceManager.java14
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java28
5 files changed, 73 insertions, 2 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e87bc50013fe..98e5eabdeb13 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3469,6 +3469,7 @@ package android.companion.virtual {
public static interface VirtualDeviceManager.ActivityListener {
method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.content.IntentSender);
method public void onDisplayEmpty(int);
+ method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onSecureWindowShown(int, @NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
method @Deprecated public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
method public default void onTopActivityChanged(int, @NonNull android.content.ComponentName, int);
}
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index 7c674f9cde6b..767f52a92566 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -54,4 +54,13 @@ oneway interface IVirtualDeviceActivityListener {
*/
void onActivityLaunchBlocked(int displayId, in ComponentName componentName, in UserHandle user,
in IntentSender intentSender);
+
+ /**
+ * Called when a secure surface is shown on the device.
+ *
+ * @param displayId The display ID on which the secure surface was shown.
+ * @param componentName The component name of the activity that showed the secure surface.
+ * @param user The user associated with the activity.
+ */
+ void onSecureWindowShown(int displayId, in ComponentName componentName, in UserHandle user);
}
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index b7bf2d16ba2c..de20a68e52cb 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -151,7 +151,24 @@ public class VirtualDeviceInternal {
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public void onSecureWindowShown(int displayId, ComponentName componentName,
+ UserHandle user) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mActivityListenersLock) {
+ for (int i = 0; i < mActivityListeners.size(); i++) {
+ mActivityListeners.valueAt(i)
+ .onSecureWindowShown(displayId, componentName, user);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
};
+
private final IVirtualDeviceSoundEffectListener mSoundEffectListener =
new IVirtualDeviceSoundEffectListener.Stub() {
@Override
@@ -584,6 +601,12 @@ public class VirtualDeviceInternal {
mActivityListener.onActivityLaunchBlocked(
displayId, componentName, user, intentSender));
}
+
+ public void onSecureWindowShown(int displayId, ComponentName componentName,
+ UserHandle user) {
+ mExecutor.execute(() ->
+ mActivityListener.onSecureWindowShown(displayId, componentName, user));
+ }
}
/**
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 40aa6837ad1d..cf3445246fce 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -1255,6 +1255,20 @@ public final class VirtualDeviceManager {
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
@NonNull UserHandle user, @Nullable IntentSender intentSender) {}
+
+ /**
+ * Called when a window with a secure surface is shown on the device.
+ *
+ * @param displayId The display ID on which the window was shown.
+ * @param componentName The component name of the activity that showed the window.
+ * @param user The user associated with the activity.
+ *
+ * @see Display#FLAG_SECURE
+ * @see WindowManager.LayoutParams#FLAG_SECURE
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
+ default void onSecureWindowShown(int displayId, @NonNull ComponentName componentName,
+ @NonNull UserHandle user) {}
}
/**
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 277d582492b9..cd2dd3a27c9a 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -40,6 +40,7 @@ import android.app.Activity;
import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
+import android.app.compat.CompatChanges;
import android.companion.AssociationInfo;
import android.companion.virtual.ActivityPolicyExemption;
import android.companion.virtual.IVirtualDevice;
@@ -55,6 +56,8 @@ import android.companion.virtual.camera.VirtualCameraConfig;
import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
import android.companion.virtual.sensor.VirtualSensorEvent;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Context;
@@ -87,6 +90,7 @@ import android.hardware.input.VirtualTouchscreenConfig;
import android.media.AudioManager;
import android.media.audiopolicy.AudioMix;
import android.os.Binder;
+import android.os.Build;
import android.os.IBinder;
import android.os.LocaleList;
import android.os.Looper;
@@ -131,6 +135,16 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
private static final String TAG = "VirtualDeviceImpl";
+ /**
+ * Do not show a toast on the virtual display when a secure surface is shown after
+ * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. VDM clients should use
+ * {@link VirtualDeviceManager.ActivityListener#onSecureWindowShown} instead to provide
+ * a custom notification if desired.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ public static final long DO_NOT_SHOW_TOAST_WHEN_SECURE_SURFACE_SHOWN = 311101667L;
+
private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS =
DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED
| DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL
@@ -256,8 +270,18 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
@Override
public void onSecureWindowShown(int displayId, @NonNull ActivityInfo activityInfo) {
- synchronized (mVirtualDeviceLock) {
- if (!mVirtualDisplays.contains(displayId)) {
+ if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ try {
+ mActivityListener.onSecureWindowShown(
+ displayId,
+ activityInfo.getComponentName(),
+ UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid));
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
+ }
+
+ if (CompatChanges.isChangeEnabled(DO_NOT_SHOW_TOAST_WHEN_SECURE_SURFACE_SHOWN,
+ mOwnerPackageName, UserHandle.getUserHandleForUid(mOwnerUid))) {
return;
}
}