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

Commit 874bcf0c authored by Etienne Ruffieux's avatar Etienne Ruffieux Committed by Gerrit Code Review
Browse files

Merge "Made Bluetooth codec configuration APIs public."

parents 27fe51fc 64d4e6b6
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.Manifest.permission.BLUETOOTH_CONNECT;

import static com.android.bluetooth.Utils.checkCallerTargetSdk;
import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
import static com.android.bluetooth.Utils.enforceCdmAssociation;
import static com.android.bluetooth.Utils.hasBluetoothPrivilegedPermission;

import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothA2dp;
@@ -32,6 +34,7 @@ import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
import android.bluetooth.IBluetoothA2dp;
import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -39,6 +42,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
import android.os.Binder;
import android.os.Build;
import android.os.HandlerThread;
import android.sysprop.BluetoothProperties;
@@ -83,6 +87,7 @@ public class A2dpService extends ProfileService {
    ServiceFactory mFactory = new ServiceFactory();
    private AudioManager mAudioManager;
    private A2dpCodecConfig mA2dpCodecConfig;
    private CompanionDeviceManager mCompanionDeviceManager;

    @GuardedBy("mStateMachines")
    private BluetoothDevice mActiveDevice;
@@ -135,6 +140,7 @@ public class A2dpService extends ProfileService {
        mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
                "DatabaseManager cannot be null when A2dpService starts");
        mAudioManager = getSystemService(AudioManager.class);
        mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class);
        Objects.requireNonNull(mAudioManager,
                               "AudioManager cannot be null when A2dpService starts");

@@ -1480,6 +1486,10 @@ public class A2dpService extends ProfileService {
            if (service == null) {
                return;
            }
            if (!hasBluetoothPrivilegedPermission(service)) {
                enforceCdmAssociation(service.mCompanionDeviceManager, service,
                        source.getPackageName(), Binder.getCallingUid(), device);
            }
            service.setCodecConfigPreference(device, codecConfig);
        }

+7 −0
Original line number Diff line number Diff line
@@ -3,10 +3,13 @@ package android.bluetooth {

  public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
    method public void finalize();
    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isA2dpPlaying(android.bluetooth.BluetoothDevice);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CODEC_CONFIG_CHANGED = "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PLAYING_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
    field public static final int STATE_NOT_PLAYING = 11; // 0xb
@@ -443,6 +446,10 @@ package android.bluetooth {
    field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
    field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
    field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
    field public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_ADAPTIVE = 1003; // 0x3eb
    field public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_HIGH = 1000; // 0x3e8
    field public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_LOW = 1002; // 0x3ea
    field public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_MID = 1001; // 0x3e9
    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecConfig> CREATOR;
    field public static final int SAMPLE_RATE_176400 = 16; // 0x10
    field public static final int SAMPLE_RATE_192000 = 32; // 0x20
+0 −3
Original line number Diff line number Diff line
@@ -5,18 +5,15 @@ package android.bluetooth {
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void disableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void enableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BufferConstraints getBufferConstraints();
    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getDynamicBufferSupport();
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int isOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int isOptionalCodecsSupported(@NonNull android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setAvrcpAbsoluteVolume(int);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setBufferLengthMillis(int, int);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice, int);
    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACTIVE_DEVICE_CHANGED = "android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED";
    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CODEC_CONFIG_CHANGED = "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
    field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1
    field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2; // 0x2
    field public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0; // 0x0
+18 −21
Original line number Diff line number Diff line
@@ -144,10 +144,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
     * connected, otherwise it is not included.</li>
     * </ul>
     *
     * @hide
     */
    @SystemApi
    @RequiresLegacyBluetoothPermission
    @RequiresBluetoothConnectPermission
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -770,20 +767,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    }

    /**
     * Gets the current codec status (configuration and capability).
     * Retrieves the current codec configuration and the capabilities of the remote {@code device}.
     *
     * @param device the remote Bluetooth device.
     * @return the current codec status
     * @hide
     * @param device the remote Bluetooth device
     * @return       the current codec status of the remote Bluetooth device
     */
    @SystemApi
    @Nullable
    @RequiresLegacyBluetoothPermission
    @RequiresBluetoothConnectPermission
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
    })
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
        if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
        verifyDeviceNotNull(device, "getCodecStatus");
@@ -806,19 +798,24 @@ public final class BluetoothA2dp implements BluetoothProfile {
    }

    /**
     * Sets the codec configuration preference.
     * Sets the preferred codec configuration of remote {@code device}.
     *
     * @param device the remote Bluetooth device.
     * @param codecConfig the codec configuration preference
     * @hide
     * The configuration must contain only selectable parameters in order to be used.
     * See {@link #getCodecStatus} and {@link BluetoothCodecStatus#isCodecConfigSelectable}.
     *
     * <p>This method requires the calling app to be associated with Companion Device Manager (see
     * {@link android.companion.CompanionDeviceManager#associate(AssociationRequest,
     * android.companion.CompanionDeviceManager.Callback, Handler)}) and have the
     * {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission. Alternatively, if the
     * caller has the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission, they can
     * bypass the Companion Device Manager association requirement.
     *
     * @param device      the remote Bluetooth device
     * @param codecConfig the preferred codec configuration preference
     */
    @SystemApi
    @RequiresLegacyBluetoothPermission
    @RequiresBluetoothConnectPermission
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
    })
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    public void setCodecConfigPreference(@NonNull BluetoothDevice device,
                                         @NonNull BluetoothCodecConfig codecConfig) {
        if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
+30 −1
Original line number Diff line number Diff line
@@ -219,6 +219,36 @@ public final class BluetoothCodecConfig implements Parcelable {
     */
    public static final int CHANNEL_MODE_STEREO = 0x1 << 1;

    /** @hide */
    @IntDef(prefix = "CODEC_SPECIFIC_1_LDAC_", value = {
            CODEC_SPECIFIC_1_LDAC_QUALITY_HIGH,
            CODEC_SPECIFIC_1_LDAC_QUALITY_MID,
            CODEC_SPECIFIC_1_LDAC_QUALITY_LOW,
            CODEC_SPECIFIC_1_LDAC_QUALITY_ADAPTIVE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface CodecSpecific1Ldac {}

    /**
     * Codec specific value for LDAC high quality bitrate.
     */
    public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_HIGH = 1000;

    /**
     * Codec specific value for LDAC medium quality bitrate.
     */
    public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_MID = 1001;

    /**
     * Codec specific value for LDAC low quality bitrate.
     */
    public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_LOW = 1002;

    /**
     * Codec specific value for LDAC adaptive bitrate.
     */
    public static final int CODEC_SPECIFIC_1_LDAC_QUALITY_ADAPTIVE = 1003;

    private final @SourceCodecType int mCodecType;
    private @CodecPriority int mCodecPriority;
    private final @SampleRate int mSampleRate;
@@ -241,7 +271,6 @@ public final class BluetoothCodecConfig implements Parcelable {
     * @param codecSpecific2 the specific value 2
     * @param codecSpecific3 the specific value 3
     * @param codecSpecific4 the specific value 4
     * values to 0.
     * @hide
     */
    @UnsupportedAppUsage