From e5a896d56a10adec386a3c7213b6f5627cc6bfaa Mon Sep 17 00:00:00 2001 From: Ricky Wai Date: Thu, 19 May 2022 15:03:45 +0000 Subject: [PATCH] Add hidden flag for allowing system app to use BAL permission to launch pending intent in background Priv-app no longer use its BAL permission to launch background activity by default, it needs to use this new flag to allow this operation. Bug: 232921553 Test: PackageInstaller.Session.commit() no longer able to start BAL. Change-Id: Ifbc642a32dbebdf8854e7e5b1366cb899e971fa7 --- core/java/android/app/ComponentOptions.java | 30 +++++++++++++++++++ .../server/am/PendingIntentRecord.java | 11 +++++++ .../android/server/wm/ActivityStarter.java | 7 ++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/ComponentOptions.java b/core/java/android/app/ComponentOptions.java index d50a73a1f4c26..58732f0153187 100644 --- a/core/java/android/app/ComponentOptions.java +++ b/core/java/android/app/ComponentOptions.java @@ -38,7 +38,15 @@ public class ComponentOptions { public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED = "android.pendingIntent.backgroundActivityAllowed"; + /** + * PendingIntent caller allows activity to be started if caller has BAL permission. + * @hide + */ + public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION = + "android.pendingIntent.backgroundActivityAllowedByPermission"; + private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT; + private boolean mPendingIntentBalAllowedByPermission = false; ComponentOptions() { } @@ -50,6 +58,9 @@ public class ComponentOptions { setPendingIntentBackgroundActivityLaunchAllowed( opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, PENDING_INTENT_BAL_ALLOWED_DEFAULT)); + setPendingIntentBackgroundActivityLaunchAllowedByPermission( + opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, + false)); } /** @@ -68,9 +79,28 @@ public class ComponentOptions { return mPendingIntentBalAllowed; } + /** + * Set PendingIntent activity can be launched from background if caller has BAL permission. + * @hide + */ + public void setPendingIntentBackgroundActivityLaunchAllowedByPermission(boolean allowed) { + mPendingIntentBalAllowedByPermission = allowed; + } + + /** + * Get PendingIntent activity is allowed to be started in the background if the caller + * has BAL permission. + * @hide + */ + public boolean isPendingIntentBackgroundActivityLaunchAllowedByPermission() { + return mPendingIntentBalAllowedByPermission; + } + public Bundle toBundle() { Bundle b = new Bundle(); b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed); + b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, + mPendingIntentBalAllowedByPermission); return b; } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 81a8680cdbf0f..4044cceb606b2 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -310,6 +310,17 @@ public final class PendingIntentRecord extends IIntentSender.Stub { requiredPermission, null, null, 0, 0, 0, options); } + /** + * Return true if the activity options allows PendingIntent to use caller's BAL permission. + */ + public static boolean isPendingIntentBalAllowedByPermission( + @Nullable ActivityOptions activityOptions) { + if (activityOptions == null) { + return false; + } + return activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission(); + } + public static boolean isPendingIntentBalAllowedByCaller( @Nullable ActivityOptions activityOptions) { if (activityOptions == null) { diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index b97ee7ef76b3e..3af2ecd397598 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1365,10 +1365,9 @@ class ActivityStarter { PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions); if (balAllowedByPiSender && realCallingUid != callingUid) { - // If the caller is a legacy app, we won't check if the caller has BAL permission. - final boolean isPiBalOptionEnabled = CompatChanges.isChangeEnabled( - ENABLE_PENDING_INTENT_BAL_OPTION, realCallingUid); - if (isPiBalOptionEnabled && ActivityManager.checkComponentPermission( + final boolean useCallerPermission = + PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions); + if (useCallerPermission && ActivityManager.checkComponentPermission( android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, realCallingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {