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

Commit 8851741c authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge changes from topic "mar24b" into sc-dev

* changes:
  Check permission BLUETOOTH_ADMIN -> BLUETOOTH_CONNECT
  Check permission BLUETOOTH -> BLUETOOTH_CONNECT
  Replace BLUETOOTH permission checks with checks for BLUETOOTH_CONNECT.
parents 694f9c8e 33c78b3d
Loading
Loading
Loading
Loading
+35 −25
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.bluetooth;

import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_SCAN;
import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
@@ -31,7 +32,6 @@ import android.companion.Association;
import android.companion.CompanionDeviceManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.PermissionChecker;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -360,18 +360,6 @@ public final class Utils {
                == PackageManager.PERMISSION_GRANTED;
    }

    public static void enforceBluetoothPermission(Context context) {
        context.enforceCallingOrSelfPermission(
                android.Manifest.permission.BLUETOOTH,
                "Need BLUETOOTH permission");
    }

    public static void enforceBluetoothAdminPermission(Context context) {
        context.enforceCallingOrSelfPermission(
                android.Manifest.permission.BLUETOOTH_ADMIN,
                "Need BLUETOOTH ADMIN permission");
    }

    public static void enforceBluetoothPrivilegedPermission(Context context) {
        context.enforceCallingOrSelfPermission(
                android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -390,6 +378,40 @@ public final class Utils {
                "Need DUMP permission");
    }

    /**
     * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns
     * false if the result is a soft denial. Throws SecurityException if the result is a hard
     * denial.
     *
     * <p>Should be used in situations where the app op should not be noted.
     */
    public static boolean checkConnectPermissionForPreflight(Context context) {
        int permissionCheckResult = PermissionChecker.checkCallingOrSelfPermissionForPreflight(
                context, BLUETOOTH_CONNECT);
        if (permissionCheckResult == PERMISSION_HARD_DENIED) {
            throw new SecurityException("Need BLUETOOTH_CONNECT permission");
        }
        return permissionCheckResult == PERMISSION_GRANTED;
    }

    /**
     * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns
     * false if the result is a soft denial. Throws SecurityException if the result is a hard
     * denial.
     *
     * <p>Should be used in situations where data will be delivered and hence the app op should
     * be noted.
     */
    public static boolean checkConnectPermissionForDataDelivery(
            Context context, String callingPackage, String callingAttributionTag, String message) {
        int permissionCheckResult = PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(
                context, BLUETOOTH_CONNECT, callingPackage, callingAttributionTag, message);
        if (permissionCheckResult == PERMISSION_HARD_DENIED) {
            throw new SecurityException("Need BLUETOOTH_CONNECT permission");
        }
        return permissionCheckResult == PERMISSION_GRANTED;
    }

    /**
     * Returns true if the BLUETOOTH_SCAN permission is granted for the calling app. Returns false
     * if the result is a soft denial. Throws SecurityException if the result is a hard denial.
@@ -497,18 +519,6 @@ public final class Utils {
        }
    }

    /**
     * Enforce the context has android.Manifest.permission.BLUETOOTH_ADMIN permission. A
     * {@link SecurityException} would be thrown if neither the calling process or the application
     * does not have BLUETOOTH_ADMIN permission.
     *
     * @param context Context for the permission check.
     */
    public static void enforceAdminPermission(ContextWrapper context) {
        context.enforceCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_ADMIN,
                "Need BLUETOOTH_ADMIN permission");
    }

    /**
     * Checks whether location is off and must be on for us to perform some operation
     */
+53 −21
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

package com.android.bluetooth.a2dp;

import static com.android.bluetooth.Utils.enforceBluetoothPermission;
import static android.Manifest.permission.BLUETOOTH_CONNECT;

import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;

import android.bluetooth.BluetoothA2dp;
@@ -239,7 +240,9 @@ public class A2dpService extends ProfileService {
    }

    public boolean connect(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return false;
        }
        if (DBG) {
            Log.d(TAG, "connect(): " + device);
        }
@@ -291,7 +294,9 @@ public class A2dpService extends ProfileService {
     * @return true if profile disconnected, false if device not connected over a2dp
     */
    public boolean disconnect(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return false;
        }
        if (DBG) {
            Log.d(TAG, "disconnect(): " + device);
        }
@@ -308,7 +313,9 @@ public class A2dpService extends ProfileService {
    }

    public List<BluetoothDevice> getConnectedDevices() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return new ArrayList<>(0);
        }
        synchronized (mStateMachines) {
            List<BluetoothDevice> devices = new ArrayList<>();
            for (A2dpStateMachine sm : mStateMachines.values()) {
@@ -389,7 +396,9 @@ public class A2dpService extends ProfileService {
    }

    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return new ArrayList<>(0);
        }
        List<BluetoothDevice> devices = new ArrayList<>();
        if (states == null) {
            return devices;
@@ -437,7 +446,9 @@ public class A2dpService extends ProfileService {
    }

    public int getConnectionState(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }
        synchronized (mStateMachines) {
            A2dpStateMachine sm = mStateMachines.get(device);
            if (sm == null) {
@@ -513,7 +524,9 @@ public class A2dpService extends ProfileService {
     * @return true on success, otherwise false
     */
    public boolean setActiveDevice(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return false;
        }
        synchronized (mActiveSwitchingGuard) {
            if (device == null) {
                // Remove active device and continue playing audio only if necessary.
@@ -602,7 +615,9 @@ public class A2dpService extends ProfileService {
     * @return the active device or null if no device is active
     */
    public BluetoothDevice getActiveDevice() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return null;
        }
        synchronized (mStateMachines) {
            return mActiveDevice;
        }
@@ -681,7 +696,9 @@ public class A2dpService extends ProfileService {
    }

    boolean isA2dpPlaying(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return false;
        }
        if (DBG) {
            Log.d(TAG, "isA2dpPlaying(" + device + ")");
        }
@@ -703,7 +720,9 @@ public class A2dpService extends ProfileService {
     * @hide
     */
    public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return null;
        }
        if (DBG) {
            Log.d(TAG, "getCodecStatus(" + device + ")");
        }
@@ -732,7 +751,9 @@ public class A2dpService extends ProfileService {
     */
    public void setCodecConfigPreference(BluetoothDevice device,
                                         BluetoothCodecConfig codecConfig) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return;
        }
        if (DBG) {
            Log.d(TAG, "setCodecConfigPreference(" + device + "): "
                    + Objects.toString(codecConfig));
@@ -764,7 +785,9 @@ public class A2dpService extends ProfileService {
     * @hide
     */
    public void enableOptionalCodecs(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return;
        }
        if (DBG) {
            Log.d(TAG, "enableOptionalCodecs(" + device + ")");
        }
@@ -795,7 +818,9 @@ public class A2dpService extends ProfileService {
     * @hide
     */
    public void disableOptionalCodecs(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return;
        }
        if (DBG) {
            Log.d(TAG, "disableOptionalCodecs(" + device + ")");
        }
@@ -828,12 +853,16 @@ public class A2dpService extends ProfileService {
     * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORT_UNKNOWN}.
     */
    public @OptionalCodecsSupportStatus int getSupportsOptionalCodecs(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
        }
        return mDatabaseManager.getA2dpSupportsOptionalCodecs(device);
    }

    public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return;
        }
        int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED
                : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
        mDatabaseManager.setA2dpSupportsOptionalCodecs(device, value);
@@ -849,7 +878,9 @@ public class A2dpService extends ProfileService {
     * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}.
     */
    public @OptionalCodecsPreferenceStatus int getOptionalCodecsEnabled(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
        }
        return mDatabaseManager.getA2dpOptionalCodecsEnabled(device);
    }

@@ -864,7 +895,9 @@ public class A2dpService extends ProfileService {
     */
    public void setOptionalCodecsEnabled(BluetoothDevice device,
            @OptionalCodecsPreferenceStatus int value) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return;
        }
        if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
                && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
                && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
@@ -1034,7 +1067,7 @@ public class A2dpService extends ProfileService {
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    private void broadcastCodecConfig(BluetoothDevice device, BluetoothCodecStatus codecStatus) {
@@ -1046,7 +1079,7 @@ public class A2dpService extends ProfileService {
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        sendBroadcast(intent, A2dpService.BLUETOOTH_PERM);
        sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    private class BondStateChangedReceiver extends BroadcastReceiver {
@@ -1320,10 +1353,9 @@ public class A2dpService extends ProfileService {
        @Override
        public int getPriority(BluetoothDevice device) {
            A2dpService service = getService();
            if (service == null) {
            if (service == null || !Utils.checkConnectPermissionForPreflight(service)) {
                return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
            }
            enforceBluetoothPermission(service);
            return service.getConnectionPolicy(device);
        }

+4 −2
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@

package com.android.bluetooth.a2dp;

import static android.Manifest.permission.BLUETOOTH_CONNECT;

import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothCodecStatus;
@@ -682,7 +684,7 @@ final class A2dpStateMachine extends StateMachine {
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        mA2dpService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        mA2dpService.sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    private void broadcastAudioState(int newState, int prevState) {
@@ -694,7 +696,7 @@ final class A2dpStateMachine extends StateMachine {
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        mA2dpService.sendBroadcast(intent, A2dpService.BLUETOOTH_PERM);
        mA2dpService.sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    @Override
+3 −1
Original line number Diff line number Diff line
@@ -328,7 +328,9 @@ public class A2dpSinkService extends ProfileService {
     * @return true if disconnect is successful, false otherwise.
     */
    public boolean disconnect(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkConnectPermissionForPreflight(this)) {
            return false;
        }
        if (DBG) {
            StringBuilder sb = new StringBuilder();
            dump(sb);
+3 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.bluetooth.a2dpsink;

import static android.Manifest.permission.BLUETOOTH_CONNECT;

import android.bluetooth.BluetoothA2dpSink;
import android.bluetooth.BluetoothAudioConfig;
import android.bluetooth.BluetoothDevice;
@@ -307,6 +309,6 @@ public class A2dpSinkStateMachine extends StateMachine {
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        mMostRecentState = currentState;
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        mService.sendBroadcast(intent, BLUETOOTH_CONNECT);
    }
}
Loading