Temp allowlist bluetooth broadcast to start FGS for 10 seconds.

Add an overloaded version of Context.sendBroadcastMultiplePermissions() that can
specify BroadcastOptions, it is called by com.android.bluetooth package.

Bug: 182816627
Test: atest AdapterServiceTest
Test: atest AvrcpControllerStateMachineTest
Test: atest BondStateMachineTest
Test: atest MapClientStateMachineTest
Test: atest RemoteDevicesTest

Change-Id: I8bb2d2ed98ece70ebbe9d3a1b549b966d690de4f
This commit is contained in:
Hui Yu
2021-04-13 21:43:22 -07:00
parent 5681f7c05f
commit 8c23d658c7
8 changed files with 87 additions and 2 deletions

View File

@@ -231,6 +231,11 @@ public class PowerExemptionManager {
* @hide
*/
public static final int REASON_LOCKED_BOOT_COMPLETED = 202;
/**
* All Bluetooth broadcasts.
* @hide
*/
public static final int REASON_BLUETOOTH_BROADCAST = 203;
/* Reason code range 300-399 are reserved for other internal reasons */
/**
@@ -363,6 +368,7 @@ public class PowerExemptionManager {
REASON_BOOT_COMPLETED,
REASON_PRE_BOOT_COMPLETED,
REASON_LOCKED_BOOT_COMPLETED,
REASON_BLUETOOTH_BROADCAST,
REASON_SYSTEM_ALLOW_LISTED,
REASON_ALARM_MANAGER_ALARM_CLOCK,
REASON_ALARM_MANAGER_WHILE_IDLE,
@@ -633,6 +639,8 @@ public class PowerExemptionManager {
return "PRE_BOOT_COMPLETED";
case REASON_LOCKED_BOOT_COMPLETED:
return "LOCKED_BOOT_COMPLETED";
case REASON_BLUETOOTH_BROADCAST:
return "BLUETOOTH_BROADCAST";
case REASON_SYSTEM_ALLOW_LISTED:
return "SYSTEM_ALLOW_LISTED";
case REASON_ALARM_MANAGER_ALARM_CLOCK:

View File

@@ -1217,6 +1217,23 @@ class ContextImpl extends Context {
}
}
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
Bundle options) {
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,
null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
String[] receiverPermissions) {

View File

@@ -2218,6 +2218,26 @@ public abstract class Context {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/**
* Version of {@link #sendBroadcastMultiplePermissions(Intent, String[])} that allows you to
* specify the {@link android.app.BroadcastOptions}.
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
* @param receiverPermissions Array of names of permissions that a receiver must hold
* in order to receive your broadcast.
* If empty, no permissions are required.
* @param options Additional sending options, generated from a
* {@link android.app.BroadcastOptions}.
* @see #sendBroadcastMultiplePermissions(Intent, String[])
* @see android.app.BroadcastOptions
* @hide
*/
public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
@NonNull String[] receiverPermissions, @Nullable Bundle options) {
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

View File

@@ -498,6 +498,13 @@ public class ContextWrapper extends Context {
mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions);
}
/** @hide */
@Override
public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
@NonNull String[] receiverPermissions, @Nullable Bundle options) {
mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, options);
}
/** @hide */
@Override
public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,

View File

@@ -20,14 +20,17 @@ import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.UserHandle.USER_SYSTEM;
import android.Manifest;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHearingAid;
@@ -62,6 +65,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerExemptionManager;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -2497,7 +2501,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null, getTempAllowlistBroadcastOptions());
}
@RequiresPermission(allOf = {
@@ -2580,7 +2584,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null,
getTempAllowlistBroadcastOptions());
}
}
@@ -2890,4 +2895,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
return permissionCheckResult == PERMISSION_GRANTED;
}
static @NonNull Bundle getTempAllowlistBroadcastOptions() {
final long duration = 10_000;
final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
bOptions.setTemporaryAppAllowlist(duration,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
PowerExemptionManager.REASON_BLUETOOTH_BROADCAST, "");
return bOptions.toBundle();
}
}

View File

@@ -286,6 +286,12 @@ public class DpmMockContext extends MockContext {
spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
}
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
Bundle options) {
spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions, options);
}
@Override
public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
String[] receiverPermissions) {

View File

@@ -373,6 +373,13 @@ public class MockContext extends Context {
throw new UnsupportedOperationException();
}
/** @hide */
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
Bundle options) {
throw new UnsupportedOperationException();
}
/** @hide */
@Override
public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,

View File

@@ -195,6 +195,12 @@ public class BroadcastInterceptingContext extends ContextWrapper {
sendBroadcast(intent);
}
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
Bundle options) {
sendBroadcast(intent);
}
@Override
public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
String[] receiverPermissions) {