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

Commit 223f197e authored by Alex Johnston's avatar Alex Johnston Committed by Android (Google) Code Review
Browse files

Merge "Added Exemption Check for OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION"

parents 40490e83 0324c82d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -77,9 +77,9 @@ import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_COMPONENT;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_UID;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BAL_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
@@ -1937,7 +1937,7 @@ class ActivityStarter {
        // BAL exception only allowed for new tasks
        if (taskToFront) {
            if (mBalCode == BAL_ALLOW_ALLOWLISTED_COMPONENT
                    || mBalCode == BAL_ALLOW_BAL_PERMISSION
                    || mBalCode == BAL_ALLOW_PERMISSION
                    || mBalCode == BAL_ALLOW_PENDING_INTENT) {
                return true;
            }
+24 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.wm;

import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;

import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
@@ -31,6 +32,7 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
import android.app.ComponentOptions;
import android.content.ComponentName;
@@ -38,6 +40,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.Slog;
@@ -67,7 +70,7 @@ public class BackgroundActivityStartController {
            BAL_ALLOW_ALLOWLISTED_COMPONENT,
            BAL_ALLOW_VISIBLE_WINDOW,
            BAL_ALLOW_PENDING_INTENT,
            BAL_ALLOW_BAL_PERMISSION,
            BAL_ALLOW_PERMISSION,
            BAL_ALLOW_SAW_PERMISSION,
            BAL_ALLOW_GRACE_PERIOD,
            BAL_ALLOW_FOREGROUND,
@@ -96,7 +99,7 @@ public class BackgroundActivityStartController {

    /** App has START_ACTIVITIES_FROM_BACKGROUND permission or BAL instrumentation privileges
     * granted to it */
    static final int BAL_ALLOW_BAL_PERMISSION = 6;
    static final int BAL_ALLOW_PERMISSION = 6;

    /** Process has SYSTEM_ALERT_WINDOW permission granted to it */
    static final int BAL_ALLOW_SAW_PERMISSION = 7;
@@ -310,7 +313,7 @@ public class BackgroundActivityStartController {
            if (ActivityTaskManagerService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND,
                    callingPid, callingUid) == PERMISSION_GRANTED) {
                return logStartAllowedAndReturnCode(/*background*/ true, callingUid,
                        BAL_ALLOW_BAL_PERMISSION,
                    BAL_ALLOW_PERMISSION,
                        "START_ACTIVITIES_FROM_BACKGROUND permission granted");
            }
            // don't abort if the caller has the same uid as the recents component
@@ -339,6 +342,17 @@ public class BackgroundActivityStartController {
                return logStartAllowedAndReturnCode(/*background*/ true, callingUid,
                        BAL_ALLOW_SAW_PERMISSION, "SYSTEM_ALERT_WINDOW permission is granted");
            }
            // don't abort if the callingUid and callingPackage have the
            // OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop
            if (isSystemExemptFlagEnabled() && mService.getAppOpsManager().checkOpNoThrow(
                    AppOpsManager.OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION,
                    callingUid,
                    callingPackage)
                    == AppOpsManager.MODE_ALLOWED) {
                return logStartAllowedAndReturnCode(/*background*/ true, callingUid,
                    BAL_ALLOW_PERMISSION,
                    "OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop is granted");
            }
        }
        // If we don't have callerApp at this point, no caller was provided to startActivity().
        // That's the case for PendingIntent-based starts, since the creator's process might not be
@@ -461,4 +475,11 @@ public class BackgroundActivityStartController {
        }
        return code;
    }

    private static boolean isSystemExemptFlagEnabled() {
        return DeviceConfig.getBoolean(
                NAMESPACE_WINDOW_MANAGER,
                /* name= */ "system_exempt_from_activity_bg_start_restriction_enabled",
                /* defaultValue= */ true);
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -23,9 +23,9 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BAL_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;

@@ -109,7 +109,7 @@ class BackgroundLaunchProcessController {
                        + ")] Activity start allowed: process instrumenting with background "
                        + "activity starts privileges");
            }
            return BAL_ALLOW_BAL_PERMISSION;
            return BAL_ALLOW_PERMISSION;
        }
        // Allow if the flag was explicitly set.
        if (isBackgroundStartAllowedByToken(uid, packageName, isCheckingForFgsStart)) {
@@ -117,7 +117,7 @@ class BackgroundLaunchProcessController {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process allowed by token");
            }
            return BAL_ALLOW_BAL_PERMISSION;
            return BAL_ALLOW_PERMISSION;
        }
        // Allow if the caller is bound by a UID that's currently foreground.
        if (isBoundByForegroundUid()) {
+45 −32
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;

import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
import android.app.IApplicationThread;
import android.app.PictureInPictureParams;
@@ -160,6 +161,7 @@ public class ActivityStarterTests extends WindowTestsBase {
    private ActivityStartController mController;
    private ActivityMetricsLogger mActivityMetricsLogger;
    private PackageManagerInternal mMockPackageManager;
    private AppOpsManager mAppOpsManager;

    @Before
    public void setUp() throws Exception {
@@ -169,6 +171,10 @@ public class ActivityStarterTests extends WindowTestsBase {
        doReturn(balController).when(mController).getBackgroundActivityLaunchController();
        mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
        clearInvocations(mActivityMetricsLogger);
        mAppOpsManager = mAtm.getAppOpsManager();
        doReturn(AppOpsManager.MODE_DEFAULT).when(mAppOpsManager).checkOpNoThrow(
                eq(AppOpsManager.OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION),
                anyInt(), any());
        mDeviceConfig.set(ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER,
                String.valueOf(true));
    }
@@ -635,7 +641,7 @@ public class ActivityStarterTests extends WindowTestsBase {
        runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -649,7 +655,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_unsupportedUsecase_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -663,7 +669,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callingUidProcessStateTop_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -677,7 +683,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_realCallingUidProcessStateTop_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -691,7 +697,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_hasForegroundActivities_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                true, false, false, false, false);
                true, false, false, false, false, false, false);
    }

    /**
@@ -705,7 +711,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_pinned_singleinstance_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false, true);
                false, false, false, false, false, true, false);
    }

    /**
@@ -719,7 +725,7 @@ public class ActivityStarterTests extends WindowTestsBase {
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
                Process.ROOT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -733,7 +739,7 @@ public class ActivityStarterTests extends WindowTestsBase {
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
                Process.SYSTEM_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -747,7 +753,7 @@ public class ActivityStarterTests extends WindowTestsBase {
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false,
                Process.NFC_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -762,7 +768,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callingUidHasVisibleWindow_notAborted", false,
                UNIMPORTANT_UID, true, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -778,7 +784,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_realCallingUidHasVisibleWindow_abortedInU", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, true, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false, false);
                false, false, false, false, false, false, false);
    }

    /**
@@ -793,7 +799,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callerIsRecents_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, true, false, false, false);
                false, true, false, false, false, false, false);
    }

    /**
@@ -808,7 +814,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callerIsAllowed_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, true, false, false);
                false, false, true, false, false, false, false);
    }

    /**
@@ -824,7 +830,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, true, false);
                false, false, false, true, false, false, false);
    }

    /**
@@ -840,7 +846,22 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callingPackageNameIsDeviceOwner_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, true);
                false, false, false, false, true, false, false);
    }

    /**
     * This test ensures that supported usecases aren't aborted when background starts are
     * disallowed. Each scenarios tests one condition that makes them supported in isolation. In
     * this case the caller has the OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop.
     */
    @Test
    public void testBackgroundActivityStartsDisallowed_callerHasSystemExemptAppOpNotAborted() {
        doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_callerHasSystemExemptAppOpNotAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false, false, true);
    }

    /**
@@ -856,22 +877,7 @@ public class ActivityStarterTests extends WindowTestsBase {
                "disallowed_callingPackageNameIsIme_notAborted", false,
                CURRENT_IME_UID, false, PROCESS_STATE_BOUND_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
                false, false, false, false, false);
    }

    private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
            int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState,
            int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState,
            boolean hasForegroundActivities, boolean callerIsRecents,
            boolean callerIsTempAllowed,
            boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
            boolean isCallingUidDeviceOwner) {
        runAndVerifyBackgroundActivityStartsSubtest(name, shouldHaveAborted, callingUid,
                callingUidHasVisibleWindow, callingUidProcState, realCallingUid,
                realCallingUidHasVisibleWindow, realCallingUidProcState,
                hasForegroundActivities, callerIsRecents, callerIsTempAllowed,
                callerIsInstrumentingWithBackgroundActivityStartPrivileges,
                isCallingUidDeviceOwner, false /* isPinnedSingleInstance */);
                false, false, false, false, false, false, false);
    }

    private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -881,7 +887,8 @@ public class ActivityStarterTests extends WindowTestsBase {
            boolean callerIsTempAllowed,
            boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
            boolean isCallingUidDeviceOwner,
            boolean isPinnedSingleInstance) {
            boolean isPinnedSingleInstance,
            boolean hasSystemExemptAppOp) {
        // window visibility
        doReturn(callingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(callingUid);
        doReturn(realCallingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(realCallingUid);
@@ -914,6 +921,12 @@ public class ActivityStarterTests extends WindowTestsBase {
        // callingUid is the device owner
        doReturn(isCallingUidDeviceOwner).when(mAtm).isDeviceOwner(callingUid);

        // caller has OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop
        doReturn(hasSystemExemptAppOp ? AppOpsManager.MODE_ALLOWED
                : AppOpsManager.MODE_DEFAULT).when(mAppOpsManager).checkOpNoThrow(
                eq(AppOpsManager.OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION),
                anyInt(), any());

        int launchMode = LAUNCH_MULTIPLE;
        if (isPinnedSingleInstance) {
            final ActivityRecord baseActivity =