当前位置:   article > 正文

Android 蓝牙启动流程(以及设置蓝牙为作为sink模式 & 接收端模式)_bluetoothadapterservice: startservice com.android.

bluetoothadapterservice: startservice com.android.bluetooth.hid.hiddeviceser

本文以Android 7.1为基础

最近在做蓝牙开发,研究了一下蓝牙的启动流程,总结一下

Google在Android源码中推出了它和博通公司一起开发的BlueDroid以替代BlueZ。BlueZ的创始者,高通公司也将在基于其芯片的Android参考设计中去除BlueZ,支持BlueDroid。相比BlueZ,BlueDroid最值得称道的地方就是其框架结构变得更为简洁和清晰。对我们工程师来说这也是个不错的福利,清晰、简洁的架构使我们在debug过程中思路更清晰;

蓝牙的总体流程图

从流程图我们可以看出来 蓝牙应用通过binder和系统蓝牙Service进行通讯 ,然后通过Jin与蓝牙HAL层进行通讯。

按层级划分

Bluetooth Service(Java层)代码路径

frameworks/base/core/java/Android/Bluetooth:

Bluetooth 应用层代码路径

packages/apps/Bluetooth

Bluetooth协议层代码

system/bt/

涉及的总共路径:

  1. frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
  2. frameworks/base/core/java/android/bluetooth/BluetoothManagerService.java
  3. packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
  4. packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
  5. packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
  6. system/bt/btif/src/btif_dm.c
  7. system/bt/btif/include/btif_common.h
  8. hardware/libhardware/include/hardware/bluetooth.h 

一.将蓝牙作为sink模式 配置

sink模式一般是车机端需要设置的模式,用于链接手机之后可以播放蓝牙音乐,获取联系人,和电话控制等等

  1. packages/apps/Bluetooth/src/com/android/bluetooth/btservice/Config.java
  2. 有如下两个参数控制是否是 sink端
  3.  
  4. boolean isA2dpSinkEnabled = SystemProperties.getBoolean("persist.service.bt.a2dp.sink", false);
  5.         boolean isHfpClientEnabled = SystemProperties.getBoolean("persist.service.bt.hfp.client",false);

我们需要在编译源码的时候去配置成sink模式:

  1. device/qcom/msmxxx_64/system.prop
  2. 添加如下配置
  3. persist.service.bt.a2dp.sink=true
  4. persist.service.bt.hfp.client=true

再具体的配置信息在如下配置中进行设置具体支持那种profile

packages/apps/Bluetooth/res/values/config.xml
  1. <resources>
  2.     <bool name="profile_supported_a2dp">true</bool>
  3.     <bool name="profile_supported_a2dp_sink">false</bool>
  4.     <bool name="profile_supported_hdp">true</bool>
  5.     <bool name="profile_supported_hs_hfp">true</bool>
  6.     <bool name="profile_supported_hfpclient">false</bool>
  7.     <bool name="profile_supported_hid">true</bool>
  8.     <bool name="profile_supported_opp">true</bool>
  9.     <bool name="profile_supported_pan">true</bool>
  10.     <bool name="profile_supported_pbap">true</bool>
  11.     <bool name="profile_supported_gatt">true</bool>
  12.     <bool name="pbap_include_photos_in_vcard">true</bool>
  13.     <bool name="pbap_use_profile_for_owner_vcard">true</bool>
  14.     <bool name="profile_supported_map">true</bool>
  15.     <bool name="profile_supported_avrcp_controller">false</bool>
  16.     <bool name="profile_supported_sap">false</bool>
  17.     <bool name="profile_supported_pbapclient">false</bool>
  18.     <bool name="strict_location_check">true</bool>
  19. </resources>

当然修改上面的配置我们可以在如下路径配置

  1. vendor/qcom/opensource/bluetooth/res/values/config.xml
  2. <resources>
  3.     <bool name="profile_supported_ftp">true</bool>
  4.     <bool name="profile_supported_map">false</bool>
  5.     <bool name="profile_supported_sap">true</bool>
  6.     <bool name="profile_supported_dun">true</bool>
  7. </resources>

如果 packages/apps/Bluetooth/res/values/config.xml 和 vendor/qcom/opensource/bluetooth/res/values/config.xml 都配置了如下配置 或者是配置的两个Boolean 值是反向的,系统会依据 vendor/qcom/opensource/bluetooth/res/values/config.xml 配置为最终结果,配置完成之后编译系统,烧录系统就可以作为sink端使用,也就是接收端.

二.启动流程分析

首先我们先看一下时序图

我们调用蓝牙的时候使用的是Bluetooth的 BluetoothAdapter.java 类 中的enable方法 

路径如下:

  1. frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
  1. public boolean enable() {
  2. android.util.SeempLog.record(56);
  3. if (isEnabled()) {
  4. if (DBG) Log.d(TAG, "enable(): BT already enabled!");
  5. return true;
  6. }
  7. try {
  8. // 此处调用的是 IBluetoothManager.java的 enable
  9. return mManagerService.enable(ActivityThread.currentPackageName());
  10. } catch (RemoteException e) {Log.e(TAG, "", e);}
  11. return false;
  12. }

我们查看到 IBluetoothManager.java的实现类是BluetoothManagerService.java , BluetoothManagerService.java

  1. class BluetoothManagerService extends IBluetoothManager.Stub {
  2.  .....省略代码.....
  3.   public boolean enable(String packageName) throws RemoteException {
  4.         final int callingUid = Binder.getCallingUid();
  5.         final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
  6.         .....省略代码.....
  7.         // 权限检查
  8.         .....省略代码.....
  9.  
  10.         synchronized(mReceiver) {
  11.             mQuietEnableExternal = false;
  12.             mEnableExternal = true;
  13.             // waive WRITE_SECURE_SETTINGS permission check
  14.             sendEnableMsg(false, packageName);
  15.         }
  16.         if (DBG) Slog.d(TAG, "enable returning");
  17.         return true;
  18.     }
  19.  .....省略代码.....
  20. }

我们继续查看可以看到调用的是 sendEnableMsg(boolean quietMode, String packageName) 方法. 

  1. private void sendEnableMsg(boolean quietMode, String packageName) {
  2.         mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
  3.                              quietMode ? 1 : 0, 0));
  4.         addActiveLog(packageName, true);
  5.     }

在sendEnableMsg 方法中 发送了一个message消息 MESSAGE_ENABLE 

  1.  case MESSAGE_ENABLE:
  2.                     
  3.                     try {
  4.                         if (mBluetooth != null) {
  5.                             int state = mBluetooth.getState();
  6.                             if (state == BluetoothAdapter.STATE_BLE_ON) {
  7.                                 //如果蓝牙已经打开调用 BluetoothAdapterService.java 开启profile
  8.                                 mBluetooth.onLeServiceUp();
  9.                                 //保存蓝牙的开关状态
  10.                                 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
  11.                                 break;
  12.                             }
  13.                         }
  14.                     }
  15.                     mQuietEnable = (msg.arg1 == 1);
  16.                     //如果没有蓝牙没有打开去打开蓝牙
  17.                     if (mBluetooth == null) {
  18.                         handleEnable(mQuietEnable);
  19.                     } else {
  20.                      
  21.                         if(state == BluetoothAdapter.STATE_TURNING_OFF || state == BluetoothAdapter.STATE_BLE_TURNING_OFF)
  22.                             waitForMonitoredOnOff(false, true);
  23.                         //重启蓝牙
  24.                         Message restartMsg = mHandler.obtainMessage(
  25.                                 MESSAGE_RESTART_BLUETOOTH_SERVICE);
  26.                         mHandler.sendMessageDelayed(restartMsg,
  27.                                 2 * SERVICE_RESTART_TIME_MS);
  28.                     }
  29.                     break;

在 MESSAGE_ENABLE 接收的消息中会先判断盘牙是否打开,如果已经打开 就调用mBluetooth.onLeServiceUp();去打开 Profile文件如果没有打开就调用handleEnable(mQuietEnable);去打开蓝牙. 咱们这里先不看 mBluetooth.onLeServiceUp(); 方法先查看handleEnable(mQuietEnable)

  1. private void handleEnable(boolean quietMode) {
  2.       
  3.             if ((mBluetooth == null) && (!mBinding)) {
  4.                 //蓝牙打开超时记录
  5.                 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
  6.                 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
  7.                 Intent i = new Intent(IBluetooth.class.getName());
  8.                 //此处我们查看到  mConnection 方法是链接状态的回调 
  9.                 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
  10.                         UserHandle.CURRENT)) {
  11.                     mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
  12.                 } else {
  13.                     mBinding = true;
  14.                 }
  15.             } 
  16.     }

其中mConnection 是链接的回调 BluetoothServiceConnection 就是 mConnection 类

在BluetoothServiceConnection 类中会发送   MESSAGE_BLUETOOTH_SERVICE_CONNECTED 消息并传递了一个 AdapterService对象.

  1.  private class BluetoothServiceConnection implements ServiceConnection {
  2.         public void onServiceConnected(ComponentName componentName, IBinder service) {
  3.             String name = componentName.getClassName();
  4.             if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
  5.             Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
  6.             if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
  7.                 msg.arg1 = SERVICE_IBLUETOOTH;
  8.             } 
  9.             msg.obj = service;
  10.             mHandler.sendMessage(msg);
  11.         }
  12.  
  13.         public void onServiceDisconnected(ComponentName componentName) {
  14.             // Called if we unexpectedly disconnect.
  15.             String name = componentName.getClassName();
  16.             if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
  17.             Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
  18.             if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
  19.                 msg.arg1 = SERVICE_IBLUETOOTH;
  20.             }
  21.             mHandler.sendMessage(msg);
  22.         }
  23.     }

我们继续追踪  MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息 

  1. case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
  2.                 {
  3.                     IBinder service = (IBinder) msg.obj;
  4.                     mBinding = false;
  5.                     mBluetoothBinder = service;
  6.                     mBluetooth = IBluetooth.Stub.asInterface(service);
  7.                     //注册 CallBack 重要,后面的回调要使用
  8.                     try {
  9.                         mBluetooth.registerCallback(mBluetoothCallback);
  10.                     } catch (RemoteException re) {
  11.                         Slog.e(TAG, "Unable to register BluetoothCallback",re);
  12.                     }
  13.                     //Do enable request
  14.                     try {
  15.                         //打开蓝牙请求
  16.                         if (mQuietEnable == false) {
  17.                             if (!mBluetooth.enable()) {
  18.                                 Slog.e(TAG,"IBluetooth.enable() returned false");
  19.                             }
  20.                         }
  21.                     }
  22.                     break;
  23.                 }

MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息里面可以查看到 mBluetooth = IBluetooth.Stub.asInterface(service);获取的是 IBluetooth 对象 , 而AdapterService.java 内部类 AdapterServiceBinder  实现了 IBluetooth 

packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
  1.   private static class AdapterServiceBinder extends IBluetooth.Stub {
  2.         private AdapterService mService;
  3.  
  4.         public AdapterService getService() {
  5.             if (mService != null && mService.isAvailable()) {
  6.                 return mService;
  7.             }
  8.             return null;
  9.         }
  10.  
  11.       public boolean enable() {
  12.            ........
  13.             AdapterService service = getService();
  14.             if (service == null) return false;
  15.             return service.enable();
  16.         }
  17.     }

由上面可以看出 return service.enable();调用的是 AdapterService.java 中的方法 enable() 方法

  1.  public synchronized boolean enable(boolean quietMode) {
  2.          enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
  3.  
  4.          debugLog("enable() - Enable called with quiet mode status =  " + mQuietmode);
  5.          mQuietmode = quietMode;
  6.          Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);
  7.          mAdapterStateMachine.sendMessage(m);
  8.          mBluetoothStartTime = System.currentTimeMillis();
  9.          return true;
  10.      }

发送的是 BLE_TURN_ON,

packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java 接受了这个消息 

  1. case BLE_TURN_ON:
  2.                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
  3.                    //将蓝牙的状态转换成 mPendingCommandState
  4.                    mPendingCommandState.setBleTurningOn(true);
  5.                    transitionTo(mPendingCommandState);
  6.                    sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
  7.                    adapterService.BleOnProcessStart();
  8.                    break;

将蓝牙的状态转换成 mPendingCommandState 调用 BleOnProcessStart 方法,也可以在supportedProfileServices  方法中去掉自己不想开启的ProfileService.

  1.    void BleOnProcessStart()
  2.         
  3.         //获取支持的profile 文件
  4.         Class[] supportedProfileServices = Config.getSupportedProfiles();
  5.         //Initialize data objects
  6.         for (int i=0; i < supportedProfileServices.length;i++) {
  7.             mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);
  8.         }
  9.         mRemoteDevices.cleanup();
  10.         mAdapterProperties.init(mRemoteDevices);
  11.         mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
  12.         //Start Gatt service
  13.         //调用 ProfileService
  14.         setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
  15.     }

获取支持的ProfileService列表. 

  1.   private static final Class[] PROFILE_SERVICES = {
  2.         HeadsetService.class,
  3.         A2dpService.class,
  4.         A2dpSinkService.class,
  5.         HidService.class,
  6.         HealthService.class,
  7.         PanService.class,
  8.         GattService.class,
  9.         BluetoothMapService.class,
  10.         HeadsetClientService.class,
  11.         AvrcpControllerService.class,
  12.         SapService.class,
  13.         PbapClientService.class
  14.     };

//发送  ACTION_SERVICE_STATE_CHANGED参数 每一个profile 都有 遍历开启 profile 

  1.   private void setGattProfileServiceState(Class[] services, int state) {
  2.  
  3.         for (int i=0; i <services.length;i++) {
  4.                 mProfileServicesState.put(serviceName,pendingState);
  5.                 Intent intent = new Intent(this,services[i]);
  6.                 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
  7.                 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
  8.                 startService(intent);
  9.                 return;
  10.             }
  11.         }
  12.     }
  1.   public int onStartCommand(Intent intent, int flags, int startId) {
  2.         if (intent == null) {
  3.             Log.d(mName, "Restarting profile service...");
  4.             return PROFILE_SERVICE_MODE;
  5.         } else {
  6.             String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
  7.             if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
  8.                 } else if (state == BluetoothAdapter.STATE_ON) {
  9.                        ........省略代码......
  10.                         // 开启服务
  11.                          doStart(intent);
  12.                 }
  13.         }
  14.         return PROFILE_SERVICE_MODE;
  15.     }

调用doStartService之后 我们可以看到调用了 notifyProfileServiceStateChanged 方法。

  1.   private void doStart(Intent intent) {
  2.    
  3.             if (!mStartError) {
  4.                // 开始调用 notifyProfileServiceStateChanged
  5.                 notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON);
  6.             } 
  7.     }

继续查看notifyProfileServiceStateChanged 方法 ,里面又回到了AdapterServer 中的 onProfileServiceStateChanged方法

  1. protected void notifyProfileServiceStateChanged(int state) {
  2.         //Notify adapter service
  3.         AdapterService adapterService = AdapterService.getAdapterService();
  4.         if (adapterService != null) {
  5.             adapterService.onProfileServiceStateChanged(getClass().getName(), state);
  6.         }
  7.     }

发送MESSAGE_PROFILE_SERVICE_STATE_CHANGED 消息 给消息处理

  1.  public void onProfileServiceStateChanged(String serviceName, int state) {
  2.         Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
  3.         m.obj=serviceName;
  4.         m.arg1 = state;
  5.         mHandler.sendMessage(m);
  6.     }

在消息接收的地方查看到蓝牙的 processProfileServiceStateChanged 方法被调用,在processProfileServiceStateChanged 方法中发送了 BLE_STARTED 消息,而这个消息接受的地方是开起底层ProfileService的地方。

  1.  case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: {
  2.                     debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
  3.                     processProfileServiceStateChanged((String) msg.obj, msg.arg1);
  4.                 }
  5.                     break;
  1. private void processProfileServiceStateChanged(String serviceName, int state) {
  2. if (isBleTurningOn) {
  3. if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
  4. debugLog("GattService is started");
  5. mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED));
  6. return;
  7. }
  8. }
  9. }

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java BLE_STARTED消息处理任务,通过 adapterService.enableNative(isGuest) 开启底层的profileService。

  1.  case BLE_STARTED:
  2.                    //开启底层服务
  3.                     if (!adapterService.enableNative(isGuest)) {
  4.                         errorLog("Error while turning Bluetooth on");
  5.                         notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
  6.                         transitionTo(mOffState);
  7.                     }
  8.                     break;

调用的是 AdapterService.java 中的native方法 ,根据包名和JNI 方法的名称我们可以推算出来调用的CPP的名称是 com_android_bluetooth_btservice_AdapterService.cpp

/*package*/ native boolean enableNative(boolean startRestricted);

在如下路径找到了 packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp 在enableNative中查看到 int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); 调用的是 sBluetoothInterface 中的enable方法

  1. static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
  2.     ALOGV("%s:",__FUNCTION__);
  3.  
  4.     jboolean result = JNI_FALSE;
  5.     if (!sBluetoothInterface) return result;
  6.     int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
  7.     result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;
  8.     return result;
  9. }

具体的实现在 bluetooth.c中。 

/system/bt/btif/src/bluetooth.c
  1. static int enable(bool start_restricted) {
  2.   LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted);
  3.  
  4.   restricted_mode = start_restricted;
  5.  
  6.   if (!interface_ready())
  7.     return BT_STATUS_NOT_READY;
  8.  
  9.   stack_manager_get_interface()->start_up_stack_async();
  10.   return BT_STATUS_SUCCESS;
  11. }

底层回调传递到上层的时候主要使用的是 btif_dm.c 中对消息的处理 BTA_DM_INQ_RES_EVT 消息:

system/bt/btif/src/btif_dm.c

  1. static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
  2.     ...省略代码.....
  3.     case BTA_DM_INQ_RES_EVT:
  4.      ...省略代码.....
  5.  /* Callback to notify upper layer of device */
  6.               HAL_CBACK(bt_hal_cbacks, device_found_cb,
  7.                                 num_properties, properties);
  8.           
  9.         break;

/system/bt/btif/include/btif_common.h

define HAL_CBACK(P_CB, P_CBACK, ...) 方法 , HAL_CBACK就是一宏定义,就是调用结构体中对应的方法

  1. extern bt_callbacks_t *bt_hal_cbacks;
  2.  
  3. #define HAL_CBACK(P_CB, P_CBACK, ...)\
  4.     if (P_CB && P_CB->P_CBACK) {            \
  5.         BTIF_TRACE_API("HAL %s->%s", #P_CB, #P_CBACK); \
  6.         P_CB->P_CBACK(__VA_ARGS__);         \
  7.     }                                       \
  8.     else {                                  \
  9.         ASSERTC(0, "Callback is NULL", 0);  \
  10.     }

bt_hal_cbacks 其实就是 蓝牙AdapterService中调用了initNative方法传入到底层的。看下jni中的initNative方法:

  1.  @Override
  2.     public void onCreate() {
  3.         super.onCreate();
  4.         ..........
  5.         //调用底层方法
  6.        initNative();
  7.  
  8.        ........
  9.  
  10.     }

调用com_android_bluetooth_btservice_AdapterService.cpp init方法 将Callback传递到底层

  1. static bool initNative(JNIEnv* env, jobject obj) {
  2.             .......
  3.             //调用com_android_bluetooth_btservice_AdapterService.cpp init方法 将Callback传递到底层
  4.             // 再调用 bluetooth.c 的 init方法
  5.  
  6.         int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
  7.               
  8.             .......
  9. }

com_android_bluetooth_btservice_AdapterService.cpp  再调用 bluetooth.c 的 init方法

  1. static int init(bt_callbacks_t *callbacks) {
  2.   CallBack传递到底层
  3.   bt_hal_cbacks = callbacks;
  4.   stack_manager_get_interface()->init_stack();
  5.  
  6. }

其实这里有两个地方有  bt_callbacks_t  我们可以对比看一下 

1./hardware/libhardware/include/hardware/bluetooth.h 

2. /packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp  

  1. bluetooth.h 中的 bt_callbacks_t
  2.  
  3. typedef struct {
  4.     /** set to sizeof(bt_callbacks_t) */
  5.     size_t size;
  6.     adapter_state_changed_callback adapter_state_changed_cb;
  7.     adapter_properties_callback adapter_properties_cb;
  8.     remote_device_properties_callback remote_device_properties_cb;
  9.     device_found_callback device_found_cb;
  10.     discovery_state_changed_callback discovery_state_changed_cb;
  11.     pin_request_callback pin_request_cb;
  12.     ssp_request_callback ssp_request_cb;
  13.     bond_state_changed_callback bond_state_changed_cb;
  14.     acl_state_changed_callback acl_state_changed_cb;
  15.     callback_thread_event thread_evt_cb;
  16.     dut_mode_recv_callback dut_mode_recv_cb;
  17.     le_test_mode_callback le_test_mode_cb;
  18.     energy_info_callback energy_info_cb;
  19. } bt_callbacks_t;
  1. // com_android_bluetooth_btservice_AdapterService.cpp 中的 bt_callbacks_t
  2. static bt_callbacks_t sBluetoothCallbacks = {
  3.     sizeof(sBluetoothCallbacks),
  4.     adapter_state_change_callback,
  5.     adapter_properties_callback,
  6.     remote_device_properties_callback,
  7.     device_found_callback,
  8.     discovery_state_changed_callback,
  9.     pin_request_callback,
  10.     ssp_request_callback,
  11.    bond_state_changed_callback,
  12.     acl_state_changed_callback,
  13.     callback_thread_event,
  14.     dut_mode_recv_callback,
  15.     le_test_mode_recv_callback,
  16.     energy_info_recv_callback
  17. };
  1. static bt_callbacks_t sBluetoothCallbacks = {
  2.     sizeof(sBluetoothCallbacks),
  3.     adapter_state_change_callback,
  4.     adapter_properties_callback,
  5.     remote_device_properties_callback,
  6.     device_found_callback,
  7.     discovery_state_changed_callback,
  8.     pin_request_callback,
  9.     ssp_request_callback,
  10.    bond_state_changed_callback,
  11.     acl_state_changed_callback,
  12.     callback_thread_event,
  13.     dut_mode_recv_callback,
  14.     le_test_mode_recv_callback,
  15.     energy_info_recv_callback
  16. };

最后蓝牙驱动打开之后会通过  /system/bt/btif/src/btif_core.c 中的 btif_enable_bluetooth_evt(tBTA_STATUS status) 回调给应用

  1. void btif_enable_bluetooth_evt(tBTA_STATUS status){
  2.   // 省略代码
  3.  HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
  4. }

然后回调给 adapter_properties_callback:返回手机蓝牙设备的地址、名称、UUID

adapter_state_change_callback 回调 通过 C调用 Java的代码 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);  返回给应用中的也就是回调java层代码 JniCallback.java文件中stateChangeCallback方法。这时跳转到AdapterState.java中,执行stateChangeCallback()方法;发送了ENABLED_READY消息。根据以上分析,这时状态机还处于PendingCommandState,在该状态下处理ENABLED_READY消息, 

  1. case ENABLED_READY:
  2. removeMessages(ENABLE_TIMEOUT);
  3. mPendingCommandState.setBleTurningOn(false);
  4. transitionTo(mBleOnState);
  5. notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
  6. break;

做下面两个动作:状态切换到mOnState;更新adapterProperties中的蓝牙状态信息;通知蓝牙状态变为打开。具体看下notifyAdapterStateChange方法。主要是调用了adapterService类的方法。 

  1. private void notifyAdapterStateChange(int newState) {
  2. AdapterService adapterService = mAdapterService;
  3. AdapterProperties adapterProperties = mAdapterProperties;
  4. if ((adapterService == null) || (adapterProperties == null)) {
  5. errorLog("notifyAdapterStateChange after cleanup:" + newState);
  6. return;
  7. }
  8. int oldState = adapterProperties.getState();
  9. adapterProperties.setState(newState);
  10. infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState);
  11. adapterService.updateAdapterState(oldState, newState);
  12. }

adapterService.updateAdapterState(oldState, newState); 
来到adapterService类。 

  1. void updateAdapterState(int prevState, int newState){
  2. if (mCallbacks !=null) {
  3. int n=mCallbacks.beginBroadcast();
  4. debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers.");
  5. for (int i=0; i <n;i++) {
  6. try {
  7. // 完成回调 发送广播给调用者
  8. mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState);
  9. } catch (RemoteException e) {
  10. debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
  11. }
  12. }
  13. mCallbacks.finishBroadcast();
  14. }
  15. }

之前在打开蓝牙操作初期,在BluetoothManagerService中注册了回调方法,因此又跳转到framework中,执行回调方法。蓝牙打开从framework公共接口开始调用enable方法,执行到bluetooth.apk中,在该应用中通过jni注册回调方法和调用hal层打开蓝牙方法,在驱动层完成蓝牙上电等操作后,通过hal-jni回调到应用层中,应用通过aidl回调通知framework蓝牙状态变化,framework发送广播通知大家蓝牙打开。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/250962
推荐阅读
相关标签
  

闽ICP备14008679号