summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Oscar Shu <xshu@google.com> 2021-12-14 23:28:15 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-12-14 23:28:15 +0000
commit93a619cf6f122fb38bcda3ab989ee87c9e391e37 (patch)
tree8a9ce6d967e430cc6d1cfb407ca365c3f057bdb3
parent087d988261e8405b3be3ae9c65ff0b8f68c8eef2 (diff)
parenta2a4482c8dc27a4b6f07cb3356129fc47f53548f (diff)
Merge "Configure allowed/excluded permission list with BroadcastOptions"
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/java/android/app/BroadcastOptions.java62
-rw-r--r--core/java/android/app/ContextImpl.java12
3 files changed, 75 insertions, 1 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 99d98078427c..a5291af3d633 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -726,6 +726,8 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
method public void setDontSendToRestrictedApps(boolean);
method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
+ method public void setRequireAllOfPermissions(@Nullable String[]);
+ method public void setRequireNoneOfPermissions(@Nullable String[]);
method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
method public android.os.Bundle toBundle();
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 5b8cc70cc0a8..3108d9178440 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -43,6 +43,8 @@ public class BroadcastOptions extends ComponentOptions {
private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
private boolean mDontSendToRestrictedApps = false;
private boolean mAllowBackgroundActivityStarts;
+ private String[] mRequireAllOfPermissions;
+ private String[] mRequireNoneOfPermissions;
/**
* How long to temporarily put an app on the power allowlist when executing this broadcast
@@ -85,6 +87,20 @@ public class BroadcastOptions extends ComponentOptions {
"android:broadcast.allowBackgroundActivityStarts";
/**
+ * Corresponds to {@link #setRequireAllOfPermissions}
+ * @hide
+ */
+ public static final String KEY_REQUIRE_ALL_OF_PERMISSIONS =
+ "android:broadcast.requireAllOfPermissions";
+
+ /**
+ * Corresponds to {@link #setRequireNoneOfPermissions}
+ * @hide
+ */
+ public static final String KEY_REQUIRE_NONE_OF_PERMISSIONS =
+ "android:broadcast.requireNoneOfPermissions";
+
+ /**
* @hide
* @deprecated Use {@link android.os.PowerExemptionManager#
* TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED} instead.
@@ -132,6 +148,8 @@ public class BroadcastOptions extends ComponentOptions {
mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false);
mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS,
false);
+ mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS);
+ mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS);
}
/**
@@ -323,6 +341,44 @@ public class BroadcastOptions extends ComponentOptions {
}
/**
+ * Use this to configure a broadcast to be sent to apps that hold all permissions in
+ * the list. This is only for use with the {@link Context#sendBroadcast(Intent intent,
+ * @Nullable String receiverPermission, @Nullable Bundle options)}.
+ *
+ * <p> If both {@link #setRequireAllOfPermissions(String[])} and
+ * {@link #setRequireNoneOfPermissions(String[])} are used, then receivers must have all of the
+ * permissions set by {@link #setRequireAllOfPermissions(String[])}, and none of the
+ * permissions set by {@link #setRequireNoneOfPermissions(String[])} to get the broadcast.
+ *
+ * @param requiredPermissions a list of Strings of permission the receiver must have, or null
+ * to clear any previously set value.
+ * @hide
+ */
+ @SystemApi
+ public void setRequireAllOfPermissions(@Nullable String[] requiredPermissions) {
+ mRequireAllOfPermissions = requiredPermissions;
+ }
+
+ /**
+ * Use this to configure a broadcast to be sent to apps that don't hold any permissions in
+ * list. This is only for use with the {@link Context#sendBroadcast(Intent intent,
+ * @Nullable String receiverPermission, @Nullable Bundle options)}.
+ *
+ * <p> If both {@link #setRequireAllOfPermissions(String[])} and
+ * {@link #setRequireNoneOfPermissions(String[])} are used, then receivers must have all of the
+ * permissions set by {@link #setRequireAllOfPermissions(String[])}, and none of the
+ * permissions set by {@link #setRequireNoneOfPermissions(String[])} to get the broadcast.
+ *
+ * @param excludedPermissions a list of Strings of permission the receiver must not have,
+ * or null to clear any previously set value.
+ * @hide
+ */
+ @SystemApi
+ public void setRequireNoneOfPermissions(@Nullable String[] excludedPermissions) {
+ mRequireNoneOfPermissions = excludedPermissions;
+ }
+
+ /**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
* Context.sendBroadcast(Intent)} and related methods.
@@ -351,6 +407,12 @@ public class BroadcastOptions extends ComponentOptions {
if (mAllowBackgroundActivityStarts) {
b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true);
}
+ if (mRequireAllOfPermissions != null) {
+ b.putStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS, mRequireAllOfPermissions);
+ }
+ if (mRequireNoneOfPermissions != null) {
+ b.putStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS, mRequireNoneOfPermissions);
+ }
return b.isEmpty() ? null : b;
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 885feb1f789a..f3e9f105500e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1272,12 +1272,22 @@ class ContextImpl extends Context {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
+ String[] excludedPermissions = null;
+ if (options != null) {
+ String[] receiverPermissionsBundle = options.getStringArray(
+ BroadcastOptions.KEY_REQUIRE_ALL_OF_PERMISSIONS);
+ if (receiverPermissionsBundle != null) {
+ receiverPermissions = receiverPermissionsBundle;
+ }
+ excludedPermissions = options.getStringArray(
+ BroadcastOptions.KEY_REQUIRE_NONE_OF_PERMISSIONS);
+ }
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntentWithFeature(
mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
null, Activity.RESULT_OK, null, null, receiverPermissions,
- null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false,
+ excludedPermissions, AppOpsManager.OP_NONE, options, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();