Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfb2141e authored by Mohammed Rashidy's avatar Mohammed Rashidy
Browse files

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
parent bf90f82c
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+2 −5
Original line number Diff line number Diff line
@@ -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;
    }
+1 −4
Original line number Diff line number Diff line
@@ -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(
+64 −4
Original line number Diff line number Diff line
@@ -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));
    }