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

Commit a9192592 authored by Ashwini Oruganti's avatar Ashwini Oruganti
Browse files

Add an excludedPermission arg to filter the set of apps that a broadcast

gets sent to

This adds an API to allow sending a broadcast to an app that has permission FOO but not permission BAR.
Earlier, a lack of this option was causing a double send problem for broadcasts, which should now be resolved.

Test: manual
Bug: 183537857
Change-Id: I13287d63e039164694be4daa832bb23709990054
parent 517485f8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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) {
        }
    }
+55 −30
Original line number Diff line number Diff line
@@ -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();
        }
+1 −1
Original line number Diff line number Diff line
@@ -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
+11 −0
Original line number Diff line number Diff line
@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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,
Loading