阅读 339

[蓝牙深入浅出系列] 蓝牙的Init流程

前言

之前分享过一篇蓝牙科普文章 蓝牙那点事儿 ,从蓝牙名称的由来,到蓝牙版本的演进,再到Android蓝牙的变化之路等做了一个总体上的描述,发现很多同学对蓝牙的技术都比较感兴趣,因此本系列文章将对蓝牙的各个技术流程深入浅出的从源码角度具体分析(qcom 865, android 11平台)

bt_arch1.png

android上蓝牙的架构,如上图所示,一共分为5层,分别是Bluetooth App, Bluetooth Framework,

Bluetooth HAL, Bluetooth driver以及bluetooth chip。

在高通平台上,蓝牙的进程在android初始化阶段不会被启动,所以对应的初始化往往是在enable的过程中发生的,为了和从setting enable蓝牙的流程区分开,本文将单独介绍BluetoothManagerService和Bluetooth Application的初始化流程。

一. BluetoothManagerService初始化

BluetoothManagerService作为蓝牙的deamon service, 主要负责蓝牙enable,disable以及蓝牙异常导致的restart,是bluetooth framework层一个核心service,下面先说一下BluetoothManagerService是如何初始化的

熟悉android init流程的同学应该都知道,android系统在初始化过程中的顺序如下:

init进程 –-> Zygote进程 –> SystemServer进程 –>应用进程

当SystemServer进程被zygote进程folk出来之后,在run方法中,SystemService会start很多services,这里关注下startOtherServices()方法

frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {

try {

    traceBeginAndSlog("InitBeforeStartServices");

...

// Start services.

try {

    traceBeginAndSlog("StartServices");

    startBootstrapServices();

    startCoreServices();

    startOtherServices();
复制代码
frameworks/base/services/java/com/android/server/SystemServer.java

/**

* Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.

*/

private void startOtherServices() {

    final Context context = mSystemContext;

...

if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {

    Slog.i(TAG, "No Bluetooth Service (factory test)");

} else if (!context.getPackageManager().hasSystemFeature

    (PackageManager.FEATURE_BLUETOOTH)) {

Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");

} else {

    traceBeginAndSlog("StartBluetoothService");

    mSystemServiceManager.startService(BluetoothService.class);

    traceEnd();

}
复制代码
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public void startService(@NonNull final SystemService service) {

    // Register it.

    mServices.add(service);

    // Start it.

    long time = SystemClock.elapsedRealtime();

    try {

    service.onStart();
复制代码

在startOtherServices()方法里,SystemServer会挨个启动一些android系统的核心service,比如InputManagerService,WindowManagerService,BluetoothService就是在这时候被start的

在SystemServiceManager的startService方法里,可以看到首先会把即将start的service加入到一个systemService的Arralist里,然后调用service的onStart方法

frameworks/base/services/core/java/com/android/server/BluetoothService.java

public BluetoothService(Context context) {

    super(context);

    mBluetoothManagerService = new BluetoothManagerService(context);

}

@Override

public void onBootPhase(int phase) {

    if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {

    publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,

    mBluetoothManagerService);

    }

}
复制代码

进入到BluetoothService的构造函数中,可以看到,BluetoothManagerService就是在这个时候被new出来的,然后当SystemServer将所有的system service启动完毕之后,会调用

mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY)

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public void startBootPhase(final int phase) {

...

    final int serviceLen = mServices.size();

    for (int i = 0; i < serviceLen; i++) {

    final SystemService service = mServices.get(i);

    long time = SystemClock.elapsedRealtime();

    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());

    try {

    service.onBootPhase(mCurrentPhase);
复制代码

这里的startBootPhase方法,会对SystemService的列表中的所有service进行遍历,然后挨个调用其对应的onBootPhase方法,所以最终BluetoothService的onBootPhase方法会被回调,如上所示,在这里会最终将BluetoothManagerService加入到ServiceManager中,以便于后面的binder调用,大体上的流程图如下所示

frameworks/base/services/java/com/android/server/SystemServer.java

protected final void publishBinderService(String name, IBinder service,

        boolean allowIsolated, int dumpPriority) {

    ServiceManager.addService(name, service, allowIsolated, dumpPriority);

}
复制代码

bluetooth_init_1.png

二. 蓝牙Application初始化

BluetoothApp的类图如下所示

bluetooth_init_class.png

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterApp.java

static {

    if (DBG) {

        Log.d(TAG, "Loading JNI Library");

    }

    System.loadLibrary("bluetooth_qti_jni");

}    

@Override

public void onCreate() {

    super.onCreate();

    if (DBG) {

        Log.d(TAG, "onCreate");
    }

    Config.init(this);

}
复制代码

Android 11上,因为bluetooth加入了apex计划,高通放弃了android 原生的代码,转而使用qcom目录的蓝牙代码工作

当Bluetooth App被start之后,AdapterApp首先进行执行静态代码块System.loadLibrary("bluetooth_qti_jni")

这里经过android runtime的反射调用,最终会走到下面的JNI_OnLoad方法中

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

jint JNI_OnLoad(JavaVM *jvm, void *reserved) {

    JNIEnv *e;

    int status;

    ALOGV("Bluetooth Adapter Service : loading JNI\n");

    // Check JNI version

    if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {

        ALOGE("JNI version mismatch error");

        return JNI_ERR;

}

    status = android::register_com_android_bluetooth_btservice_AdapterService(e);

    if (status < 0) {

        ALOGE("jni adapter service registration failure, status: %d", status);

        return JNI_ERR;

    }

    status = android::register_com_android_bluetooth_hfp(e);

    if (status < 0) {

        ALOGE("jni hfp registration failure, status: %d", status);

        return JNI_ERR;

    }

...

}
复制代码

com_android_bluetooth_btservice_AdapterService.cpp的JNI_OnLoad方法,将btService以及蓝牙各个常用profile的JNInativeMethod做了注册(上面代码只截取了hfp的一部分),后续java层面定义的方法就可以通过映射找到对应的native方法往下执行。

在onCreate()方法里,会调用Config.init(this), 将当前平台默认需要enable的profile加入到supportedProfile的list里面,等待后续的逐个start

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

static {

    System.loadLibrary("bluetooth_qti_jni");

    classInitNative();

}
复制代码

进入到AdapterService之中,静态代码块首先会再次load jni library(如果第一次没有load上),然后调用classInitNative

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

static void classInitNative(JNIEnv* env, jclass clazz) {

...

method_releaseWakeLock =

    env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");

method_energyInfo = env->GetMethodID(

    clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");

if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {

    ALOGE("No Bluetooth Library found");

}

}
复制代码

这里会将jni层的callback方法和java层的做映射,然后调用hal_util_load_bt_library去加载so的library

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

#define PROPERTY_BT_LIBRARY_NAME "ro.bluetooth.library_name"

#define DEFAULT_BT_LIBRARY_NAME "libbluetooth.so"


int hal_util_load_bt_library(const bt_interface_t** interface) {

  const char* sym = BLUETOOTH_INTERFACE_STRING;

  bt_interface_t* itf = nullptr;

  // The library name is not set by default, so the preset library name is used.

  char path[PROPERTY_VALUE_MAX] = "";

  property_get(PROPERTY_BT_LIBRARY_NAME, path, DEFAULT_BT_LIBRARY_NAME);

  void* handle = dlopen(path, RTLD_NOW);

  if (!handle) {

    const char* err_str = dlerror();

    LOG(ERROR) << __func__ << ": failed to load Bluetooth library, error="

               << (err_str ? err_str : "error unknown");

    goto error;

  }

  // Get the address of the bt_interface_t.

  itf = (bt_interface_t*)dlsym(handle, sym);

  if (!itf) {

    LOG(ERROR) << __func__ << ": failed to load symbol from Bluetooth library "

               << sym;

    goto error;

  }

  // Success.

LOG(INFO) << __func__ << " loaded HAL: btinterface=" << itf

          << ", handle=" << handle;

*interface = itf;

return 0;
复制代码

hal_util_load_bt_library函数中, 首先会去getprop "ro.bluetooth.library_name"的路径,如果拿不到,则去获取默认的libbluetooth.so路径,通过adb shell我可以可以看到qcom 865平台默认使用的高通的蓝牙协议栈,libbluetooth_qti.so(这个可以在system.prop文件去定义,qcom推荐使用libbluetooth_qti.so取代原生的libbluetooth.so)

darwin:/ # getprop | grep ro.bluetooth.library_name

[ro.bluetooth.library_name]: [libbluetooth_qti.so]
复制代码

然后通过dlopen打开对应的动态链接库,返回一个句柄给调用进程

最后调用dlsym根据dlopen返回的动态链接库的操作句柄与symbol返回symbol对应的函数地址并赋值给

sBluetoothInterface,所以jni侧可以通过sBluetoothInterface去调用动态链接库相关的方法

#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java  

 @Override

 public void onCreate() {

 super.onCreate();

 ...

 // step1 init IBluetooth binder server

 mBinder = new AdapterServiceBinder(this);

 ...
 
 // step2 Adapter State Machine start

 mAdapterStateMachine =  AdapterState.make(this);

 ...

 // step3 init native

 initNative(isGuest(), isSingleUserMode(), configCompareResult, isAtvDevice);

 ...
 
 // step4 Load the name and address

 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);

 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);

 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE);

 // step5 SdpManager init

 mSdpManager = SdpManager.init(this);
 
 // step6 ProfileObserver init

 mProfileObserver = new ProfileObserver(getApplicationContext(), this, new Handler());

 mProfileObserver.start();

 // step7 DatabaseManager start

 mDatabaseManager = new DatabaseManager(this);

 mDatabaseManager.start(MetadataDatabase.createDatabase(this));

 // step8 Phone policy start

 // Phone policy is specific to phone implementations and hence if a device wants to exclude

 // it out then it can be disabled by using the flag below.

 if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) {

     Log.i(TAG, "Phone policy enabled");

     mPhonePolicy = new PhonePolicy(this, new ServiceFactory());

     // step6 PhonePolicy start

     mPhonePolicy.start();

 }

// step9 BondStateMachine start

 mBondStateMachine = BondStateMachine.make(mPowerManager, this, mAdapterProperties, mRemoteDevices);

 // step10 ActiveDeviceManager start

 mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory());

 mActiveDeviceManager.start();

 // step11 SilenceDeviceManager start

 mSilenceDeviceManager = new SilenceDeviceManager(this, new ServiceFactory(),

         Looper.getMainLooper());

 mSilenceDeviceManager.start();

 // step12 Vendor init  

 mVendor.init();

 mVendorAvailble = mVendor.getQtiStackStatus();

 ...

 // Step13 AdapterProperty init

 mAdapterProperties.init(mRemoteDevices);

}
复制代码

AdapterService的onCreate()方法是初始化整个蓝牙的起点,完整的从上到下init过程,大概可以分为13个步骤,接下来一一做深入分析

1. 蓝牙binder server初始化

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

private static class AdapterServiceBinder extends IBluetooth.Stub {

    private AdapterService mService;

    AdapterServiceBinder(AdapterService svc) {

        mService = svc;

    }
复制代码

AdapterServiceBinder继承了IBluetooth.Stub,熟悉binder机制的同学应该都知道,这里是一个bind server的implementation,当蓝牙在enable的过程中,通过bindService或自动创建对应的service

2. 蓝牙状态机启动

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java

public static AdapterState make(AdapterService service) {

    Log.d(TAG, "make() - Creating AdapterState");

    AdapterState as = new AdapterState(service);

    as.start();

    return as;

}  

...

private AdapterState(AdapterService service) {

    super(TAG);

    addState(mOnState);

    addState(mBleOnState);

    addState(mOffState);

    addState(mTurningOnState);

    addState(mTurningOffState);

    addState(mTurningBleOnState);

    addState(mTurningBleOffState);

    mAdapterService = service;

    setInitialState(mOffState);

}
复制代码

AdapterState继承了StateMachine,主要的作用是控制蓝牙enable阶段状态的变化,从上面的代码中可以看到,在make方法中,状态机会被正式启动,AdapterState的状态比较多

enable流程执行的顺序,分别是OffState -> TurningBleOnState -> BleOnState -> TurningOnState -> OnState

disable流程执行的顺序,分别是OnState -> TurningOffState -> BleOnState -> TurningBleOffState -> OffState

3. 蓝牙Native初始化

initNative(isGuest(), isNiapMode()) 这个方法会初始化蓝牙底层的所有module

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,

                       jboolean isNiapMode) {
  ...

      int ret = sBluetoothInterface->init(&sBluetoothCallbacks,

                                      isGuest == JNI_TRUE ? 1 : 0,

                                      isNiapMode == JNI_TRUE ? 1 : 0);

  if (ret != BT_STATUS_SUCCESS && ret != BT_STATUS_DONE) {

    ALOGE("Error while setting the callbacks: %d\n", ret);

    sBluetoothInterface = NULL;

    return JNI_FALSE;

  }
复制代码

通过jni调用sBluetoothInterface->init, sBluetoothInterface在上面我们分析过,是打开libbluetooth_qti.so返回的函数地址,通过sBluetoothInterface可以调用协议栈对应的方法

vendor/qcom/opensource/commonsys/system/bt/btif/src/bluetooth.cc

static int init(bt_callbacks_t* callbacks, bool start_restricted,

                bool is_single_user_mode) {

  LOG_INFO(LOG_TAG, "QTI OMR1 stack: %s: start restricted = %d : single user = %d",

                     __func__, start_restricted, is_single_user_mode);

  if (interface_ready()) return BT_STATUS_DONE;

#ifdef BLUEDROID_DEBUG

  allocation_tracker_init();

#endif

  bt_hal_cbacks = callbacks;

  restricted_mode = start_restricted;

  single_user_mode = is_single_user_mode;

  stack_manager_get_interface()->init_stack();

  btif_debug_init();

  return BT_STATUS_SUCCESS;

}
复制代码

bluetooth.cc是bluetooth hal的实现,所以我们调用到这里的init方法,看下init_stack的实现

vendor/qcom/opensource/commonsys/system/bt/btif/src/stack_manager.cc

static void init_stack(void) {

  // This is a synchronous process. Post it to the thread though, so

  // state modification only happens there. Using the thread to perform

  // all stack operations ensures that the operations are done serially

  // and do not overlap.

  semaphore_t* semaphore = semaphore_new(0);

  thread_post(management_thread, event_init_stack, semaphore);

  semaphore_wait(semaphore);

  semaphore_free(semaphore);

}

static void event_init_stack(void* context) {

  semaphore_t* semaphore = (semaphore_t*)context;

  LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__);

  if (stack_is_initialized) {

    LOG_INFO(LOG_TAG, "%s found the stack already in initialized state",

             __func__);

  } else {

    module_management_start();

    start_bt_logger();

    module_init(get_module(OSI_MODULE));

    module_init(get_module(BT_UTILS_MODULE));

#if (BT_IOT_LOGGING_ENABLED == TRUE)

    module_init(get_module(DEVICE_IOT_CONFIG_MODULE));

#endif

    module_init(get_module(BTIF_CONFIG_MODULE));

    future_t* local_hack_future = future_new();

    hack_future = local_hack_future;

    btif_init_bluetooth();

    future_await(local_hack_future);

    // stack init is synchronous, so no waiting necessary here

    stack_is_initialized = true;

  }

  LOG_INFO(LOG_TAG, "%s finished", __func__);

  if (semaphore) semaphore_post(semaphore);

}
复制代码

init_stack是一个同步的方法,在management_thread的子线程中去执行event_init_stack操作

event_init_stack是一个线程同步的方法,会去完成bluetooth stack的初始化

首先会去init四个模块,分别是"osi_module","bt_utils_module", "device_iot_config_module", "btif_config_module",然后去执行btif_init_bluetooth

vendor/qcom/opensource/commonsys/system/bt/btif/src/btif_core.cc

bt_status_t btif_init_bluetooth() {

  LOG_INFO(LOG_TAG, "%s entered", __func__);

  bte_main_boot_entry();

  char twsplus_prop[PROPERTY_VALUE_MAX] = "false";

  property_get("persist.vendor.btstack.enable.twsplus", twsplus_prop, "false");

  if(!strcmp(twsplus_prop, "false")) {

    twsplus_enabled = false;

  } else {

    twsplus_enabled = true;

  }

  bt_jni_workqueue_thread = thread_new_sized(BT_JNI_WORKQUEUE_NAME, MAX_JNI_WORKQUEUE_COUNT);

  if (bt_jni_workqueue_thread == NULL) {

    LOG_ERROR(LOG_TAG, "%s Unable to create thread %s", __func__,

              BT_JNI_WORKQUEUE_NAME);

    goto error_exit;

  }

  thread_post(bt_jni_workqueue_thread, run_message_loop, nullptr);

  LOG_INFO(LOG_TAG, "%s finished", __func__);

  return BT_STATUS_SUCCESS;
复制代码

这里首先会调用bte_main_boot_entry方法,init "interop_module","profile_config_module", "stack_config_module" 以及hci layer ,然后start一个message loop,到这里bluetooth stack init方法结束

4. 蓝牙名称和mac地址加载

回到AdapterService的onCreate方法,接下里就是去获取address,name和cod的值

getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);

getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);

getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE);

5. SdpManager初始化

vendor/qcom/opensource/commonsys/system/bt/btif/src/btif_sdp.cc

static bt_status_t init(btsdp_callbacks_t* callbacks) {

  BTIF_TRACE_DEBUG("Sdp Search %s", __func__);

  bt_sdp_callbacks = callbacks;

  sdp_server_init();

  btif_enable_service(BTA_SDP_SERVICE_ID);

  return BT_STATUS_SUCCESS;

}
复制代码

蓝牙的服务发现都是基于sdp的,SdpManager主要负责sdp的search和各个profile service record的创建

通过jni的调用,sdp的初始化会在btif_sdp.cc文件中完成

这里调用了以下两个方法:

  1. sdp_server_init
  2. btif_enable_service(BTA_SDP_SERVICE_ID)

sdp_server_init完成了对sdp_slots的初始化,sdp的最大slot为 #define MAX_SDP_SLOTS 128

vendor/qcom/opensource/commonsys/system/bt/btif/src/btif_core.cc

bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id) {

  tBTA_SERVICE_ID* p_id = &service_id;

  /* If BT is enabled, we need to switch to BTIF context and trigger the

   * enable for that profile
 
   * Otherwise, we just set the flag. On BT_Enable, the DM will trigger

   * enable for the profiles that have been enabled */

  btif_enabled_services |= ((tBTA_SERVICE_MASK)1 << service_id);

  BTIF_TRACE_DEBUG("%s: current services:0x%" PRIx64, __func__,

                   btif_enabled_services);

  if (btif_is_enabled()) {

    btif_transfer_context(btif_dm_execute_service_request,

                          BTIF_DM_ENABLE_SERVICE, (char*)p_id,

                          sizeof(tBTA_SERVICE_ID), NULL);
  }

  return BT_STATUS_SUCCESS;

}
复制代码

首先会将btif_enabled_services的flag加上SDP service,然后调用btif_dm_execute_service_request

vendor/qcom/opensource/commonsys/system/bt/btif/src/btif_dm.cc

bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
                                            bool b_enable) {

  BTIF_TRACE_DEBUG("%s service_id: %d", __func__, service_id);

  /* Check the service_ID and invoke the profile's BT state changed API */

  switch (service_id) {

    case BTA_HFP_SERVICE_ID:

    case BTA_HSP_SERVICE_ID: {

      bluetooth::headset::btif_hf_execute_service(b_enable);

    } break;

    case BTA_A2DP_SOURCE_SERVICE_ID: {

      btif_av_execute_service(b_enable);

    } break;

    case BTA_A2DP_SINK_SERVICE_ID: {

      btif_av_sink_execute_service(b_enable);

    } break;

    case BTA_HID_SERVICE_ID: {

      btif_hh_execute_service(b_enable);

    } break;

    case BTA_HFP_HS_SERVICE_ID: {

      btif_hf_client_execute_service(b_enable);

    } break;

    case BTA_SDP_SERVICE_ID: {

      btif_sdp_execute_service(b_enable);

    } break;
复制代码

根据传入的ID为BTA_SDP_SERVICE_ID,继续调用btif_sdp_execute_service,这里b_enable为true

vendor/qcom/opensource/commonsys/system/bt/bta/sdp/bta_sdp_api.cc

tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK* p_cback) {

  tBTA_SDP_STATUS status = BTA_SDP_FAILURE;

  APPL_TRACE_API(__func__);

  if (p_cback && false == bta_sys_is_register(BTA_ID_SDP)) {

    memset(&bta_sdp_cb, 0, sizeof(tBTA_SDP_CB));

    /* register with BTA system manager */

    bta_sys_register(BTA_ID_SDP, &bta_sdp_reg);

    if (p_cback) {

      tBTA_SDP_API_ENABLE* p_buf =

          (tBTA_SDP_API_ENABLE*)osi_malloc(sizeof(tBTA_SDP_API_ENABLE));

      p_buf->hdr.event = BTA_SDP_API_ENABLE_EVT;

      p_buf->p_cback = p_cback;

      bta_sys_sendmsg(p_buf);

      status = BTA_SDP_SUCCESS;

    }

  }

  return status;
}
复制代码

BTA_SdpEnable中,会对SDP进行注册,然后发送bta_sys_sendmsg,event为BTA_SDP_API_ENABLE_EVT

vendor/qcom/opensource/commonsys/system/bt/bta/sdp/bta_sdp_act.cc

void bta_sdp_enable(tBTA_SDP_MSG* p_data) {

  APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);

  tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;

  bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;

  tBTA_SDP bta_sdp;

  bta_sdp.status = status;

  bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, &bta_sdp, NULL);

}
复制代码

bta_sdp_enable是最终初始化SDP I/F的地方,将pback进行赋值,然后回调callback给上层

6. ProfileObserver初始化

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/ProfileObserver.java

private static class AdapterStateObserver extends BroadcastReceiver {

    private ProfileObserver mProfileObserver;

    AdapterStateObserver(ProfileObserver observer) {

        mProfileObserver = observer;

    }

    @Override

    public void onReceive(Context context, Intent intent) {

        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())

                && intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)

                == BluetoothAdapter.STATE_OFF) {

            mProfileObserver.onBluetoothOff();

        }

    }

}
复制代码

ProfileObserver主要负责对已经enabled的profile的管理。在init方法中,会创建一个contentObserver,监听"bluetooth_disabled_profiles"这个值,一旦发生了变化,就会通过AdapterService将蓝牙给disable掉

7. DatabaseManager启动

DatabaseManager的作用是利用room database处理active device的持久化数据

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/storage/DatabaseManager.java

public void start(MetadataDatabase database) {

    if (DBG) {

        Log.d(TAG, "start()");

    }

    if (mAdapterService == null) {

        Log.e(TAG, "stat failed, mAdapterService is null.");

        return;

    }

    if (database == null) {

        Log.e(TAG, "stat failed, database is null.");

        return;

    }

    mDatabase = database;

    mHandlerThread = new HandlerThread("BluetoothDatabaseManager");

    mHandlerThread.start();

    mHandler = new DatabaseHandler(mHandlerThread.getLooper());

    IntentFilter filter = new IntentFilter();

    filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);

    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);

    mAdapterService.registerReceiver(mReceiver, filter);

    loadDatabase();

}
复制代码

首先会创建一个HandlerThread用于处于DatabaseHandler接收到的相关message

然后注册了ACTION_BOND_STATE_CHANGED 和 ACTION_STATE_CHANGED两个状态变化的广播

最后调用loadDatabase去加载之前的bluetooth persistent 数据

8. Phone policy启动

PhonePolicy主要负责以下两个功能:

  • 当蓝牙开启之后,有自动连接优先级profile的自动重连
  • 当profile的状态发生变化时,如果蓝牙支持的某一个profile处于connected状态,policy会自动去尝试连接其他支持的profile
vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/PhonePolicy.java

 // Policy API functions for lifecycle management (protected)

    protected void start() {

        IntentFilter filter = new IntentFilter();

        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);

        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);

        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);

        filter.addAction(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);

        filter.addAction(BluetoothDevice.ACTION_UUID);

        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);

        filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);

        filter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);

        filter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);

        mAdapterService.registerReceiver(mReceiver, filter);

    }
复制代码

policy的start方法中,主要是监听了目前蓝牙上常用的profile的连接状态和激活状态的变化的广播事件,在蓝牙工作的过程中,会根据收到的特定广播,做出相对应的逻辑处理

9. 蓝牙配对状态机启动

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java

public static BondStateMachine make(PowerManager pm, AdapterService service,

        AdapterProperties prop, RemoteDevices remoteDevices) {

    Log.d(TAG, "make");

    BondStateMachine bsm = new BondStateMachine(pm, service, prop, remoteDevices);

    bsm.start();

    return bsm;
}
...

private BondStateMachine(PowerManager pm, AdapterService service,

        AdapterProperties prop, RemoteDevices remoteDevices) {

    super("BondStateMachine:");

    addState(mStableState);

    addState(mPendingCommandState);

    mRemoteDevices = remoteDevices;

    mAdapterService = service;

    mAdapterProperties = prop;

    mAdapter = BluetoothAdapter.getDefaultAdapter();

    setInitialState(mStableState);
复制代码

和AdapterState一样,BondStateMachine也是控制蓝牙状态变化的一个状态机,蓝牙的配对,鉴权认证等操作都是通过它来操作。

BondStateMachine主要有两个状态,一个是StableState,一个是PendingCommandState。StableState表示的是当前蓝牙处于空闲状态,PendingCommandState表示当前蓝牙处于执行command的过程中,等待执行完毕。状态机的初始化状态为StableState

10. ActiveDeviceManager启动

ActiveDeviceManager主要负责A2dp, Hfp, Avrcp, Hearing Aid的select管理

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/ActiveDeviceManager.java

void start() {

    if (DBG) {

        Log.d(TAG, "start()");

    }

    mHandlerThread = new HandlerThread("BluetoothActiveDeviceManager");

    mHandlerThread.start();

    mHandler = new ActiveDeviceManagerHandler(mHandlerThread.getLooper());

    IntentFilter filter = new IntentFilter();

    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);

    filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);

    filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);

    filter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);

    mAdapterService.registerReceiver(mReceiver, filter);

    mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);  

}
复制代码

创建一个HandlerThread用于处理ActiveDevice的相关的message

主要注册了A2dp, Hfp, hearing aid和adapter相关的连接状态变化广播

11. SilenceDeviceManager启动

SilienceDeviceManager是一个控制A2dp,Hfp,Avrcp静音模式的管理类

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/SilenceDeviceManager.java

void start() {

    if (VERBOSE) {

        Log.v(TAG, "start()");

    }

    mHandler = new SilenceDeviceManagerHandler(mLooper);

    IntentFilter filter = new IntentFilter();

    filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);

    filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);

    mAdapterService.registerReceiver(mReceiver, filter);

}
复制代码

这里创建一个SilenceDeviceManagerHandler去处理a2dp,hfp的连接状态变化的广播,当对应的profile状态发生变化时,handler会根据silence mode的规则进行对应的设置

12. Vendor Feature初始化

vendor/qcom/opensource/commonsys/bluetooth_ext/packages_apps_bluetooth_ext/src/btservice/Vendor.java

public void init(){

    initNative();

    isQtiStackEnabled = getQtiStackStatusNative();

    Log.d(TAG,"Qti Stack enabled status: " + isQtiStackEnabled);

    socName = getSocNameNative();

    Log.d(TAG,"socName: " + socName);

    a2dpOffloadCap = getA2apOffloadCapabilityNative();

    Log.d(TAG,"a2dpOffloadCap: " + a2dpOffloadCap);

    splitA2dpEnabled = isSplitA2dpEnabledNative();

    Log.d(TAG,"splitA2dpEnabled: " + splitA2dpEnabled);

    isSwbEnabled = isSwbEnabledNative();

    Log.d(TAG,"isSwbEnabled: " + isSwbEnabled);

    isSwbPmEnabled = isSwbPmEnabledNative();

    Log.d(TAG,"isSwbPmEnabled: " + isSwbPmEnabled);

}
复制代码

vendor init是针对高通平台的特定feature的初始化

vendor/qcom/opensource/commonsys/bluetooth_ext/packages_apps_bluetooth_ext/jni/com_android_bluetooth_btservice_vendor.cpp

static void initNative(JNIEnv *env, jobject object) {

    const bt_interface_t* btInf;

    bt_status_t status;

    load_bt_configstore_lib();

    if (bt_configstore_intf != NULL) {

       std::vector<vendor_property_t> vPropList;

       bt_configstore_intf->get_vendor_properties(BT_PROP_ALL, vPropList);

       for (auto&& vendorProp : vPropList) {

          if (vendorProp.type == BT_PROP_SOC_TYPE) {

            strlcpy(soc_name, vendorProp.value, sizeof(soc_name));

            ALOGI("%s:: soc_name = %s",__func__, soc_name);

          } else if(vendorProp.type == BT_PROP_SPILT_A2DP) {

            if (!strncasecmp(vendorProp.value, "true", sizeof("true"))) {

              spilt_a2dp_supported = true;

            } else {

              spilt_a2dp_supported = false;

            }

          } else if(vendorProp.type == BT_PROP_SWB_ENABLE) {

            if (!strncasecmp(vendorProp.value, "true", sizeof("true"))) {

              swb_supported = true;

            } else {

              swb_supported = false;

            }

          } else if(vendorProp.type == BT_PROP_SWBPM_ENABLE) {

            if (!strncasecmp(vendorProp.value, "true", sizeof("true"))) {

              swb_pm_supported = true;

            } else {

              swb_pm_supported = false;

            }

          } else if(vendorProp.type == BT_PROP_A2DP_OFFLOAD_CAP) {

            strlcpy(a2dp_offload_Cap, vendorProp.value, sizeof(a2dp_offload_Cap));

            ALOGI("%s:: a2dp_offload_Cap = %s", __func__, a2dp_offload_Cap);

          }

       }

    }

    if ( (btInf = getBluetoothInterface()) == NULL) {

        ALOGE("Bluetooth module is not loaded");

        return;

    }

    if (mCallbacksObj != NULL) {

        ALOGW("Cleaning up Bluetooth Vendor callback object");

        env->DeleteGlobalRef(mCallbacksObj);

        mCallbacksObj = NULL;

    }

    if ( (sBluetoothVendorInterface = (btvendor_interface_t *)

          btInf->get_profile_interface(BT_PROFILE_VENDOR_ID)) == NULL) {

        ALOGE("Failed to get Bluetooth Vendor Interface");

        return;

    }

    if ( (status = sBluetoothVendorInterface->init(&sBluetoothVendorCallbacks))

                 != BT_STATUS_SUCCESS) {

        ALOGE("Failed to initialize Bluetooth Vendor, status: %d", status);

        sBluetoothVendorInterface = NULL;

        return;

    }

    mCallbacksObj = env->NewGlobalRef(object);

    sBluetoothVendorInterface->set_property_callouts(&sBluetoothPropertyCallout);

}
复制代码

这里首先调用load_bt_configstore_lib这个方法,去dlopen "libbtconfigstore.so"

然后去尝试获取一些qcom bluetooth feature,比如soc name, split a2dp 是否support

vendor/qcom/opensource/commonsys/bluetooth_ext/system_bt_ext/btif/src/btif_vendor.cc

static bt_status_t init( btvendor_callbacks_t* callbacks)

{

    bt_vendor_callbacks = callbacks;

    broadcast_cb_timer = alarm_new("btif_vnd.cb_timer");

    LOG_INFO(LOG_TAG,"init");

    LOG_INFO(LOG_TAG,"init done");

    return BT_STATUS_SUCCESS;

}
复制代码

在协议栈的init方法中,会对jni传递过来的callbacks进行赋值,以便于后续的event上报

initNative执行完毕之后,接下来就是通过jni拿到刚刚从"libbtconfigstore.so"中解析的一些值

以下为目前qcom平台上支持的vendor feature功能

 497 03-06 10:25:06.459 13331 13331 D BluetoothVendorService: Qti Stack enabled status: true

 498 03-06 10:25:06.459 13331 13331 I BluetoothVendorJni: getSocNameNative

 499 03-06 10:25:06.459 13331 13331 D BluetoothVendorService: socName: cherokee

 500 03-06 10:25:06.459 13331 13331 I BluetoothVendorJni: getA2apOffloadCapabilityNative

 501 03-06 10:25:06.459 13331 13331 D BluetoothVendorService: a2dpOffloadCap: sbc-aptx-aptxtws-aptxhd-aac-ldac-aptxadaptive

 502 03-06 10:25:06.459 13331 13331 I BluetoothVendorJni: isSplitA2dpEnabledNative

 503 03-06 10:25:06.459 13331 13331 D BluetoothVendorService: splitA2dpEnabled: true

 504 03-06 10:25:06.459 13331 13331 I BluetoothVendorJni: isSwbEnabledNative

 505 03-06 10:25:06.459 13331 13331 D BluetoothVendorService: isSwbEnabled: true

 506 03-06 10:25:06.460 13331 13331 I BluetoothVendorJni: isSwbPmEnabledNative

 507 03-06 10:25:06.460 13331 13331 D BluetoothVendorService: isSwbPmEnabled: true
复制代码

13. AdapterProperty初始化

vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java

public void init(RemoteDevices remoteDevices) {

    mProfileConnectionState.clear();

    mRemoteDevices = remoteDevices;

    mBluetoothPrefs = PreferenceManager.getDefaultSharedPreferences(

            mService.getApplicationContext());

    mBluetoothEditor = mBluetoothPrefs.edit();

    // Get default max connected audio devices from config.xml in frameworks/base/core

    int configDefaultMaxConnectedAudioDevices = mService.getResources().getInteger(
            com.android.internal.R.integer.config_bluetooth_max_connected_audio_devices);

    // Override max connected audio devices if MAX_CONNECTED_AUDIO_DEVICES_PROPERTY is set

    int propertyOverlayedMaxConnectedAudioDevices =
            SystemProperties.getInt(MAX_CONNECTED_AUDIO_DEVICES_PROPERTY,

                    configDefaultMaxConnectedAudioDevices);

    // Make sure the final value of max connected audio devices is within allowed range

    mMaxConnectedAudioDevices = Math.min(Math.max(propertyOverlayedMaxConnectedAudioDevices,
            MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOND), MAX_CONNECTED_AUDIO_DEVICES_UPPER_BOUND);

    ...

    mA2dpOffloadEnabled =

            SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false)

                    && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);

    IntentFilter filter = new IntentFilter();

    filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);

    mService.registerReceiver(mReceiver, filter);
    ...
}
复制代码

AdapterProperty这个类主要对蓝牙的一些系统属性进行了获取和保存

在init方法里,进行了如下的操作:

  1. 通过xml默认值和system prop的value来确认当前平台蓝牙默认支持的最大可连接的audio devices
  2. 获取当前平台的split a2dp功能是否enable
  3. 注册当前平台蓝牙支持的profile的ACTION_CONNECTION_STATE_CHANGED的广播,会根据不同profile的状态变化,进行相应的数据库value存取,并发送对应的状态变化的广播通知出去

完整的蓝牙init时序图如下:

1111104a4a210fe07454db07509fc9adb8d0f.png

文章分类
Android
文章标签