diff options
12 files changed, 155 insertions, 51 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index bed1b43fdbe7..15e5706db9d1 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3448,7 +3448,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, int); + method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, int, @Nullable android.content.IntentSender); method public void onDisplayEmpty(int); 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 39371a3dbd3f..564fb023dc7b 100644 --- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl +++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl @@ -17,6 +17,7 @@ package android.companion.virtual; import android.content.ComponentName; +import android.content.IntentSender; /** * Interface to listen for activity changes in a virtual device. @@ -48,6 +49,8 @@ oneway interface IVirtualDeviceActivityListener { * @param displayId The display ID on which the activity tried to launch. * @param componentName The component name of the blocked activity. * @param userId The user ID associated with the blocked activity. + * @param intentSender The original sender of the intent. */ - void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId); + void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId, + in IntentSender intentSender); } diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java index d8899b24eda3..19eb497dbd7a 100644 --- a/core/java/android/companion/virtual/VirtualDeviceInternal.java +++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java @@ -38,6 +38,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentSender; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplay; @@ -135,13 +136,14 @@ public class VirtualDeviceInternal { @Override public void onActivityLaunchBlocked(int displayId, ComponentName componentName, - @UserIdInt int userId) { + @UserIdInt int userId, IntentSender intentSender) { final long token = Binder.clearCallingIdentity(); try { synchronized (mActivityListenersLock) { for (int i = 0; i < mActivityListeners.size(); i++) { mActivityListeners.valueAt(i) - .onActivityLaunchBlocked(displayId, componentName, userId); + .onActivityLaunchBlocked( + displayId, componentName, userId, intentSender); } } } finally { @@ -593,9 +595,10 @@ public class VirtualDeviceInternal { } public void onActivityLaunchBlocked(int displayId, ComponentName componentName, - @UserIdInt int userId) { + @UserIdInt int userId, IntentSender intentSender) { mExecutor.execute(() -> - mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId)); + mActivityListener.onActivityLaunchBlocked( + displayId, componentName, userId, intentSender)); } } diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 42da7e9e1815..77c417bb6471 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -43,6 +43,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentSender; import android.graphics.Point; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.VirtualDisplayFlag; @@ -1250,13 +1251,18 @@ public final class VirtualDeviceManager { * @param displayId The display ID on which the activity tried to launch. * @param componentName The component name of the blocked activity. * @param userId The user ID associated with the blocked activity. + * @param intentSender The original sender of the intent. May be {@code null} if the sender + * expects an activity result to be reported. In that case + * {@link android.app.Activity#RESULT_CANCELED} was already reported back because the + * launch was blocked. This {@link IntentSender} can be used to relaunch the blocked + * activity to a different display. * * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY * @see VirtualDevice#addActivityPolicyExemption(ComponentName) */ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API) default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName, - @UserIdInt int userId) {} + @UserIdInt int userId, @Nullable IntentSender intentSender) {} } /** diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java index 62a7283621cc..a16d53768ca1 100644 --- a/core/java/android/window/DisplayWindowPolicyController.java +++ b/core/java/android/window/DisplayWindowPolicyController.java @@ -25,12 +25,14 @@ import android.annotation.UserIdInt; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.util.ArraySet; import java.io.PrintWriter; import java.util.List; import java.util.Set; +import java.util.function.Supplier; /** * Abstract class to control the policies of the windows that can be displayed on the virtual @@ -136,10 +138,14 @@ public abstract class DisplayWindowPolicyController { * Returns {@code true} if the given activity can be launched on this virtual display in the * configuration defined by the rest of the arguments. If the given intent would be intercepted * by the display owner then this means that the activity cannot be launched. + * + * The intentSender argument can provide an IntentSender for the original intent to be passed + * to any activity listeners, in case the activity cannot be launched. */ public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, - int launchingFromDisplayId, boolean isNewTask); + int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected, + @Nullable Supplier<IntentSender> intentSender); /** * Returns {@code true} if the given activity can be launched on this virtual display in the 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 84b5c3992d30..e57817f8e7ee 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -33,6 +33,7 @@ import android.compat.annotation.EnabledSince; import android.content.AttributionSource; import android.content.ComponentName; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.os.Build; import android.os.Handler; @@ -51,6 +52,7 @@ import com.android.modules.expresslog.Counter; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; /** * A controller to control the policies of the windows that can be displayed on the virtual display. @@ -73,7 +75,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController */ public interface ActivityBlockedCallback { /** Called when an activity is blocked.*/ - void onActivityBlocked(int displayId, ActivityInfo activityInfo); + void onActivityBlocked(int displayId, ActivityInfo activityInfo, IntentSender intentSender); } private static final ComponentName BLOCKED_APP_STREAMING_COMPONENT = new ComponentName("android", BlockedAppStreamingActivity.class.getName()); @@ -282,7 +284,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @Override public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, - int launchingFromDisplayId, boolean isNewTask) { + int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected, + @Nullable Supplier<IntentSender> intentSender) { if (mIntentListenerCallback != null && intent != null && mIntentListenerCallback.shouldInterceptIntent(intent)) { logActivityLaunchBlocked("Virtual device intercepting intent"); @@ -290,7 +293,10 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId, isNewTask)) { - notifyActivityBlocked(activityInfo); + // If the sender of the original intent expects a result to be reported, do not pass the + // intent sender to the client callback. As the launch is blocked, the caller already + // received that activity result. + notifyActivityBlocked(activityInfo, isResultExpected ? null : intentSender); return false; } return true; @@ -381,7 +387,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. if ((windowFlags & FLAG_SECURE) != 0 || (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { - notifyActivityBlocked(activityInfo); + notifyActivityBlocked(activityInfo, /* intentSender= */ null); return false; } } @@ -454,13 +460,15 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController && mDisplayCategories.contains(activityInfo.requiredDisplayCategory); } - private void notifyActivityBlocked(ActivityInfo activityInfo) { + private void notifyActivityBlocked( + ActivityInfo activityInfo, Supplier<IntentSender> intentSender) { int displayId = waitAndGetDisplayId(); // Don't trigger activity blocked callback for mirror displays, because we can't show // any activity or presentation on it anyway. if (!waitAndGetIsMirrorDisplay() && mActivityBlockedCallback != null && displayId != INVALID_DISPLAY) { - mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo); + mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo, + intentSender == null ? null : intentSender.get()); } Counter.logIncrementWithUid( "virtual_devices.value_activity_blocked_count", 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 ed2c90d6a7ee..2db54435199b 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -60,6 +60,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.graphics.PointF; @@ -241,9 +242,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @Override public void onActivityLaunchBlocked(int displayId, - @NonNull ComponentName componentName, @UserIdInt int userId) { + @NonNull ComponentName componentName, @UserIdInt int userId, + @Nullable IntentSender intentSender) { try { - mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId); + mActivityListener.onActivityLaunchBlocked( + displayId, componentName, userId, intentSender); } catch (RemoteException e) { Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); } @@ -1364,7 +1367,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) - private void onActivityBlocked(int displayId, ActivityInfo activityInfo) { + private void onActivityBlocked(int displayId, ActivityInfo activityInfo, + IntentSender intentSender) { Intent intent = BlockedAppStreamingActivity.createIntent(activityInfo, getDisplayName()); if (shouldShowBlockedActivityDialog( activityInfo.getComponentName(), intent.getComponent())) { @@ -1380,7 +1384,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub displayId, activityInfo.getComponentName(), UserHandle.getUserHandleForUid( - activityInfo.applicationInfo.uid).getIdentifier()); + activityInfo.applicationInfo.uid).getIdentifier(), + intentSender); } } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index cc195ac6eae4..2f6e7deb5535 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -28,6 +28,8 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityTaskManager.INVALID_TASK_ID; +import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; +import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; @@ -146,6 +148,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.DateFormat; import java.util.Date; +import java.util.function.Supplier; /** * Controller for interpreting how and then launching an activity. @@ -2079,9 +2082,23 @@ class ActivityStarter { ? targetTask.getWindowingMode() : displayContent.getWindowingMode(); final int launchingFromDisplayId = mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY; + final boolean isResultExpected = r.resultTo != null; + Supplier<IntentSender> intentSender = null; + if (android.companion.virtualdevice.flags.Flags.activityControlApi()) { + intentSender = () -> { + IIntentSender target = mService.getIntentSenderLocked( + ActivityManager.INTENT_SENDER_ACTIVITY, mRequest.callingPackage, + mRequest.callingFeatureId, mCallingUid, r.mUserId, + /* token= */ null, /* resultCode= */ null, /* requestCode= */ 0, + new Intent[]{ mIntent }, new String[]{ r.resolvedType }, + FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT, + mOptions == null ? null : mOptions.toBundle()); + return new IntentSender(target); + }; + } if (!displayContent.mDwpcHelper .canActivityBeLaunched(r.info, r.intent, targetWindowingMode, - launchingFromDisplayId, newTask)) { + launchingFromDisplayId, newTask, isResultExpected, intentSender)) { Slog.w(TAG, "Abort to launch " + r.info.getComponentName() + " on display area " + mPreferredTaskDisplayArea); return START_ABORTED; diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java index 4ec318bee726..dedf35a74e04 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java @@ -24,6 +24,7 @@ import android.app.WindowConfiguration; import android.companion.virtualdevice.flags.Flags; import android.content.ComponentName; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.os.Process; import android.os.UserHandle; @@ -34,6 +35,7 @@ import android.window.DisplayWindowPolicyController; import java.io.PrintWriter; import java.util.List; +import java.util.function.Supplier; class DisplayWindowPolicyControllerHelper { private static final String TAG = "DisplayWindowPolicyControllerHelper"; @@ -98,7 +100,8 @@ class DisplayWindowPolicyControllerHelper { */ public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, - int launchingFromDisplayId, boolean isNewTask) { + int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected, + Supplier<IntentSender> intentSender) { if (mDisplayWindowPolicyController == null) { // Missing controller means that this display has no categories for activity launch // restriction. @@ -111,7 +114,7 @@ class DisplayWindowPolicyControllerHelper { return true; } return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent, - windowingMode, launchingFromDisplayId, isNewTask); + windowingMode, launchingFromDisplayId, isNewTask, isResultExpected, intentSender); } private boolean hasDisplayCategory(ActivityInfo aInfo) { diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java index 7eabfac2ee3f..9317d06ec968 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java @@ -42,9 +42,11 @@ import android.content.AttributionSource; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.net.Uri; +import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; @@ -592,13 +594,15 @@ public class GenericWindowPolicyControllerTest { // register interceptor and intercept intent when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(true); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isFalse(); // unregister interceptor and launch activity when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); } @@ -617,13 +621,36 @@ public class GenericWindowPolicyControllerTest { // register interceptor with different filter when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); verify(mIntentListenerCallback, timeout(TIMEOUT_MILLIS)) .shouldInterceptIntent(any(Intent.class)); } @Test + public void canActivityBeLaunched_resultExpected_noIntentSenderInCallback() { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("testing")); + + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false); + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ false, + /* targetDisplayCategory */ null); + + IntentSender intentSender = new IntentSender(new Binder()); + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false, + /* isResultExpected = */ true, /* intentSender= */ () -> intentSender)) + .isFalse(); + + verify(mActivityBlockedCallback, timeout(TIMEOUT_MILLIS)) + .onActivityBlocked(DISPLAY_ID, activityInfo, /* intentSender= */ null); + } + + @Test public void onTopActivitychanged_null_noCallback() { GenericWindowPolicyController gwpc = createGwpc(); gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false); @@ -659,7 +686,8 @@ public class GenericWindowPolicyControllerTest { verify(mSecureWindowCallback, after(TIMEOUT_MILLIS).never()) .onSecureWindowShown(DISPLAY_ID, activityInfo.applicationInfo.uid); - verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo); + verify(mActivityBlockedCallback, never()) + .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any()); } @Test @@ -678,7 +706,7 @@ public class GenericWindowPolicyControllerTest { verify(mSecureWindowCallback, timeout(TIMEOUT_MILLIS)).onSecureWindowShown(DISPLAY_ID, activityInfo.applicationInfo.uid); verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never()) - .onActivityBlocked(DISPLAY_ID, activityInfo); + .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any()); } @Test @@ -697,7 +725,8 @@ public class GenericWindowPolicyControllerTest { verify(mSecureWindowCallback, after(TIMEOUT_MILLIS).never()) .onSecureWindowShown(DISPLAY_ID, activityInfo.applicationInfo.uid); - verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo); + verify(mActivityBlockedCallback, never()) + .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any()); } @Test @@ -911,11 +940,12 @@ public class GenericWindowPolicyControllerTest { private void assertActivityCanBeLaunched(GenericWindowPolicyController gwpc, int fromDisplay, boolean isNewTask, int windowingMode, ActivityInfo activityInfo) { + IntentSender intentSender = new IntentSender(new Binder()); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay, - isNewTask)).isTrue(); + isNewTask, /* isResultExpected= */ false, () -> intentSender)).isTrue(); verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never()) - .onActivityBlocked(fromDisplay, activityInfo); + .onActivityBlocked(fromDisplay, activityInfo, intentSender); verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class)); } @@ -927,23 +957,26 @@ public class GenericWindowPolicyControllerTest { private void assertActivityIsBlocked(GenericWindowPolicyController gwpc, int fromDisplay, boolean isNewTask, int windowingMode, ActivityInfo activityInfo) { + IntentSender intentSender = new IntentSender(new Binder()); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay, - isNewTask)).isFalse(); + isNewTask, /* isResultExpected= */ false, () -> intentSender)).isFalse(); verify(mActivityBlockedCallback, timeout(TIMEOUT_MILLIS)) - .onActivityBlocked(fromDisplay, activityInfo); + .onActivityBlocked(fromDisplay, activityInfo, intentSender); verify(mIntentListenerCallback, after(TIMEOUT_MILLIS).never()) .shouldInterceptIntent(any(Intent.class)); } private void assertNoActivityLaunched(GenericWindowPolicyController gwpc, int fromDisplay, ActivityInfo activityInfo) { + IntentSender intentSender = new IntentSender(new Binder()); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, true)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false, + /* isResultExpected= */ false, () -> intentSender)) .isFalse(); verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never()) - .onActivityBlocked(fromDisplay, activityInfo); + .onActivityBlocked(eq(fromDisplay), eq(activityInfo), any()); verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class)); } } 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 19712ea367d3..c2882124e6e3 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 @@ -314,7 +314,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); return blockedAppIntent; } @@ -1522,7 +1523,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext, never()).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1543,7 +1545,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1564,7 +1567,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext, never()).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1585,7 +1589,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1606,7 +1611,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1627,7 +1633,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1648,7 +1655,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1669,7 +1677,8 @@ public class VirtualDeviceManagerServiceTest { Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1691,7 +1700,8 @@ public class VirtualDeviceManagerServiceTest { /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/ false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isFalse(); // Verify that BlockedAppStreamingActivity also doesn't launch for mirror displays. Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( @@ -1716,7 +1726,8 @@ public class VirtualDeviceManagerServiceTest { /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/ false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1768,7 +1779,8 @@ public class VirtualDeviceManagerServiceTest { /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); assertThat(gwpc.canActivityBeLaunched(activityInfo, null, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); } @@ -1784,7 +1796,8 @@ public class VirtualDeviceManagerServiceTest { /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); } @@ -1815,7 +1828,8 @@ public class VirtualDeviceManagerServiceTest { // register interceptor and intercept intent mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isFalse(); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(interceptor).onIntentIntercepted(intentCaptor.capture()); @@ -1827,7 +1841,8 @@ public class VirtualDeviceManagerServiceTest { // unregister interceptor and launch activity mDeviceImpl.unregisterIntentInterceptor(interceptor); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); } @@ -1858,7 +1873,8 @@ public class VirtualDeviceManagerServiceTest { mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, + /* isResultExpected = */ false, /* intentSender= */ null)) .isTrue(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java index bb5887d12f4b..58f8eb220218 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java @@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.os.Process; import android.util.ArraySet; @@ -40,12 +41,14 @@ import android.view.Display; import android.window.DisplayWindowPolicyController; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Set; +import java.util.function.Supplier; /** * Tests for the {@link DisplayWindowPolicyController} class. @@ -224,7 +227,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { assertEquals(result, START_ABORTED); } - private class TestDisplayWindowPolicyController extends DisplayWindowPolicyController { + private static class TestDisplayWindowPolicyController extends DisplayWindowPolicyController { public ComponentName DISALLOWED_ACTIVITY = new ComponentName("fake.package", "DisallowedActivity"); @@ -236,7 +239,8 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { @Override public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, - boolean isNewTask) { + boolean isNewTask, boolean isResultExpected, + @Nullable Supplier<IntentSender> intentSender) { return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask); } |