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

Commit 4eaef210 authored by Cheney Ni's avatar Cheney Ni
Browse files

Apply the new A2DP codec config only when passed the check with codec status

In order to apply a new codec config, the Bluetooth framework needs to
re-configure A2DP with remote, to restart the session with the Audio
HAL, and to notify the audio server to reset the output. This is a
heavy task over HALs and frameworks, so we use the current codec status
to ignore redundant codec preferences.

* To change the preference of optional codecs only when there are all
  mandatory and optional codecs selectable.
* To apply the new codec preference only when those feeding parameters
  or codec specifics are changing.
* Using the current feeding parameters as default settings, and no
  codec changed is needed.

Bug: 131147224
Bug: 133719424
Test: atest -t BluetoothInstrumentationTests:com.android.bluetooth.a2dp
Change-Id: I028b9f168d2e629dd02c8474592e3713445a5000
parent 5518e430
Loading
Loading
Loading
Loading
+14 −26
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ class A2dpCodecConfig {

    void setCodecConfigPreference(BluetoothDevice device,
                                  BluetoothCodecStatus codecStatus,
                                  BluetoothCodecConfig codecConfig) {
                                  BluetoothCodecConfig newCodecConfig) {
        Objects.requireNonNull(codecStatus);

        // Check whether the codecConfig is selectable for this Bluetooth device.
@@ -66,34 +66,36 @@ class A2dpCodecConfig {
                codec.isMandatoryCodec())) {
            // Do not set codec preference to native if the selectableCodecs not contain mandatory
            // codec. The reason could be remote codec negotiation is not completed yet.
            Log.w(TAG, "Cannot find mandatory codec in selectableCodecs.");
            Log.w(TAG, "setCodecConfigPreference: must have mandatory codec before changing.");
            return;
        }
        if (!isCodecConfigSelectable(codecConfig, selectableCodecs)) {
            Log.w(TAG, "Codec is not selectable: " + codecConfig);
        if (!codecStatus.isCodecConfigSelectable(newCodecConfig)) {
            Log.w(TAG, "setCodecConfigPreference: invalid codec "
                    + Objects.toString(newCodecConfig));
            return;
        }

        // Check whether the codecConfig would change current codec config.
        int prioritizedCodecType = getPrioitizedCodecType(codecConfig, selectableCodecs);
        int prioritizedCodecType = getPrioitizedCodecType(newCodecConfig, selectableCodecs);
        BluetoothCodecConfig currentCodecConfig = codecStatus.getCodecConfig();
        if (prioritizedCodecType == currentCodecConfig.getCodecType()
                && (currentCodecConfig.getCodecType() != codecConfig.getCodecType()
                || currentCodecConfig.sameAudioFeedingParameters(codecConfig))) {
                && (prioritizedCodecType != newCodecConfig.getCodecType()
                || (currentCodecConfig.similarCodecFeedingParameters(newCodecConfig)
                && currentCodecConfig.sameCodecSpecificParameters(newCodecConfig)))) {
            // Same codec with same parameters, no need to send this request to native.
            Log.i(TAG, "setCodecConfigPreference: codec not changed.");
            Log.w(TAG, "setCodecConfigPreference: codec not changed.");
            return;
        }

        BluetoothCodecConfig[] codecConfigArray = new BluetoothCodecConfig[1];
        codecConfigArray[0] = codecConfig;
        codecConfigArray[0] = newCodecConfig;
        mA2dpNativeInterface.setCodecConfigPreference(device, codecConfigArray);
    }

    void enableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentCodecConfig) {
        if (currentCodecConfig != null && !currentCodecConfig.isMandatoryCodec()) {
            Log.i(TAG, "enableOptionalCodecs: already using optional codec: "
                    + currentCodecConfig.getCodecType());
            Log.i(TAG, "enableOptionalCodecs: already using optional codec "
                    + currentCodecConfig.getCodecName());
            return;
        }

@@ -115,7 +117,7 @@ class A2dpCodecConfig {

    void disableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentCodecConfig) {
        if (currentCodecConfig != null && currentCodecConfig.isMandatoryCodec()) {
            Log.i(TAG, "disableOptionalCodecs: already using mandatory codec");
            Log.i(TAG, "disableOptionalCodecs: already using mandatory codec.");
            return;
        }

@@ -150,20 +152,6 @@ class A2dpCodecConfig {
        return prioritizedCodecConfig.getCodecType();
    }

    // Check whether the codecConfig is selectable
    private static boolean isCodecConfigSelectable(BluetoothCodecConfig codecConfig,
            BluetoothCodecConfig[] selectableCodecs) {
        for (BluetoothCodecConfig config : selectableCodecs) {
            if (codecConfig.getCodecType() == config.getCodecType()
                    && (codecConfig.getSampleRate() & config.getSampleRate()) != 0
                    && (codecConfig.getBitsPerSample() & config.getBitsPerSample()) != 0
                    && (codecConfig.getChannelMode() & config.getChannelMode()) != 0) {
                return true;
            }
        }
        return false;
    }

    // Assign the A2DP Source codec config priorities
    private BluetoothCodecConfig[] assignCodecConfigPriorities() {
        Resources resources = mContext.getResources();
+10 −11
Original line number Diff line number Diff line
@@ -718,17 +718,16 @@ public class A2dpService extends ProfileService {
            device = mActiveDevice;
        }
        if (device == null) {
            Log.e(TAG, "Cannot set codec config preference: no active A2DP device");
            Log.e(TAG, "setCodecConfigPreference: Invalid device");
            return;
        }
        if (getSupportsOptionalCodecs(device) != BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED) {
            Log.e(TAG, "Cannot set codec config preference: not supported");
        if (codecConfig == null) {
            Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
            return;
        }

        BluetoothCodecStatus codecStatus = getCodecStatus(device);
        if (codecStatus == null) {
            Log.e(TAG, "Codec status is null on " + device);
            Log.e(TAG, "setCodecConfigPreference: Codec status is null");
            return;
        }
        mA2dpCodecConfig.setCodecConfigPreference(device, codecStatus, codecConfig);
@@ -750,16 +749,16 @@ public class A2dpService extends ProfileService {
            device = mActiveDevice;
        }
        if (device == null) {
            Log.e(TAG, "Cannot enable optional codecs: no active A2DP device");
            Log.e(TAG, "enableOptionalCodecs: Invalid device");
            return;
        }
        if (getSupportsOptionalCodecs(device) != BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED) {
            Log.e(TAG, "Cannot enable optional codecs: not supported");
            Log.e(TAG, "enableOptionalCodecs: No optional codecs");
            return;
        }
        BluetoothCodecStatus codecStatus = getCodecStatus(device);
        if (codecStatus == null) {
            Log.e(TAG, "Cannot enable optional codecs: codec status is null");
            Log.e(TAG, "enableOptionalCodecs: Codec status is null");
            return;
        }
        mA2dpCodecConfig.enableOptionalCodecs(device, codecStatus.getCodecConfig());
@@ -781,16 +780,16 @@ public class A2dpService extends ProfileService {
            device = mActiveDevice;
        }
        if (device == null) {
            Log.e(TAG, "Cannot disable optional codecs: no active A2DP device");
            Log.e(TAG, "disableOptionalCodecs: Invalid device");
            return;
        }
        if (getSupportsOptionalCodecs(device) != BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED) {
            Log.e(TAG, "Cannot disable optional codecs: not supported");
            Log.e(TAG, "disableOptionalCodecs: No optional codecs");
            return;
        }
        BluetoothCodecStatus codecStatus = getCodecStatus(device);
        if (codecStatus == null) {
            Log.e(TAG, "Cannot disable optional codecs: codec status is null");
            Log.e(TAG, "disableOptionalCodecs: Codec status is null");
            return;
        }
        mA2dpCodecConfig.disableOptionalCodecs(device, codecStatus.getCodecConfig());
+702 −216

File changed.

Preview size limit exceeded, changes collapsed.