diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java index 00e1f55e0b3d6..d736ede7e97ed 100644 --- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java +++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java @@ -19,6 +19,7 @@ package com.android.server.wm; import android.annotation.IntDef; import android.annotation.Nullable; import android.app.ActivityOptions; +import android.app.TaskInfo; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; @@ -39,6 +40,12 @@ public abstract class ActivityInterceptorCallback { */ public abstract @Nullable Intent intercept(ActivityInterceptorInfo info); + /** + * Called when an activity is successfully launched. + */ + public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo) { + } + /** * The unique id of each interceptor which determines the order it will execute in. */ diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index 223f0be9bbeaf..352a0709d0d2d 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -37,6 +37,7 @@ import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.KeyguardManager; +import android.app.TaskInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.IIntentSender; @@ -402,4 +403,16 @@ class ActivityStartInterceptor { mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/); return true; } + + /** + * Called when an activity is successfully launched. + */ + void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo) { + final SparseArray callbacks = + mService.getActivityInterceptorCallbacks(); + for (int i = 0; i < callbacks.size(); i++) { + final ActivityInterceptorCallback callback = callbacks.valueAt(i); + callback.onActivityLaunched(taskInfo, activityInfo); + } + } } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index bb7434d5092f5..471b4ce327794 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1559,6 +1559,10 @@ class ActivityStarter { mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( targetTask.getTaskInfo(), homeTaskVisible, clearedTask, visible); } + + if (ActivityManager.isStartResultSuccessful(result)) { + mInterceptor.onActivityLaunched(targetTask.getTaskInfo(), r.info); + } } /** 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 c103bc6fb9a13..3e617d58caa0b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -19,6 +19,10 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; @@ -327,4 +331,16 @@ public class ActivityStartInterceptorTest { assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } + + @Test + public void testActivityLaunchedCallback_singleCallback() { + addMockInterceptorCallback(null); + + assertEquals(1, mActivityInterceptorCallbacks.size()); + final ActivityInterceptorCallback callback = mActivityInterceptorCallbacks.valueAt(0); + spyOn(callback); + mInterceptor.onActivityLaunched(null, null); + + verify(callback, times(1)).onActivityLaunched(any(), any()); + } }