Loading services/core/java/com/android/server/communal/CommunalManagerService.java +5 −3 Original line number Diff line number Diff line Loading @@ -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: " Loading @@ -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); } }; Loading services/core/java/com/android/server/wm/ActivityInterceptorCallback.java +21 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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; } } } services/core/java/com/android/server/wm/ActivityStartInterceptor.java +5 −3 Original line number Diff line number Diff line Loading @@ -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} Loading Loading @@ -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); Loading services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +19 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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()); Loading @@ -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); Loading services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +5 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading Loading
services/core/java/com/android/server/communal/CommunalManagerService.java +5 −3 Original line number Diff line number Diff line Loading @@ -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: " Loading @@ -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); } }; Loading
services/core/java/com/android/server/wm/ActivityInterceptorCallback.java +21 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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; } } }
services/core/java/com/android/server/wm/ActivityStartInterceptor.java +5 −3 Original line number Diff line number Diff line Loading @@ -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} Loading Loading @@ -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); Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +19 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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()); Loading @@ -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); Loading
services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +5 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading @@ -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; } }); Loading