diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index db42803ac9f9f..a24555f79a1c7 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -4272,7 +4272,8 @@ public class ActivityManager { try { getService().broadcastIntentWithFeature( null, null, intent, null, null, Activity.RESULT_OK, null, null, - null /*permission*/, appOp, null, false, true, userId); + null /*requiredPermissions*/, null /*excludedPermissions*/, appOp, null, false, + true, userId); } catch (RemoteException ex) { } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index f7ea3815d567c..9753b6748c786 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1176,8 +1176,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, - false, getUserId()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1194,7 +1194,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, null, false, false, getUserId()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1209,7 +1210,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, null, false, false, getUserId()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1224,7 +1226,24 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + user.getIdentifier()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Override + public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, + String[] excludedPermissions) { + warnIfCallingFromSystemProcess(); + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.prepareToLeaveProcess(this); + ActivityManager.getService().broadcastIntentWithFeature( + mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, + null, Activity.RESULT_OK, null, null, receiverPermissions, excludedPermissions, + AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1241,7 +1260,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, options, false, false, getUserId()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1257,8 +1277,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, - false, getUserId()); + null, Activity.RESULT_OK, null, null, receiverPermissions, + null /*excludedPermissions=*/, appOp, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1275,7 +1295,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, null, true, false, getUserId()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, false, + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1337,8 +1358,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - rd, initialCode, initialData, initialExtras, receiverPermissions, appOp, - options, true, false, getUserId()); + rd, initialCode, initialData, initialExtras, receiverPermissions, + null /*excludedPermissions=*/, appOp, options, true, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1351,8 +1372,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, - false, user.getIdentifier()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1375,7 +1396,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - AppOpsManager.OP_NONE, options, false, false, user.getIdentifier()); + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, + user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1391,8 +1413,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, - false, user.getIdentifier()); + null, Activity.RESULT_OK, null, null, receiverPermissions, + null /*excludedPermissions=*/, appOp, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1442,8 +1464,9 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - rd, initialCode, initialData, initialExtras, receiverPermissions, appOp, - options, true, false, user.getIdentifier()); + rd, initialCode, initialData, initialExtras, receiverPermissions, + null /*excludedPermissions=*/, appOp, options, true, false, + user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1483,8 +1506,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, - true, getUserId()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, null, false, true, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1522,8 +1545,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, options, - false, true, getUserId()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, options, false, true, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1558,8 +1581,9 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - rd, initialCode, initialData, initialExtras, null, AppOpsManager.OP_NONE, null, - true, true, getUserId()); + rd, initialCode, initialData, initialExtras, null, + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1590,8 +1614,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, - true, user.getIdentifier()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, null, false, true, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1605,8 +1629,8 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, options, - false, true, user.getIdentifier()); + null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, + AppOpsManager.OP_NONE, options, false, true, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1640,8 +1664,9 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, - rd, initialCode, initialData, initialExtras, null, AppOpsManager.OP_NONE, null, - true, true, user.getIdentifier()); + rd, initialCode, initialData, initialExtras, null, + null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, + user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index f9279da172a08..89d90a3b9d6f2 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -137,7 +137,7 @@ interface IActivityManager { int appOp, in Bundle options, boolean serialized, boolean sticky, int userId); int broadcastIntentWithFeature(in IApplicationThread caller, in String callingFeatureId, in Intent intent, in String resolvedType, in IIntentReceiver resultTo, int resultCode, - in String resultData, in Bundle map, in String[] requiredPermissions, + in String resultData, in Bundle map, in String[] requiredPermissions, in String[] excludePermissions, int appOp, in Bundle options, boolean serialized, boolean sticky, int userId); void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId); @UnsupportedAppUsage diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 09ac8103c5260..318913f3bec0a 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2207,6 +2207,17 @@ public abstract class Context { throw new RuntimeException("Not implemented. Must override in a subclass."); } + /** + * Like {@link #sendBroadcastMultiplePermissions(Intent, String[])}, but also allows + * specification of a list of excluded permissions. This allows sending a broadcast to an + * app that has the permissions in `receiverPermissions` but not `excludedPermissions`. + * @hide + */ + public void sendBroadcastMultiplePermissions(@NonNull Intent intent, + @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + /** * Broadcast the given intent to all interested BroadcastReceivers, allowing * an array of required permissions to be enforced. This call is asynchronous; it returns diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 8936d0c47a58d..dddcbea638726 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -491,6 +491,13 @@ public class ContextWrapper extends Context { mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions); } + /** @hide */ + @Override + public void sendBroadcastMultiplePermissions(@NonNull Intent intent, + @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions) { + mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions); + } + /** @hide */ @Override public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2a1a8971ec8c8..e3b06d6964236 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2500,7 +2500,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void batterySendBroadcast(Intent intent) { synchronized (this) { - broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, + broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, null, OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } @@ -3940,7 +3940,7 @@ public class ActivityManagerService extends IActivityManager.Stub intent.putExtra(Intent.EXTRA_UID, uid); intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); broadcastIntentLocked(null, null, null, intent, - null, null, 0, null, null, null, OP_NONE, + null, null, 0, null, null, null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.getUserId(uid)); } @@ -7531,7 +7531,7 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, null, intent, - null, null, 0, null, null, null, OP_NONE, + null, null, 0, null, null, null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, currentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); @@ -7543,8 +7543,8 @@ public class ActivityManagerService extends IActivityManager.Stub public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {} - }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, OP_NONE, null, - true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, null, OP_NONE, + null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, UserHandle.USER_ALL); } catch (Throwable e) { Slog.wtf(TAG, "Failed sending first user broadcasts", e); @@ -12302,7 +12302,7 @@ public class ActivityManagerService extends IActivityManager.Stub Intent intent = allSticky.get(i); BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, null, - null, null, -1, -1, false, null, null, OP_NONE, null, receivers, + null, null, -1, -1, false, null, null, null, OP_NONE, null, receivers, null, 0, null, null, false, true, true, -1, false, null, false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */); queue.enqueueParallelBroadcastLocked(r); @@ -12544,13 +12544,13 @@ public class ActivityManagerService extends IActivityManager.Stub final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, String callerFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, - int realCallingPid, int userId) { + Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions, + int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, + int callingUid, int realCallingUid, int realCallingPid, int userId) { return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, - appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, - realCallingPid, userId, false /* allowBackgroundActivityStarts */, + excludedPermissions, appOp, bOptions, ordered, sticky, callingPid, callingUid, + realCallingUid, realCallingPid, userId, false /* allowBackgroundActivityStarts */, null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */); } @@ -12558,9 +12558,11 @@ public class ActivityManagerService extends IActivityManager.Stub final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, @Nullable String callerFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, - int realCallingPid, int userId, boolean allowBackgroundActivityStarts, + Bundle resultExtras, String[] requiredPermissions, + String[] excludedPermissions, int appOp, Bundle bOptions, + boolean ordered, boolean sticky, int callingPid, int callingUid, + int realCallingUid, int realCallingPid, int userId, + boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken, @Nullable int[] broadcastAllowList) { intent = new Intent(intent); @@ -13139,8 +13141,8 @@ public class ActivityManagerService extends IActivityManager.Stub final BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, - resultCode, resultData, resultExtras, ordered, sticky, false, userId, + requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers, + resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, allowBackgroundActivityStarts, backgroundActivityStartsToken, timeoutExempt); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); @@ -13237,10 +13239,10 @@ public class ActivityManagerService extends IActivityManager.Stub BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, - resultData, resultExtras, ordered, sticky, false, userId, - allowBackgroundActivityStarts, backgroundActivityStartsToken, - timeoutExempt); + requiredPermissions, excludedPermissions, appOp, brOptions, + receivers, resultTo, resultCode, resultData, resultExtras, + ordered, sticky, false, userId, allowBackgroundActivityStarts, + backgroundActivityStartsToken, timeoutExempt); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r); @@ -13366,14 +13368,14 @@ public class ActivityManagerService extends IActivityManager.Stub String[] requiredPermissions, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId) { return broadcastIntentWithFeature(caller, null, intent, resolvedType, resultTo, resultCode, - resultData, resultExtras, requiredPermissions, appOp, bOptions, serialized, sticky, - userId); + resultData, resultExtras, requiredPermissions, null, appOp, bOptions, serialized, + sticky, userId); } public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, - String[] requiredPermissions, int appOp, Bundle bOptions, + String[] requiredPermissions, String[] excludedPermissions, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId) { enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { @@ -13388,8 +13390,8 @@ public class ActivityManagerService extends IActivityManager.Stub return broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermissions, appOp, bOptions, serialized, sticky, - callingPid, callingUid, callingUid, callingPid, userId); + requiredPermissions, excludedPermissions, appOp, bOptions, serialized, + sticky, callingPid, callingUid, callingUid, callingPid, userId); } finally { Binder.restoreCallingIdentity(origId); } @@ -13410,7 +13412,7 @@ public class ActivityManagerService extends IActivityManager.Stub : new String[] {requiredPermission}; try { return broadcastIntentLocked(null, packageName, featureId, intent, resolvedType, - resultTo, resultCode, resultData, resultExtras, requiredPermissions, + resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid, realCallingPid, userId, allowBackgroundActivityStarts, backgroundActivityStartsToken, @@ -15615,7 +15617,7 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManagerService.this.broadcastIntentLocked(null /*callerApp*/, null /*callerPackage*/, null /*callingFeatureId*/, intent, null /*resolvedType*/, resultTo, 0 /*resultCode*/, null /*resultData*/, - null /*resultExtras*/, requiredPermissions, AppOpsManager.OP_NONE, + null /*resultExtras*/, requiredPermissions, null, AppOpsManager.OP_NONE, bOptions /*options*/, serialized, false /*sticky*/, callingPid, callingUid, callingUid, callingPid, userId, false /*allowBackgroundStarts*/, @@ -15740,8 +15742,8 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), - Binder.getCallingPid(), UserHandle.USER_ALL); + null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND @@ -15751,8 +15753,9 @@ public class ActivityManagerService extends IActivityManager.Stub intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), - Binder.getCallingPid(), UserHandle.USER_ALL); + null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + Binder.getCallingUid(), Binder.getCallingPid(), + UserHandle.USER_ALL); } // Send a broadcast to PackageInstallers if the configuration change is interesting @@ -15766,7 +15769,7 @@ public class ActivityManagerService extends IActivityManager.Stub String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES }; broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, - permissions, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + permissions, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } } @@ -15791,7 +15794,7 @@ public class ActivityManagerService extends IActivityManager.Stub } broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), + null, OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 42aac295c0273..6fa8ecd41d7c3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -760,7 +760,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.flush(); Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle(); mInterface.broadcastIntentWithFeature(null, null, intent, null, receiver, 0, null, null, - requiredPermissions, android.app.AppOpsManager.OP_NONE, bundle, true, false, + requiredPermissions, null, android.app.AppOpsManager.OP_NONE, bundle, true, false, mUserId); if (!mAsync) { receiver.waitForFinish(); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index a5474d0b8c72c..f0b116cc18697 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -1419,6 +1419,7 @@ public final class BroadcastQueue { skip = true; } } + boolean isSingleton = false; try { isSingleton = mService.isSingleton(info.activityInfo.processName, @@ -1553,6 +1554,37 @@ public final class BroadcastQueue { + info.activityInfo.applicationInfo.uid + " : user is not running"); } + if (!skip && r.excludedPermissions != null && r.excludedPermissions.length > 0) { + for (int i = 0; i < r.excludedPermissions.length; i++) { + String excludedPermission = r.excludedPermissions[i]; + try { + perm = AppGlobals.getPackageManager() + .checkPermission(excludedPermission, + info.activityInfo.applicationInfo.packageName, + UserHandle + .getUserId(info.activityInfo.applicationInfo.uid)); + } catch (RemoteException e) { + perm = PackageManager.PERMISSION_DENIED; + } + + if (perm == PackageManager.PERMISSION_GRANTED) { + skip = true; + break; + } + + int appOp = AppOpsManager.permissionToOpCode(excludedPermission); + if (appOp != AppOpsManager.OP_NONE) { + if (mService.getAppOpsManager().checkOpNoThrow(appOp, + info.activityInfo.applicationInfo.uid, + info.activityInfo.packageName) + == AppOpsManager.MODE_ALLOWED) { + skip = true; + break; + } + } + } + } + if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && r.requiredPermissions != null && r.requiredPermissions.length > 0) { for (int i = 0; i < r.requiredPermissions.length; i++) { diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index 198ba34e3956d..8015596204575 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -62,6 +62,7 @@ final class BroadcastRecord extends Binder { final int userId; // user id this broadcast was for final String resolvedType; // the resolved data type final String[] requiredPermissions; // permissions the caller has required + final String[] excludedPermissions; // permissions to exclude final int appOp; // an app op that is associated with this broadcast final BroadcastOptions options; // BroadcastOptions supplied by caller final List receivers; // contains BroadcastFilter and ResolveInfo @@ -142,6 +143,10 @@ final class BroadcastRecord extends Binder { pw.print(Arrays.toString(requiredPermissions)); pw.print(" appOp="); pw.println(appOp); } + if (excludedPermissions != null && excludedPermissions.length > 0) { + pw.print(prefix); pw.print("excludedPermissions="); + pw.print(Arrays.toString(excludedPermissions)); + } if (options != null) { pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); } @@ -240,11 +245,11 @@ final class BroadcastRecord extends Binder { Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType, - String[] _requiredPermissions, int _appOp, BroadcastOptions _options, List _receivers, - IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, - boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId, - boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken, - boolean timeoutExempt) { + String[] _requiredPermissions, String[] _excludedPermissions, int _appOp, + BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode, + String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, + boolean _initialSticky, int _userId, boolean allowBackgroundActivityStarts, + @Nullable IBinder backgroundActivityStartsToken, boolean timeoutExempt) { if (_intent == null) { throw new NullPointerException("Can't construct with a null intent"); } @@ -259,6 +264,7 @@ final class BroadcastRecord extends Binder { callerInstantApp = _callerInstantApp; resolvedType = _resolvedType; requiredPermissions = _requiredPermissions; + excludedPermissions = _excludedPermissions; appOp = _appOp; options = _options; receivers = _receivers; @@ -299,6 +305,7 @@ final class BroadcastRecord extends Binder { userId = from.userId; resolvedType = from.resolvedType; requiredPermissions = from.requiredPermissions; + excludedPermissions = from.excludedPermissions; appOp = from.appOp; options = from.options; receivers = from.receivers; @@ -356,8 +363,8 @@ final class BroadcastRecord extends Binder { // build a new BroadcastRecord around that single-target list BroadcastRecord split = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, appOp, options, splitReceivers, resultTo, resultCode, - resultData, resultExtras, ordered, sticky, initialSticky, userId, + requiredPermissions, excludedPermissions, appOp, options, splitReceivers, resultTo, + resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt); split.splitToken = this.splitToken; diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java index 984fe409b0860..7562098246140 100644 --- a/services/core/java/com/android/server/am/PreBootBroadcaster.java +++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java @@ -124,7 +124,7 @@ public abstract class PreBootBroadcaster extends IIntentReceiver.Stub { REASON_PRE_BOOT_COMPLETED, ""); synchronized (mService) { mService.broadcastIntentLocked(null, null, null, mIntent, null, this, 0, null, null, - null, AppOpsManager.OP_NONE, bOptions.toBundle(), true, + null, null, AppOpsManager.OP_NONE, bOptions.toBundle(), true, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), mUserId); } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index a5d0e72a81aeb..ba3e1fb95e7d8 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -2936,8 +2936,8 @@ class UserController implements Handler.Callback { // TODO b/64165549 Verify that mLock is not held before calling AMS methods synchronized (mService) { return mService.broadcastIntentLocked(null, null, null, intent, resolvedType, - resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, - bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, + resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, + appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 284998203ac00..85c5a5ea84b8b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -15315,9 +15315,8 @@ public class PackageManagerService extends IPackageManager.Stub final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions( REASON_LOCKED_BOOT_COMPLETED); am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null, - requiredPermissions, android.app.AppOpsManager.OP_NONE, bOptions.toBundle(), - false, false, - userId); + requiredPermissions, null, android.app.AppOpsManager.OP_NONE, + bOptions.toBundle(), false, false, userId); // Deliver BOOT_COMPLETED only if user is unlocked final UserManagerInternal umInternal = mInjector.getUserManagerInternal(); @@ -15327,9 +15326,8 @@ public class PackageManagerService extends IPackageManager.Stub bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); } am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null, - requiredPermissions, android.app.AppOpsManager.OP_NONE, bOptions.toBundle(), - false, false, - userId); + requiredPermissions, null, android.app.AppOpsManager.OP_NONE, + bOptions.toBundle(), false, false, userId); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -22197,7 +22195,7 @@ public class PackageManagerService extends IPackageManager.Stub intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); try { am.broadcastIntentWithFeature(null, null, intent, null, null, - 0, null, null, null, android.app.AppOpsManager.OP_NONE, + 0, null, null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false, userId); } catch (RemoteException e) { } @@ -27810,8 +27808,8 @@ public class PackageManagerService extends IPackageManager.Stub }; try { am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null, - requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false, - UserHandle.USER_ALL); + requiredPermissions, null, android.app.AppOpsManager.OP_NONE, null, false, + false, UserHandle.USER_ALL); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java index 5bef877e2f393..e9b5b62430893 100644 --- a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java +++ b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java @@ -184,6 +184,7 @@ public class BroadcastRecordTest { false /* callerInstantApp */, null /* resolvedType */, null /* requiredPermissions */, + null /* excludedPermissions */, 0 /* appOp */, null /* options */, new ArrayList<>(receivers), // Make a copy to not affect the original list.