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

Commit e93fa569 authored by Phaneendra Reddy's avatar Phaneendra Reddy Committed by Jakub Rotkiewicz
Browse files

AptX Voice feature support

Support for Super Wide Band codec that provides
HD-Voice quality enhancement to the existing
SCo calls is added with this change.

Bug: 293574035
Bug: 308497929
Test: atest bt_host_test_bta | Tests are in an immediate follow-up CL aosp/2679780
Change-Id: Ib19c556312ff1088f002f935d86144712a836f1e
parent 24f7b0b4
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -237,7 +237,8 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks {
                                 addr.get());
  }

  void SwbCallback(bluetooth::headset::bthf_swb_config_t swb_config,
  void SwbCallback(bluetooth::headset::bthf_swb_codec_t swb_codec,
                   bluetooth::headset::bthf_swb_config_t swb_config,
                   RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
@@ -246,8 +247,8 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks {
    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (addr.get() == nullptr) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSWB, swb_config,
                                 addr.get());
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSWB, swb_codec,
                                 swb_config, addr.get());
  }

  void AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,
@@ -998,7 +999,7 @@ int register_com_android_bluetooth_hfp(JNIEnv* env) {
      {"onSendDtmf", "(I[B)V", &method_onSendDtmf},
      {"onNoiseReductionEnable", "(Z[B)V", &method_onNoiseReductionEnable},
      {"onWBS", "(I[B)V", &method_onWBS},
      {"onSWB", "(I[B)V", &method_onSWB},
      {"onSWB", "(II[B)V", &method_onSWB},
      {"onAtChld", "(I[B)V", &method_onAtChld},
      {"onAtCnum", "([B)V", &method_onAtCnum},
      {"onAtCind", "([B)V", &method_onAtCind},
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ public final class HeadsetHalConstants {
    static final int BTHF_WBS_NO = 1;
    static final int BTHF_WBS_YES = 2;

    // match up with bthf_swb_codec_t of bt_hf.h
    static final int BTHF_SWB_CODEC_LC3 = 0;
    static final int BTHF_SWB_CODEC_VENDOR_APTX = 1;

    // match up with bthf_swb_config_t of bt_hf.h
    static final int BTHF_SWB_NONE = 0;
    static final int BTHF_SWB_NO = 1;
+3 −2
Original line number Diff line number Diff line
@@ -163,9 +163,10 @@ public class HeadsetNativeInterface {
        sendMessageToService(event);
    }

    private void onSWB(int codec, byte[] address) {
    private void onSWB(int codec, int swb, byte[] address) {
        HeadsetStackEvent event =
                new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_SWB, codec, getDevice(address));
                new HeadsetStackEvent(
                        HeadsetStackEvent.EVENT_TYPE_SWB, codec, swb, getDevice(address));
        sendMessageToService(event);
    }

+54 −17
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.bluetooth.hfp;

import static android.Manifest.permission.BLUETOOTH_CONNECT;

import static com.android.modules.utils.build.SdkLevel.isAtLeastU;

import android.annotation.RequiresPermission;
@@ -151,7 +152,8 @@ public class HeadsetStateMachine extends StateMachine {
    // Audio Parameters
    private boolean mHasNrecEnabled = false;
    private boolean mHasWbsEnabled = false;
    private boolean mHasSwbEnabled = false;
    private boolean mHasSwbLc3Enabled = false;
    private boolean mHasSwbAptXEnabled = false;
    // AT Phone book keeps a group of states used by AT+CPBR commands
    @VisibleForTesting
    final AtPhonebook mPhonebook;
@@ -250,7 +252,8 @@ public class HeadsetStateMachine extends StateMachine {
        }
        mHasWbsEnabled = false;
        mHasNrecEnabled = false;
        mHasSwbEnabled = false;
        mHasSwbLc3Enabled = false;
        mHasSwbAptXEnabled = false;
    }

    public void dump(StringBuilder sb) {
@@ -482,8 +485,9 @@ public class HeadsetStateMachine extends StateMachine {
            updateAgIndicatorEnableState(null);
            mNeedDialingOutReply = false;
            mHasWbsEnabled = false;
            mHasSwbEnabled = false;
            mHasSwbLc3Enabled = false;
            mHasNrecEnabled = false;
            mHasSwbAptXEnabled = false;

            broadcastStateTransitions();
            logFailureIfNeeded();
@@ -686,7 +690,7 @@ public class HeadsetStateMachine extends StateMachine {
                            processWBSEvent(event.valueInt);
                            break;
                        case HeadsetStackEvent.EVENT_TYPE_SWB:
                            processSWBEvent(event.valueInt);
                            processSWBEvent(event.valueInt, event.valueInt2);
                            break;
                        case HeadsetStackEvent.EVENT_TYPE_BIND:
                            processAtBind(event.valueString, event.device);
@@ -1027,7 +1031,7 @@ public class HeadsetStateMachine extends StateMachine {
                            processWBSEvent(event.valueInt);
                            break;
                        case HeadsetStackEvent.EVENT_TYPE_SWB:
                            processSWBEvent(event.valueInt);
                            processSWBEvent(event.valueInt, event.valueInt2);
                            break;
                        case HeadsetStackEvent.EVENT_TYPE_AT_CHLD:
                            processAtChld(event.valueInt, event.device);
@@ -1636,11 +1640,17 @@ public class HeadsetStateMachine extends StateMachine {

    private void setAudioParameters() {
        AudioManager am = mSystemInterface.getAudioManager();
        Log.i(TAG, "setAudioParameters for " + mDevice + ":"
                + " Name=" + getCurrentDeviceName()
                + " hasNrecEnabled=" + mHasNrecEnabled
                + " hasWbsEnabled=" + mHasWbsEnabled);
        am.setParameters("bt_lc3_swb=" + (mHasSwbEnabled ? "on" : "off"));
        Log.i(
                TAG,
                ("setAudioParameters for " + mDevice + ":")
                        + (" Name=" + getCurrentDeviceName())
                        + (" hasNrecEnabled=" + mHasNrecEnabled)
                        + (" hasWbsEnabled=" + mHasWbsEnabled)
                        + (" hasSwbEnabled=" + mHasSwbLc3Enabled)
                        + (" hasAptXSwbEnabled=" + mHasSwbAptXEnabled));
        am.setParameters("bt_lc3_swb=" + (mHasSwbLc3Enabled ? "on" : "off"));
        /* AptX bt_swb: 0 -> on, 65535 -> off */
        am.setParameters("bt_swb=" + (mHasSwbAptXEnabled ? "0" : "65535"));
        am.setBluetoothHeadsetProperties(getCurrentDeviceName(), mHasNrecEnabled, mHasWbsEnabled);
    }

@@ -1797,21 +1807,48 @@ public class HeadsetStateMachine extends StateMachine {
        log("processWBSEvent: " + prevWbs + " -> " + mHasWbsEnabled);
    }

    private void processSWBEvent(int swbConfig) {
        boolean prev_swb = mHasSwbEnabled;
    private void processSWBEvent(int swbCodec, int swbConfig) {
        boolean prevSwbLc3 = mHasSwbLc3Enabled;
        boolean prevSwbAptx = mHasSwbAptXEnabled;
        boolean success = true;

        switch (swbConfig) {
            case HeadsetHalConstants.BTHF_SWB_YES:
                mHasSwbEnabled = true;
                switch (swbCodec) {
                    case HeadsetHalConstants.BTHF_SWB_CODEC_LC3:
                        mHasSwbLc3Enabled = true;
                        mHasWbsEnabled = false;
                        mHasSwbAptXEnabled = false;
                        break;
                    case HeadsetHalConstants.BTHF_SWB_CODEC_VENDOR_APTX:
                        mHasSwbLc3Enabled = false;
                        mHasWbsEnabled = false;
                        mHasSwbAptXEnabled = true;
                        break;
                    default:
                        success = false;
                        break;
                }
                break;
            case HeadsetHalConstants.BTHF_SWB_NO:
            case HeadsetHalConstants.BTHF_SWB_NONE:
                mHasSwbEnabled = false;
                mHasSwbLc3Enabled = false;
                mHasSwbAptXEnabled = false;
                break;
            default:
                Log.e(TAG, "processSWBEvent: unknown swb_config");
                success = false;
        }

        if (!success) {
            Log.e(
                    TAG,
                    ("processSWBEvent failed: swbCodec: " + swbCodec)
                            + (" swb_config: " + swbConfig));
            return;
        }
        log("processSWBEvent: " + prev_swb + " -> " + mHasSwbEnabled);

        log("processSWBEvent LC3 SWB config: " + prevSwbLc3 + " -> " + mHasSwbLc3Enabled);
        log("processSWBEvent AptX SWB config: " + prevSwbAptx + " -> " + mHasSwbAptXEnabled);
    }

    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ cc_library_static {
        "ag/bta_ag_rfc.cc",
        "ag/bta_ag_sco.cc",
        "ag/bta_ag_sdp.cc",
        "ag/bta_ag_swb_aptx.cc",
        "ar/bta_ar.cc",
        "av/bta_av_aact.cc",
        "av/bta_av_act.cc",
Loading