Merge "Configure allowed/excluded permission list with BroadcastOptions"

This commit is contained in:
Oscar Shu
2021-12-14 23:28:15 +00:00
committed by Android (Google) Code Review
3 changed files with 75 additions and 1 deletions

View File

@@ -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();

View File

@@ -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
@@ -84,6 +86,20 @@ public class BroadcastOptions extends ComponentOptions {
private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
"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#
@@ -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);
}
/**
@@ -322,6 +340,44 @@ public class BroadcastOptions extends ComponentOptions {
return mAllowBackgroundActivityStarts;
}
/**
* 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)
@@ -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;
}
}

View File

@@ -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();