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
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user