From 7fe54164cdf6194d059d306908f39a579e341fdd Mon Sep 17 00:00:00 2001 From: Maurice Lam Date: Tue, 14 Dec 2021 23:11:46 -0800 Subject: [PATCH] Allow modifying ActivityOptions in ActivityInterceptorCallback Change ActivityInterceptorCallback to return ActivityInterceptResult, which contains both an intent and an activity options object. Bug: 194949534 Test: atest CommunalManagerServiceTest Change-Id: I81ea0b440e9dc862d8a804707dfb2bfbeae9ef21 --- .../communal/CommunalManagerService.java | 8 +++--- .../wm/ActivityInterceptorCallback.java | 25 ++++++++++++++--- .../server/wm/ActivityStartInterceptor.java | 8 +++--- .../wm/ActivityStartInterceptorTest.java | 27 +++++++++++++------ .../wm/ActivityTaskManagerServiceTests.java | 11 ++++---- 5 files changed, 55 insertions(+), 24 deletions(-) diff --git a/services/core/java/com/android/server/communal/CommunalManagerService.java b/services/core/java/com/android/server/communal/CommunalManagerService.java index 3bf6ca2dac0d4..df95bf597dc08 100644 --- a/services/core/java/com/android/server/communal/CommunalManagerService.java +++ b/services/core/java/com/android/server/communal/CommunalManagerService.java @@ -87,7 +87,7 @@ public final class CommunalManagerService extends SystemService { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { if (!shouldIntercept(info.aInfo)) { if (DEBUG) { Slog.d(TAG, "Activity allowed, not intercepting: " @@ -110,8 +110,10 @@ public final class CommunalManagerService extends SystemService { PendingIntent.FLAG_IMMUTABLE, /* bOptions= */ null); - return LaunchAfterAuthenticationActivity.createLaunchAfterAuthenticationIntent( - new IntentSender(target)); + return new ActivityInterceptResult( + LaunchAfterAuthenticationActivity.createLaunchAfterAuthenticationIntent( + new IntentSender(target)), + info.checkedOptions); } }; diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java index d736ede7e97ed..30cd3c4ab8bf8 100644 --- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java +++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.TaskInfo; @@ -33,12 +34,13 @@ import java.lang.annotation.RetentionPolicy; public abstract class ActivityInterceptorCallback { /** * Intercept the launch intent based on various signals. If an interception happened, returns - * a new/existing non-null {@link Intent} which may redirect to another activity. + * a new/existing non-null {@link ActivityInterceptResult} which may redirect to another + * activity or with new {@link ActivityOptions}. * - * @return null if no interception occurred, or a non-null intent which replaces the - * existing intent. + * @return null if no interception occurred, or a non-null result which replaces the existing + * intent and activity options. */ - public abstract @Nullable Intent intercept(ActivityInterceptorInfo info); + public abstract @Nullable ActivityInterceptResult intercept(ActivityInterceptorInfo info); /** * Called when an activity is successfully launched. @@ -108,4 +110,19 @@ public abstract class ActivityInterceptorCallback { this.checkedOptions = checkedOptions; } } + + /** + * Data class for storing the intercept result. + */ + public static final class ActivityInterceptResult { + @NonNull public final Intent intent; + @NonNull public final ActivityOptions activityOptions; + + public ActivityInterceptResult( + @NonNull Intent intent, + @NonNull ActivityOptions activityOptions) { + this.intent = intent; + this.activityOptions = activityOptions; + } + } } diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index 352a0709d0d2d..658a17bd9ec78 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -61,6 +61,7 @@ import com.android.internal.app.SuspendedAppActivity; import com.android.internal.app.UnlaunchableAppActivity; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; +import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} @@ -194,11 +195,12 @@ class ActivityStartInterceptor { for (int i = 0; i < callbacks.size(); i++) { final ActivityInterceptorCallback callback = callbacks.valueAt(i); - final Intent newIntent = callback.intercept(interceptorInfo); - if (newIntent == null) { + final ActivityInterceptResult interceptResult = callback.intercept(interceptorInfo); + if (interceptResult == null) { continue; } - mIntent = newIntent; + mIntent = interceptResult.intent; + mActivityOptions = interceptResult.activityOptions; mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mRInfo = mSupervisor.resolveIntent(mIntent, null, mUserId, 0, mRealCallingUid); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 3e617d58caa0b..55d6df95e66f8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.nullable; import android.annotation.Nullable; import android.app.ActivityManagerInternal; +import android.app.ActivityOptions; import android.app.KeyguardManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; @@ -58,6 +59,7 @@ import com.android.internal.app.UnlaunchableAppActivity; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; import com.android.server.pm.PackageManagerService; +import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; import org.junit.After; import org.junit.Before; @@ -298,35 +300,44 @@ public class ActivityStartInterceptorTest { assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); } - public void addMockInterceptorCallback(@Nullable Intent intent) { + public void addMockInterceptorCallback( + @Nullable Intent intent, @Nullable ActivityOptions activityOptions) { int size = mActivityInterceptorCallbacks.size(); mActivityInterceptorCallbacks.put(size, new ActivityInterceptorCallback() { @Override - public Intent intercept(ActivityInterceptorInfo info) { - return intent; + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { + if (intent == null && activityOptions == null) { + return null; + } + return new ActivityInterceptResult( + intent != null ? intent : info.intent, + activityOptions != null ? activityOptions : info.checkedOptions); } }); } @Test public void testInterceptionCallback_singleCallback() { - addMockInterceptorCallback(new Intent("android.test.foo")); + addMockInterceptorCallback( + new Intent("android.test.foo"), + ActivityOptions.makeBasic().setLaunchDisplayId(3)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); + assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } @Test public void testInterceptionCallback_singleCallbackReturnsNull() { - addMockInterceptorCallback(null); + addMockInterceptorCallback(null, null); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); } @Test public void testInterceptionCallback_fallbackToSecondCallback() { - addMockInterceptorCallback(null); - addMockInterceptorCallback(new Intent("android.test.second")); + addMockInterceptorCallback(null, null); + addMockInterceptorCallback(new Intent("android.test.second"), null); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); @@ -334,7 +345,7 @@ public class ActivityStartInterceptorTest { @Test public void testActivityLaunchedCallback_singleCallback() { - addMockInterceptorCallback(null); + addMockInterceptorCallback(null, null); assertEquals(1, mActivityInterceptorCallbacks.size()); final ActivityInterceptorCallback callback = mActivityInterceptorCallbacks.valueAt(0); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index e0072b441577a..a2b04c2959449 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -53,7 +53,6 @@ import android.app.IApplicationThread; import android.app.PictureInPictureParams; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.EnterPipRequestedItem; -import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.res.Configuration; @@ -951,7 +950,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { return null; } }); @@ -963,7 +962,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { return null; } }); @@ -975,7 +974,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { return null; } }); @@ -983,7 +982,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { return null; } }); @@ -997,7 +996,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { new ActivityInterceptorCallback() { @Nullable @Override - public Intent intercept(ActivityInterceptorInfo info) { + public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { return null; } });