summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java130
1 files changed, 92 insertions, 38 deletions
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index c2b5f88d0b4f..a3e1c8c90d32 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
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.ActivityTaskSupervisor.getApplicationLabel;
+import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator;
import static com.android.window.flags.Flags.balShowToasts;
import static com.android.window.flags.Flags.balShowToastsBlocked;
import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS;
@@ -42,9 +43,14 @@ import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.Overridable;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.provider.DeviceConfig;
@@ -79,6 +85,12 @@ public class BackgroundActivityStartController {
private static final long ASM_GRACEPERIOD_TIMEOUT_MS = TIMEOUT_MS;
private static final int ASM_GRACEPERIOD_MAX_REPEATS = 5;
private static final int NO_PROCESS_UID = -1;
+ /** If enabled the creator will not allow BAL on its behalf by default. */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Overridable
+ private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR =
+ 296478951;
public static final ActivityOptions ACTIVITY_OPTIONS_SYSTEM_DEFINED =
ActivityOptions.makeBasic()
.setPendingIntentBackgroundActivityStartMode(
@@ -264,12 +276,9 @@ public class BackgroundActivityStartController {
? BackgroundStartPrivileges.NONE
: BackgroundStartPrivileges.ALLOW_BAL;
} else {
- // for PendingIntents we restrict creator BAL based on target_sdk
- mBalAllowedByPiCreator =
- checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
- == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
- ? BackgroundStartPrivileges.NONE
- : BackgroundStartPrivileges.ALLOW_BAL;
+ // for PendingIntents we restrict BAL based on target_sdk
+ mBalAllowedByPiCreator = getBackgroundStartPrivilegesAllowedByCreator(
+ callingUid, callingPackage, checkedOptions);
}
mBalAllowedByPiSender =
PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
@@ -303,6 +312,45 @@ public class BackgroundActivityStartController {
}
}
+ private BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCreator(
+ int callingUid, String callingPackage, ActivityOptions checkedOptions) {
+ switch (checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()) {
+ case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED:
+ return BackgroundStartPrivileges.ALLOW_BAL;
+ case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED:
+ return BackgroundStartPrivileges.NONE;
+ case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED:
+ // no explicit choice by the app - let us decide what to do
+ Slog.i(TAG, "balRequireOptInByPendingIntentCreator = "
+ + balRequireOptInByPendingIntentCreator());
+ if (!balRequireOptInByPendingIntentCreator()) {
+ // if feature is disabled allow
+ return BackgroundStartPrivileges.ALLOW_BAL;
+ }
+ if (callingPackage != null) {
+ // determine based on the calling/creating package
+ boolean changeEnabled = CompatChanges.isChangeEnabled(
+ DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR,
+ callingPackage,
+ UserHandle.getUserHandleForUid(callingUid));
+ Slog.i(TAG, "changeEnabled = " + changeEnabled);
+ return changeEnabled ? BackgroundStartPrivileges.NONE
+ : BackgroundStartPrivileges.ALLOW_BAL;
+ }
+ // determine based on the calling/creating uid if we cannot determine the
+ // actual package name (e.g. shared uid)
+ boolean changeEnabled = CompatChanges.isChangeEnabled(
+ DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR,
+ callingUid);
+ Slog.i(TAG, "changeEnabled = " + changeEnabled);
+ return changeEnabled ? BackgroundStartPrivileges.NONE
+ : BackgroundStartPrivileges.ALLOW_BAL;
+ default:
+ throw new IllegalStateException("unsupported BackgroundActivityStartMode: "
+ + checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode());
+ }
+ }
+
private String getDebugPackageName(String packageName, int uid) {
if (packageName != null) {
return packageName; // use actual package
@@ -322,7 +370,7 @@ public class BackgroundActivityStartController {
}
private boolean isPendingIntent() {
- return mOriginatingPendingIntent != null;
+ return mOriginatingPendingIntent != null && hasRealCaller();
}
private String dump(BalVerdict resultIfPiCreatorAllowsBal) {
@@ -341,18 +389,23 @@ public class BackgroundActivityStartController {
.append(getDebugPackageName(mCallingPackage, mCallingUid));
sb.append("; callingUid: ").append(mCallingUid);
sb.append("; callingPid: ").append(mCallingPid);
- sb.append("; isPendingIntent: ").append(isPendingIntent());
sb.append("; appSwitchState: ").append(mAppSwitchState);
sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow);
sb.append("; callingUidProcState: ").append(DebugUtils.valueToString(
ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState));
sb.append("; isCallingUidPersistentSystemProcess: ")
.append(mIsCallingUidPersistentSystemProcess);
+ sb.append("; forcedBalByPiSender: ").append(mForcedBalByPiSender);
+ sb.append("; intent: ").append(mIntent);
+ sb.append("; callerApp: ").append(mCallerApp);
+ if (mCallerApp != null) {
+ sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask());
+ }
sb.append("; balAllowedByPiCreator: ").append(mBalAllowedByPiCreator);
+ sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal);
sb.append("; hasRealCaller: ").append(hasRealCaller());
sb.append("; isPendingIntent: ").append(isPendingIntent());
if (hasRealCaller()) {
- sb.append("; balAllowedByPiSender: ").append(mBalAllowedByPiSender);
sb.append("; realCallingPackage: ")
.append(getDebugPackageName(mRealCallingPackage, mRealCallingUid));
sb.append("; realCallingUid: ").append(mRealCallingUid);
@@ -364,24 +417,14 @@ public class BackgroundActivityStartController {
sb.append("; isRealCallingUidPersistentSystemProcess: ")
.append(mIsRealCallingUidPersistentSystemProcess);
sb.append("; originatingPendingIntent: ").append(mOriginatingPendingIntent);
- }
- sb.append("; mForcedBalByPiSender: ").append(mForcedBalByPiSender);
- sb.append("; intent: ").append(mIntent);
- sb.append("; callerApp: ").append(mCallerApp);
- if (hasRealCaller()) {
sb.append("; realCallerApp: ").append(mRealCallerApp);
- }
- if (mCallerApp != null) {
- sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask());
- }
- if (hasRealCaller()) {
if (mRealCallerApp != null) {
sb.append("; realInVisibleTask: ")
.append(mRealCallerApp.hasActivityInVisibleTask());
}
+ sb.append("; balAllowedByPiSender: ").append(mBalAllowedByPiSender);
sb.append("; resultIfPiSenderAllowsBal: ").append(resultIfPiSenderAllowsBal);
}
- sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal);
sb.append("]");
return sb.toString();
}
@@ -416,10 +459,9 @@ public class BackgroundActivityStartController {
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append(". BAL Code: ");
builder.append(balCodeToString(mCode));
if (DEBUG_ACTIVITY_STARTS) {
- builder.append(" ");
+ builder.append(" (");
if (mBackground) {
builder.append("Background ");
}
@@ -433,6 +475,7 @@ public class BackgroundActivityStartController {
builder.append(" ");
builder.append(mProcessInfo);
}
+ builder.append(")");
}
return builder.toString();
}
@@ -551,29 +594,40 @@ public class BackgroundActivityStartController {
&& checkedOptions.getPendingIntentBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
// Both caller and real caller allow with system defined behavior
+ if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) {
+ Slog.wtf(TAG,
+ "With Android 15 BAL hardening this activity start may be blocked"
+ + " if the PI creator upgrades target_sdk to 35+"
+ + " AND the PI sender upgrades target_sdk to 34+! "
+ + state.dump(resultForCaller, resultForRealCaller));
+ showBalRiskToast("BAL would be blocked", state);
+ // return the realCaller result for backwards compatibility
+ return statsLog(resultForRealCaller, state);
+ }
Slog.wtf(TAG,
- "With Android 15 BAL hardening this activity start may be blocked"
- + " if the PI creator upgrades target_sdk to 35+"
- + " AND the PI sender upgrades target_sdk to 34+! "
- + " (missing opt in by PI creator)! "
+ "Without Android 15 BAL hardening this activity start would be allowed"
+ + " (missing opt in by PI creator or sender)! "
+ state.dump(resultForCaller, resultForRealCaller));
- showBalRiskToast("BAL would be blocked", state);
- // return the realCaller result for backwards compatibility
- return statsLog(resultForRealCaller, state);
- }
- if (resultForCaller.allows()
+ // fall through to abort
+ } else if (resultForCaller.allows()
&& checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
// Allowed before V by creator
+ if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) {
+ Slog.wtf(TAG,
+ "With Android 15 BAL hardening this activity start may be blocked"
+ + " if the PI creator upgrades target_sdk to 35+! "
+ + " (missing opt in by PI creator)! "
+ + state.dump(resultForCaller, resultForRealCaller));
+ showBalRiskToast("BAL would be blocked", state);
+ return statsLog(resultForCaller, state);
+ }
Slog.wtf(TAG,
- "With Android 15 BAL hardening this activity start may be blocked"
- + " if the PI creator upgrades target_sdk to 35+! "
+ "Without Android 15 BAL hardening this activity start would be allowed"
+ " (missing opt in by PI creator)! "
+ state.dump(resultForCaller, resultForRealCaller));
- showBalRiskToast("BAL would be blocked", state);
- return statsLog(resultForCaller, state);
- }
- if (resultForRealCaller.allows()
+ // fall through to abort
+ } else if (resultForRealCaller.allows()
&& checkedOptions.getPendingIntentBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
// Allowed before U by sender
@@ -589,7 +643,7 @@ public class BackgroundActivityStartController {
Slog.wtf(TAG, "Without Android 14 BAL hardening this activity start would be allowed"
+ " (missing opt in by PI sender)! "
+ state.dump(resultForCaller, resultForRealCaller));
- // fall through
+ // fall through to abort
}
// anything that has fallen through would currently be aborted
Slog.w(TAG, "Background activity launch blocked! "