Add package and component checks to intercept sandbox activity intent

Apply sandbox activity checks and interception if the intent is related
to the sandbox activities by any way, for that package and component
checks are added.
In case the intent's package or component refer to the sandbox activity,
sandbox service will be called.

Bug: 274592326
Test: com.android.server.wm.ActivityStartInterceptorTest

Change-Id: I2bcb62f76211243e53a1ac7208351d3f31843660
This commit is contained in:
Mohammed Rashidy
2023-04-15 04:11:56 +01:00
parent bf90f82cb4
commit bfb2141e2d
4 changed files with 83 additions and 13 deletions

View File

@@ -16,6 +16,7 @@
package android.content;
import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY;
import static android.content.ContentProvider.maybeAddUserId;
import android.Manifest;
@@ -12463,4 +12464,19 @@ public class Intent implements Parcelable, Cloneable {
public boolean isDocument() {
return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT;
}
/** @hide */
public boolean isSandboxActivity(@NonNull Context context) {
if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) {
return true;
}
final String sandboxPackageName = context.getPackageManager().getSdkSandboxPackageName();
if (mPackage != null && mPackage.equals(sandboxPackageName)) {
return true;
}
if (mComponent != null && mComponent.getPackageName().equals(sandboxPackageName)) {
return true;
}
return false;
}
}

View File

@@ -23,7 +23,6 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.app.admin.DevicePolicyManager.EXTRA_RESTRICTION;
import static android.app.admin.DevicePolicyManager.POLICY_SUSPEND_PACKAGES;
import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Intent.EXTRA_INTENT;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
@@ -503,8 +502,7 @@ class ActivityStartInterceptor {
@ActivityInterceptorCallback.OrderedId int orderId,
@NonNull ActivityInterceptorCallback.ActivityInterceptorInfo info) {
if (orderId == MAINLINE_SDK_SANDBOX_ORDER_ID) {
return info.getIntent() != null && info.getIntent().getAction() != null
&& info.getIntent().getAction().equals(ACTION_START_SANDBOXED_ACTIVITY);
return info.getIntent() != null && info.getIntent().isSandboxActivity(mServiceContext);
}
return true;
}
@@ -513,8 +511,7 @@ class ActivityStartInterceptor {
@ActivityInterceptorCallback.OrderedId int orderId,
@NonNull ActivityInterceptorCallback.ActivityInterceptorInfo info) {
if (orderId == MAINLINE_SDK_SANDBOX_ORDER_ID) {
return info.getIntent() != null && info.getIntent().getAction() != null
&& info.getIntent().getAction().equals(ACTION_START_SANDBOXED_ACTIVITY);
return info.getIntent() != null && info.getIntent().isSandboxActivity(mServiceContext);
}
return true;
}

View File

@@ -38,7 +38,6 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -1244,9 +1243,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
boolean isSandboxedActivity = (intent != null && intent.getAction() != null
&& intent.getAction().equals(ACTION_START_SANDBOXED_ACTIVITY));
if (isSandboxedActivity) {
if (intent != null && intent.isSandboxActivity(mContext)) {
SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
SdkSandboxManagerLocal.class);
sdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity(

View File

@@ -44,11 +44,13 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
@@ -445,12 +447,15 @@ public class ActivityStartInterceptorTest {
}
@Test
public void testSandboxServiceInterceptionHappensToSandboxedActivityAction()
throws InterruptedException {
public void testSandboxServiceInterceptionHappensToIntentWithSandboxActivityAction() {
ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
PackageManager packageManagerMock = mock(PackageManager.class);
String sandboxPackageNameMock = "com.sandbox.mock";
when(mContext.getPackageManager()).thenReturn(packageManagerMock);
when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY);
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
@@ -459,13 +464,68 @@ public class ActivityStartInterceptorTest {
}
@Test
public void testSandboxServiceInterceptionNotCalledForNotSandboxedActivityAction() {
public void testSandboxServiceInterceptionHappensToIntentWithSandboxPackage() {
ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
PackageManager packageManagerMock = mock(PackageManager.class);
String sandboxPackageNameMock = "com.sandbox.mock";
when(mContext.getPackageManager()).thenReturn(packageManagerMock);
when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
Intent intent = new Intent().setPackage(sandboxPackageNameMock);
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
verify(spyCallback, times(1)).onInterceptActivityLaunch(
any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
}
@Test
public void testSandboxServiceInterceptionHappensToIntentWithComponentNameWithSandboxPackage() {
ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
PackageManager packageManagerMock = mock(PackageManager.class);
String sandboxPackageNameMock = "com.sandbox.mock";
when(mContext.getPackageManager()).thenReturn(packageManagerMock);
when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
Intent intent = new Intent().setComponent(new ComponentName(sandboxPackageNameMock, ""));
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
verify(spyCallback, times(1)).onInterceptActivityLaunch(
any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
}
@Test
public void testSandboxServiceInterceptionNotCalledWhenIntentNotRelatedToSandbox() {
ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
PackageManager packageManagerMock = mock(PackageManager.class);
String sandboxPackageNameMock = "com.sandbox.mock";
when(mContext.getPackageManager()).thenReturn(packageManagerMock);
when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
// Intent: null
mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null);
// Action: null, Package: null, ComponentName: null
Intent intent = new Intent();
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
// Wrong Action
intent = new Intent().setAction(Intent.ACTION_VIEW);
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
// Wrong Package
intent = new Intent().setPackage("Random");
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
// Wrong ComponentName's package
intent = new Intent().setComponent(new ComponentName("Random", ""));
mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null);
verify(spyCallback, never()).onInterceptActivityLaunch(
any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
}