Merge "Added Exemption Check for OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION"

This commit is contained in:
Alex Johnston
2023-02-15 10:06:02 +00:00
committed by Android (Google) Code Review
4 changed files with 74 additions and 40 deletions

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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()) {

View File

@@ -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 =