当前位置:   article > 正文

Android -- AdapterService之蓝牙启动过程分析

adapterservice

                  Android -- AdapterService之蓝牙启动过程分析

 

前面介绍BluetoothManagerService启动过程enable BT的部分提到,处理ENABLE msg的最终调用主要是call到AdapterService注册IBluetoothCallback回调监听蓝牙使能状态、以及AdapterService::enable()接口开启蓝牙,下面就接着这部分往下看。

AdapterService是Service的子类,Bind service会触发依次调用它的声明周期函数onCreate() -> onBind():

  1. public class AdapterService extends Service {
  2. ......
  3. static {
  4. classInitNative();//native层的init部分
  5. }
  6. ......
  7. @Override
  8. public void onCreate() {
  9. super.onCreate();
  10. debugLog("onCreate()");
  11. mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());//重要类型,它实现了接受stack反馈的device信息变化的回调,比如UUID
  12. mRemoteDevices.init();
  13. mBinder = new AdapterServiceBinder(this);//AdapterService内部封装的IBluetooth接口实现者
  14. mAdapterProperties = new AdapterProperties(this);//管理当前Adapter的一些属性,比如配对的device,uuid信息等;有些接口供stack回调上报状态使用
  15. mAdapterStateMachine = AdapterState.make(this);//一个简单的StateMachine,处理开关BT中间的状态切换
  16. mJniCallbacks = new JniCallbacks(this, mAdapterProperties);//stack会通过此对象上报一些bt状态和信息
  17. initNative();//native层的init工作
  18. ......
  19. // Phone policy is specific to phone implementations and hence if a device wants to exclude
  20. // it out then it can be disabled by using the flag below.
  21. if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) {
  22. Log.i(TAG, "Phone policy enabled");
  23. mPhonePolicy = new PhonePolicy(this, new ServiceFactory());//启动PhonePolicy,它会根据触发重连之前的设备;在available的设备之间处理连接切换等
  24. mPhonePolicy.start();
  25. } else {
  26. Log.i(TAG, "Phone policy disabled");
  27. }
  28. mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory());//处理Active Device的管理类;比如Android默认可以连接多个sink设备,但只有一个出声,这个就是active的device;
  29. //要通过AudioManager的接口告知Audio当前系统哪个device是active的,这样Audio系统才能根据策略选择正确的设备播放音频
  30. mActiveDeviceManager.start();
  31. setAdapterService(this);//保存当前的AdapterServie实例,因为其他的类里可能要获取它
  32. ......
  33. }
  34. ......
  35. @Override
  36. public IBinder onBind(Intent intent) {
  37. debugLog("onBind()");
  38. return mBinder;
  39. }
  40. ......
  41. /**
  42. * Handlers for incoming service calls
  43. */
  44. private AdapterServiceBinder mBinder;
  45. /**
  46. * The Binder implementation must be declared to be a static class, with
  47. * the AdapterService instance passed in the constructor. Furthermore,
  48. * when the AdapterService shuts down, the reference to the AdapterService
  49. * must be explicitly removed.
  50. *
  51. * Otherwise, a memory leak can occur from repeated starting/stopping the
  52. * service...Please refer to android.os.Binder for further details on
  53. * why an inner instance class should be avoided.
  54. *
  55. */
  56. private static class AdapterServiceBinder extends IBluetooth.Stub {
  57. private AdapterService mService;
  58. AdapterServiceBinder(AdapterService svc) {
  59. mService = svc;
  60. }
  61. public void cleanup() {
  62. mService = null;
  63. }
  64. public AdapterService getService() {
  65. if (mService != null && mService.isAvailable()) {
  66. return mService;
  67. }
  68. return null;
  69. }
  70. ......
  71. @Override
  72. public boolean enable() {
  73. if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) {
  74. Log.w(TAG, "enable() - Not allowed for non-active user and non system user");
  75. return false;
  76. }
  77. AdapterService service = getService();
  78. if (service == null) {
  79. return false;
  80. }
  81. return service.enable();
  82. }
  83. ......
  84. }
  85. }
  86. }

从code看出,BluetoothManagerService先获取到IBinder对象,再通过它调用AdapterService的对于方法完成工作。为了较好的跟flow,我们先看初始化部分;其他的细节可以参考注释:

加载AdapterService类时,需要完成的static代码块调用:

  1. static {
  2. classInitNative();
  3. }
  4. ......
  5. static void classInitNative(JNIEnv* env, jclass clazz) {
  6. jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
  7. android_bluetooth_UidTraffic.constructor =
  8. env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");
  9. jclass jniCallbackClass =
  10. env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
  11. sJniCallbacksField = env->GetFieldID(
  12. clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");//获取AdapterService中的mJniCallbacks实例,通知上层stack的变化信息
  13. method_stateChangeCallback =
  14. env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");//
  15. method_adapterPropertyChangedCallback = env->GetMethodID(
  16. jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V");
  17. method_discoveryStateChangeCallback = env->GetMethodID(
  18. jniCallbackClass, "discoveryStateChangeCallback", "(I)V");
  19. method_devicePropertyChangedCallback = env->GetMethodID(
  20. jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V");
  21. method_deviceFoundCallback =
  22. env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
  23. method_pinRequestCallback =
  24. env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
  25. method_sspRequestCallback =
  26. env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
  27. method_bondStateChangeCallback =
  28. env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
  29. method_aclStateChangeCallback =
  30. env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V");
  31. method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
  32. method_acquireWakeLock =
  33. env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
  34. method_releaseWakeLock =
  35. env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
  36. method_energyInfo = env->GetMethodID(
  37. clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
  38. if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {//加载bt stack的so,获取操作句柄sBluetoothInterface;用以调用stack的接口完成操作
  39. ALOGE("No Bluetooth Library found");
  40. }
  41. }

这部分初始化工作,从code看很清晰;主要做两件事:

  1. 在Jni层获取AdapterService中的callback接口,当stack上报状态时,需要通过这些接口反馈到framework层
  2. 解析bt so,获取它暴露给上层的接口,用来将framework的操作请求真正下发到协议栈中。主要是dlopen方式操作so、拿到操作handle的,source code部分主要在Pie_9.0.0_r3\system\bt\main中

bt_interface_t类型定义的都是上层会涉及到的bt操作,如果connect/disconnect、createBond/removeBond等,最终都会此类型将请求下发到协议栈中:

  1. /** Represents the standard Bluetooth DM interface. */
  2. typedef struct {
  3. /** set to sizeof(bt_interface_t) */
  4. size_t size;
  5. /**
  6. * Opens the interface and provides the callback routines
  7. * to the implemenation of this interface.
  8. */
  9. int (*init)(bt_callbacks_t* callbacks);
  10. /** Enable Bluetooth. */
  11. int (*enable)(bool guest_mode);
  12. /** Disable Bluetooth. */
  13. int (*disable)(void);
  14. /** Closes the interface. */
  15. void (*cleanup)(void);
  16. /** Remove Bond */
  17. int (*remove_bond)(const RawAddress* bd_addr);
  18. /** Cancel Bond */
  19. int (*cancel_bond)(const RawAddress* bd_addr);
  20. /**
  21. * Get the connection status for a given remote device.
  22. * return value of 0 means the device is not connected,
  23. * non-zero return status indicates an active connection.
  24. */
  25. int (*get_connection_state)(const RawAddress* bd_addr);
  26. /** Read Energy info details - return value indicates BT_STATUS_SUCCESS or
  27. * BT_STATUS_NOT_READY Success indicates that the VSC command was sent to
  28. * controller
  29. */
  30. int (*read_energy_info)();
  31. /**
  32. * Get the AvrcpTarget Service interface to interact with the Avrcp Service
  33. */
  34. bluetooth::avrcp::ServiceInterface* (*get_avrcp_service)(void);
  35. } bt_interface_t;

静态初始化块完成后,就是Service::onCreate()的调用,除了前面提到的初始化一些重要的Java对象外,还会做一些Native层的初始化:

  1. static bool initNative(JNIEnv* env, jobject obj) {
  2. ALOGV("%s", __func__);
  3. android_bluetooth_UidTraffic.clazz =
  4. (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
  5. sJniAdapterServiceObj = env->NewGlobalRef(obj);
  6. sJniCallbacksObj =
  7. env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
  8. if (!sBluetoothInterface) {
  9. return JNI_FALSE;
  10. }
  11. int ret = sBluetoothInterface->init(&sBluetoothCallbacks);//将需要的一些callback函数注册到stack中,这样stack就可以通过这些函数上报此类事件
  12. if (ret != BT_STATUS_SUCCESS) {
  13. ALOGE("Error while setting the callbacks: %d\n", ret);
  14. sBluetoothInterface = NULL;
  15. return JNI_FALSE;
  16. }
  17. ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);//将需要的一些callback函数注册到stack中,这样stack就可以通过这些函数上报此类事件
  18. if (ret != BT_STATUS_SUCCESS) {
  19. ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
  20. sBluetoothInterface->cleanup();
  21. sBluetoothInterface = NULL;
  22. return JNI_FALSE;
  23. }
  24. ......
  25. static bt_callbacks_t sBluetoothCallbacks = {
  26. sizeof(sBluetoothCallbacks), adapter_state_change_callback,
  27. adapter_properties_callback, remote_device_properties_callback,
  28. device_found_callback, discovery_state_changed_callback,
  29. pin_request_callback, ssp_request_callback,
  30. bond_state_changed_callback, acl_state_changed_callback,
  31. callback_thread_event, dut_mode_recv_callback,
  32. le_test_mode_recv_callback, energy_info_recv_callback};
  33. ......
  34. static bt_os_callouts_t sBluetoothOsCallouts = {
  35. sizeof(sBluetoothOsCallouts), set_wake_alarm_callout,
  36. acquire_wake_lock_callout, release_wake_lock_callout,
  37. };

将stack需要用到的一些callback函数注册给它,这样在需要的时候,stack就可以通过调用这些函数将信息反馈到上层了。

这条路串起来之后,再回头看AdapterService::enable():

  1. public synchronized boolean enable(boolean quietMode) {
  2. enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
  3. // Enforce the user restriction for disallowing Bluetooth if it was set.
  4. if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
  5. debugLog("enable() called when Bluetooth was disallowed");
  6. return false;
  7. }
  8. debugLog("enable() - Enable called with quiet mode status = " + quietMode);
  9. mQuietmode = quietMode;
  10. mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
  11. return true;
  12. }

可以看到只是简单的向AdapterState发送一个BLE_TURN_ON msg,随机进入状态机去处理;

  1. /**
  2. * This state machine handles Bluetooth Adapter State.
  3. * Stable States:
  4. * {@link OffState}: Initial State
  5. * {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on
  6. * {@link OnState} : Bluetooth is on (All supported profiles)
  7. *
  8. * Transition States:
  9. * {@link TurningBleOnState} : OffState to BleOnState
  10. * {@link TurningBleOffState} : BleOnState to OffState
  11. * {@link TurningOnState} : BleOnState to OnState
  12. * {@link TurningOffState} : OnState to BleOnState
  13. *
  14. * +------ Off <-----+
  15. * | |
  16. * v |
  17. * TurningBleOn TO---> TurningBleOff
  18. * | ^ ^
  19. * | | |
  20. * +-----> ----+ |
  21. * BleOn |
  22. * +------ <---+ O
  23. * v | T
  24. * TurningOn TO----> TurningOff
  25. * | ^
  26. * | |
  27. * +-----> On ------+
  28. *
  29. */

从上图AdapterState的注释及code,我们知道以下几点:

  1. AdapterState中所有State的父类都是BaseAdapterState,所以在enter某个状态机时,会先调用此父类的enter()接口;同时,在exit某个状态机时,也会call此父类的exit()接口
  2. 默认的初始化状态时Off状态,也就是此时BT尚未启动
  3. 因为AdapterState是管理BT启动的逻辑主要部分,所以向外通知当前BT使能进程的消息,应该在这里触发比较合理

因为在某个状态节点,我们都应该向外通知状态,所以这部分被封装到了父类State中:

  1. AdapterState:
  2. private abstract class BaseAdapterState extends State {
  3. abstract int getStateValue();
  4. @Override
  5. public void enter() {
  6. int currState = getStateValue();
  7. infoLog("entered ");
  8. mAdapterService.updateAdapterState(mPrevState, currState);//通过AdapterService向外通知BT使能的状态信息
  9. mPrevState = currState;
  10. }
  11. ......
  12. }
  13. AdapterService:
  14. void updateAdapterState(int prevState, int newState) {//如果某个服务对蓝牙启动状态过程感兴趣,它就应该注册IBluetootCallback对象;跟BluetoothManagerService一样
  15. mAdapterProperties.setState(newState);
  16. if (mCallbacks != null) {
  17. int n = mCallbacks.beginBroadcast();
  18. debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
  19. newState) + " to " + n + " receivers.");
  20. for (int i = 0; i < n; i++) {
  21. try {
  22. mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);//调用onBluetoothStateChange()回调状态变化
  23. } catch (RemoteException e) {
  24. debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
  25. }
  26. }
  27. mCallbacks.finishBroadcast();
  28. }
  29. ......
  30. }
  31. BluetoothManagerService:
  32. private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
  33. @Override
  34. public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
  35. Message msg =
  36. mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);//发送MESSAGE_BLUETOOTH_STATE_CHANGE
  37. mHandler.sendMessage(msg);
  38. }
  39. };

这里我们发送的是BLE_TURN_ON msg,看它的处理:

  1. private class OffState extends BaseAdapterState {
  2. @Override
  3. int getStateValue() {
  4. return BluetoothAdapter.STATE_OFF;
  5. }
  6. @Override
  7. public boolean processMessage(Message msg) {
  8. switch (msg.what) {
  9. case BLE_TURN_ON:
  10. transitionTo(mTurningBleOnState);
  11. break;
  12. default:
  13. infoLog("Unhandled message - " + messageString(msg.what));
  14. return false;
  15. }
  16. return true;
  17. }
  18. }
  19. ......
  20. private class TurningBleOnState extends BaseAdapterState {
  21. @Override
  22. int getStateValue() {
  23. return BluetoothAdapter.STATE_BLE_TURNING_ON;
  24. }
  25. @Override
  26. public void enter() {
  27. super.enter();
  28. sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
  29. mAdapterService.bringUpBle();
  30. }
  31. @Override
  32. public void exit() {
  33. removeMessages(BLE_START_TIMEOUT);
  34. super.exit();
  35. }
  36. @Override
  37. public boolean processMessage(Message msg) {
  38. switch (msg.what) {
  39. case BLE_STARTED:
  40. transitionTo(mBleOnState);
  41. break;
  42. case BLE_START_TIMEOUT:
  43. errorLog(messageString(msg.what));
  44. transitionTo(mTurningBleOffState);
  45. break;
  46. default:
  47. infoLog("Unhandled message - " + messageString(msg.what));
  48. return false;
  49. }
  50. return true;
  51. }
  52. }
  53. ......
  54. }

BLE_TURN_ON的消息处理是transferTo TurningBleOnState,它的enter()会调用mAdapterService.bringUpBle():

  1. void bringUpBle() {
  2. debugLog("bleOnProcessStart()");
  3. if (getResources().getBoolean(
  4. R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
  5. Config.init(getApplicationContext());
  6. }
  7. // Reset |mRemoteDevices| whenever BLE is turned off then on
  8. // This is to replace the fact that |mRemoteDevices| was
  9. // reinitialized in previous code.
  10. //
  11. // TODO(apanicke): The reason is unclear but
  12. // I believe it is to clear the variable every time BLE was
  13. // turned off then on. The same effect can be achieved by
  14. // calling cleanup but this may not be necessary at all
  15. // We should figure out why this is needed later
  16. mRemoteDevices.reset();//RemoteDeivces管理对端设备的一些信息
  17. mAdapterProperties.init(mRemoteDevices);//AdapterProperties管理当前Adapter的一些信息
  18. debugLog("bleOnProcessStart() - Make Bond State Machine");
  19. mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);//创建BondStateMachine对象,它负责管理一个device的配对过程
  20. mJniCallbacks.init(mBondStateMachine, mRemoteDevices);//JniCallbacks主要负责监听来自stack的callback信息,如设备配对状态或设备更新UUID变化时,framework就可以收到回调
  21. try {
  22. mBatteryStats.noteResetBleScan();
  23. } catch (RemoteException e) {
  24. Log.w(TAG, "RemoteException trying to send a reset to BatteryStats");
  25. }
  26. StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, -1, null,
  27. StatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false);
  28. //Start Gatt service
  29. setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);//启动GattService服务,BLE设备需要GATT协议交换信息
  30. }

除了创建一些重要对象外,这里主要就是起到GattService了,Ble设备都需要通过GATT协议交换信息;其他可以参考上面的注释。

Bluetooth framework声明的Profile服务基本都是ProfileService的子类,所以参照Android Service的启动过程,某个Profile启动时,会调用到ProfileService的方法:

  1. /**
  2. * Base class for a background service that runs a Bluetooth profile
  3. */
  4. public abstract class ProfileService extends Service {
  5. @Override
  6. public int onStartCommand(Intent intent, int flags, int startId) {
  7. ......
  8. if (state == BluetoothAdapter.STATE_OFF) {
  9. doStop();//通知AdapterService的此Profile停止成功
  10. } else if (state == BluetoothAdapter.STATE_ON) {
  11. doStart();//通知AdapterService的此Profile启动成功
  12. }
  13. }
  14. return PROFILE_SERVICE_MODE;
  15. }
  16. private void doStart() {
  17. ......
  18. mAdapterService.addProfile(this);//告知AdapterService此Profile启动成功,更新Profile集合
  19. ......
  20. mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);//通知AdapterService此Profile已启动
  21. }
  22. private void doStop() {
  23. ......
  24. if (mAdapterService != null) {
  25. mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_OFF);//通知AdapterService此Profile已停止
  26. }
  27. if (!stop()) {
  28. Log.e(mName, "Unable to stop profile");
  29. }
  30. if (mAdapterService != null) {
  31. mAdapterService.removeProfile(this);//告知AdapterService此Profile停止成功,更新Profile集合
  32. }
  33. ......
  34. stopSelf();
  35. }
  36. }

接着看AdapterService的处理:

  1. /**
  2. * Register a {@link ProfileService} with AdapterService.
  3. *
  4. * @param profile the service being added.
  5. */
  6. public void addProfile(ProfileService profile) {
  7. mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget();
  8. }
  9. /**
  10. * Unregister a ProfileService with AdapterService.
  11. *
  12. * @param profile the service being removed.
  13. */
  14. public void removeProfile(ProfileService profile) {
  15. mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget();
  16. }
  17. /**
  18. * Notify AdapterService that a ProfileService has started or stopped.
  19. *
  20. * @param profile the service being removed.
  21. * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF}
  22. */
  23. public void onProfileServiceStateChanged(ProfileService profile, int state) {
  24. if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
  25. throw new IllegalArgumentException(BluetoothAdapter.nameForState(state));
  26. }
  27. Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
  28. m.obj = profile;
  29. m.arg1 = state;
  30. mHandler.sendMessage(m);
  31. }
  32. private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1;
  33. private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
  34. private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
  35. class AdapterServiceHandler extends Handler {
  36. @Override
  37. public void handleMessage(Message msg) {
  38. debugLog("handleMessage() - Message: " + msg.what);
  39. switch (msg.what) {
  40. case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
  41. debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
  42. processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
  43. break;
  44. case MESSAGE_PROFILE_SERVICE_REGISTERED:
  45. debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED");
  46. registerProfileService((ProfileService) msg.obj);
  47. break;
  48. case MESSAGE_PROFILE_SERVICE_UNREGISTERED:
  49. debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
  50. unregisterProfileService((ProfileService) msg.obj);
  51. break;
  52. }
  53. }
  54. private void registerProfileService(ProfileService profile) {
  55. if (mRegisteredProfiles.contains(profile)) {
  56. Log.e(TAG, profile.getName() + " already registered.");
  57. return;
  58. }
  59. mRegisteredProfiles.add(profile);
  60. }
  61. private void unregisterProfileService(ProfileService profile) {
  62. if (!mRegisteredProfiles.contains(profile)) {
  63. Log.e(TAG, profile.getName() + " not registered (UNREGISTERED).");
  64. return;
  65. }
  66. mRegisteredProfiles.remove(profile);
  67. }
  68. private void processProfileServiceStateChanged(ProfileService profile, int state) {
  69. switch (state) {
  70. case BluetoothAdapter.STATE_ON://此时是启动GattService,所以是STATE_ON
  71. if (!mRegisteredProfiles.contains(profile)) {
  72. Log.e(TAG, profile.getName() + " not registered (STATE_ON).");
  73. return;
  74. }
  75. if (mRunningProfiles.contains(profile)) {//防止重复启动某个Profile
  76. Log.e(TAG, profile.getName() + " already running.");
  77. return;
  78. }
  79. mRunningProfiles.add(profile);
  80. if (GattService.class.getSimpleName().equals(profile.getName())) {
  81. enableNativeWithGuestFlag();//如果是启动Gatt profile,则向stack下发enable bt的指令
  82. } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
  83. && mRegisteredProfiles.size() == mRunningProfiles.size()) {//这里是启动Gatt以外的,在config.xml中声明支持的其他Profile;相当于启动BREDR mode
  84. mAdapterProperties.onBluetoothReady();
  85. updateUuids();
  86. setBluetoothClassFromConfig();
  87. mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
  88. }
  89. break;
  90. case BluetoothAdapter.STATE_OFF:
  91. if (!mRegisteredProfiles.contains(profile)) {
  92. Log.e(TAG, profile.getName() + " not registered (STATE_OFF).");
  93. return;
  94. }
  95. if (!mRunningProfiles.contains(profile)) {
  96. Log.e(TAG, profile.getName() + " not running.");
  97. return;
  98. }
  99. mRunningProfiles.remove(profile);
  100. // If only GATT is left, send BREDR_STOPPED.
  101. if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName()
  102. .equals(mRunningProfiles.get(0).getName())))) {
  103. mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED);
  104. } else if (mRunningProfiles.size() == 0) {
  105. disableNative();
  106. mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
  107. }
  108. break;
  109. default:
  110. Log.e(TAG, "Unhandled profile state: " + state);
  111. }
  112. }
  113. }

处理enable 蓝牙:

  1. private void enableNativeWithGuestFlag() {
  2. boolean isGuest = UserManager.get(this).isGuestUser();
  3. if (!enableNative(isGuest)) {
  4. Log.e(TAG, "enableNative() returned false");
  5. }
  6. }
  7. static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
  8. ALOGV("%s", __func__);
  9. if (!sBluetoothInterface) return JNI_FALSE;
  10. int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
  11. return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
  12. : JNI_FALSE;
  13. }

前面有介绍到stack的state回调会通过JNICallbacks对象回调上来,enable状态也是如此:

  1. final class JniCallbacks {
  2. void stateChangeCallback(int status) {
  3. mAdapterService.stateChangeCallback(status);
  4. }
  5. }
  6. AdapterService:
  7. void stateChangeCallback(int status) {
  8. if (status == AbstractionLayer.BT_STATE_OFF) {
  9. debugLog("stateChangeCallback: disableNative() completed");
  10. } else if (status == AbstractionLayer.BT_STATE_ON) {//BT State on
  11. mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
  12. } else {
  13. Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
  14. }
  15. }

BT启动之后,向AdapterState通知状态,TurningBleOnState收到消息后,就会进入BleOnState;并对外通知状态变化,如之前介绍,是通过AdapterService::updateAdapterState()函数处理:

  1. void updateAdapterState(int prevState, int newState) {//如果某个服务对蓝牙启动状态过程感兴趣,它就应该注册IBluetootCallback对象;跟BluetoothManagerService一样
  2. mAdapterProperties.setState(newState);
  3. if (mCallbacks != null) {
  4. int n = mCallbacks.beginBroadcast();
  5. debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
  6. newState) + " to " + n + " receivers.");
  7. for (int i = 0; i < n; i++) {
  8. try {
  9. mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);//调用onBluetoothStateChange()回调状态变化
  10. } catch (RemoteException e) {
  11. debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
  12. }
  13. }
  14. mCallbacks.finishBroadcast();
  15. }
  16. // Turn the Adapter all the way off if we are disabling and the snoop log setting changed.
  17. if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
  18. mSnoopLogSettingAtEnable =
  19. SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false);
  20. } else if (newState == BluetoothAdapter.STATE_BLE_ON
  21. && prevState != BluetoothAdapter.STATE_OFF) {
  22. boolean snoopLogSetting =
  23. SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false);
  24. if (mSnoopLogSettingAtEnable != snoopLogSetting) {
  25. mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
  26. }
  27. }
  28. }

在介绍BluetoothManagerService时,我们就提到BMS会向AdapterService注册一个callback来监听BT的状态:

  1. private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
  2. @Override
  3. public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
  4. Message msg =
  5. mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);//发送MESSAGE_BLUETOOTH_STATE_CHANGE
  6. mHandler.sendMessage(msg);
  7. }
  8. };

处理Msg:

  1. case MESSAGE_BLUETOOTH_STATE_CHANGE: {
  2. int prevState = msg.arg1;
  3. int newState = msg.arg2;
  4. if (DBG) {
  5. Slog.d(TAG,
  6. "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
  7. prevState) + " > " + BluetoothAdapter.nameForState(
  8. newState));
  9. }
  10. mState = newState;
  11. bluetoothStateChangeHandler(prevState, newState);//处理state变化
  12. ......
  13. }

看bluetoothStateChangeHandler()的主要处理:

  1. // Notify all proxy objects first of adapter state change
  2. if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
  3. boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
  4. && newState == BluetoothAdapter.STATE_BLE_ON);
  5. if (newState == BluetoothAdapter.STATE_OFF) {
  6. // If Bluetooth is off, send service down event to proxy objects, and unbind
  7. if (DBG) {
  8. Slog.d(TAG, "Bluetooth is complete send Service Down");
  9. }
  10. sendBluetoothServiceDownCallback();
  11. unbindAndFinish();
  12. sendBleStateChanged(prevState, newState);
  13. // Don't broadcast as it has already been broadcast before
  14. isStandardBroadcast = false;
  15. } else if (!intermediate_off) {//现在state是BLE_ON
  16. // connect to GattService
  17. if (DBG) {
  18. Slog.d(TAG, "Bluetooth is in LE only mode");
  19. }
  20. if (mBluetoothGatt != null || !mContext.getPackageManager()
  21. .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {//此时GattService只是启动了,BMS还未拿到它的Binder操作句柄
  22. continueFromBleOnState();
  23. } else {
  24. if (DBG) {
  25. Slog.d(TAG, "Binding Bluetooth GATT service");
  26. }
  27. Intent i = new Intent(IBluetoothGatt.class.getName());
  28. doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
  29. UserHandle.CURRENT);//这里去Bind GattService,然后在BluetoothServiceConnection中触发MESSAGE_BLUETOOTH_SERVICE_CONNECTED msg,并区分是SERVICE_IBLUETOOTHGATT
  30. }
  31. sendBleStateChanged(prevState, newState);
  32. //Don't broadcase this as std intent
  33. isStandardBroadcast = false;
  34. } else if (intermediate_off) {
  35. if (DBG) {
  36. Slog.d(TAG, "Intermediate off, back to LE only mode");
  37. }
  38. // For LE only mode, broadcast as is
  39. sendBleStateChanged(prevState, newState);
  40. sendBluetoothStateCallback(false); // BT is OFF for general users
  41. // Broadcast as STATE_OFF
  42. newState = BluetoothAdapter.STATE_OFF;
  43. sendBrEdrDownCallback();
  44. }
  45. }

BluetoothManagerService中Bind Profile的内容跟之前介绍的一样,我们直接看处理:

  1. case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
  2. if (DBG) {
  3. Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
  4. }
  5. IBinder service = (IBinder) msg.obj; //保存Service的onBinder()句柄
  6. try {
  7. mBluetoothLock.writeLock().lock();
  8. if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
  9. mBluetoothGatt =
  10. IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));//获取GattService的句柄
  11. continueFromBleOnState();//启动BREDR的profile
  12. break;
  13. } // else must be SERVICE_IBLUETOOTH
  14. }

获取Gatt profile的Binder句柄,并调用continueFromBleOnState()去启动其他的profile:

  1. /**
  2. * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
  3. */
  4. private void continueFromBleOnState() {
  5. if (DBG) {
  6. Slog.d(TAG, "continueFromBleOnState()");
  7. }
  8. try {
  9. mBluetoothLock.readLock().lock();
  10. if (mBluetooth == null) {
  11. Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
  12. return;
  13. }
  14. if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
  15. // This triggers transition to STATE_ON
  16. mBluetooth.onLeServiceUp();//调用onLeServiceUp()
  17. persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
  18. }
  19. } catch (RemoteException e) {
  20. Slog.e(TAG, "Unable to call onServiceUp", e);
  21. } finally {
  22. mBluetoothLock.readLock().unlock();
  23. }
  24. }
  25. AdapterService:
  26. void onLeServiceUp() {
  27. mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);//发送USER_TURN_ON
  28. }
  29. //现在处于BleOnState,处理此消息进入TurningOnState
  30. AdapterState:
  31. private class TurningOnState extends BaseAdapterState {
  32. @Override
  33. int getStateValue() {
  34. return BluetoothAdapter.STATE_TURNING_ON;
  35. }
  36. @Override
  37. public void enter() {
  38. super.enter();
  39. sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
  40. mAdapterService.startProfileServices();
  41. }
  42. ......
  43. }
  44. //启动配置文件中定义的Profile:
  45. AdapterService:
  46. void startProfileServices() {
  47. debugLog("startCoreServices()");
  48. Class[] supportedProfileServices = Config.getSupportedProfiles();
  49. if (supportedProfileServices.length == 1 && GattService.class.getSimpleName()
  50. .equals(supportedProfileServices[0].getSimpleName())) {
  51. mAdapterProperties.onBluetoothReady();
  52. updateUuids();
  53. setBluetoothClassFromConfig();
  54. mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
  55. } else {
  56. setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
  57. }
  58. }

最终的处理是启动全部在Bluetooth.apk的config.xml中定义的Profile,Config.getSupportedProfiles()调用拿到的Profile集合就是声明了true的Service:

  1. <bool name="profile_supported_a2dp">true</bool>
  2. <bool name="profile_supported_a2dp_sink">false</bool>
  3. <bool name="profile_supported_hdp">true</bool>
  4. <bool name="profile_supported_hs_hfp">true</bool>
  5. <bool name="profile_supported_hfpclient">false</bool>
  6. <bool name="profile_supported_hid_host">true</bool>
  7. <bool name="profile_supported_opp">true</bool>
  8. <bool name="profile_supported_pan">true</bool>
  9. <bool name="profile_supported_pbap">true</bool>
  10. <bool name="profile_supported_gatt">true</bool>
  11. <bool name="pbap_include_photos_in_vcard">true</bool>
  12. <bool name="pbap_use_profile_for_owner_vcard">true</bool>
  13. <bool name="profile_supported_map">true</bool>
  14. <bool name="profile_supported_avrcp_target">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="profile_supported_mapmce">false</bool>
  19. <bool name="profile_supported_hid_device">true</bool>
  20. <bool name="profile_supported_hearing_aid">false</bool>

setAllProfileServiceStates()就是以STATE_ON的状态启动所有这些supported的Profile,它们也都是ProfileService的子类:

  1. private void setAllProfileServiceStates(Class[] services, int state) {
  2. for (Class service : services) {
  3. if (GattService.class.getSimpleName().equals(service.getSimpleName())) {
  4. continue;
  5. }
  6. setProfileServiceState(service, state);
  7. }
  8. }

所以也跟GattService启动的flow类似,AdapterService会处理这些Profile的状态变化,这里是STATE_ON:

  1. private void processProfileServiceStateChanged(ProfileService profile, int state) {
  2. switch (state) {
  3. case BluetoothAdapter.STATE_ON://此时是启动GattService,所以是STATE_ON
  4. if (!mRegisteredProfiles.contains(profile)) {
  5. Log.e(TAG, profile.getName() + " not registered (STATE_ON).");
  6. return;
  7. }
  8. if (mRunningProfiles.contains(profile)) {//防止重复启动某个Profile
  9. Log.e(TAG, profile.getName() + " already running.");
  10. return;
  11. }
  12. mRunningProfiles.add(profile);
  13. if (GattService.class.getSimpleName().equals(profile.getName())) {
  14. enableNativeWithGuestFlag();//如果是启动Gatt profile,则向stack下发enable bt的指令
  15. } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
  16. && mRegisteredProfiles.size() == mRunningProfiles.size()) {//这里是启动Gatt以外的,在config.xml中声明支持的其他Profile;相当于启动BREDR mode
  17. mAdapterProperties.onBluetoothReady();//Profile全部启动完成,初始化变化,并设置当前Bt工作的mode
  18. updateUuids();//更新UUID
  19. setBluetoothClassFromConfig();
  20. mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);//通知AdapterState,随即进入OnState;BT启动成功
  21. }
  22. break;
  23. ......
  24. }

mRegisteredProfiles、mRunningProfiles最终会跟config声明的Profile一致,然后继续做一些设置工作,其中我们可能比较关心的就是设置当前蓝牙的工作模式了:

  1. void onBluetoothReady() {
  2. debugLog("onBluetoothReady, state=" + BluetoothAdapter.nameForState(getState())
  3. + ", ScanMode=" + mScanMode);
  4. synchronized (mObject) {
  5. // Reset adapter and profile connection states
  6. setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
  7. mProfileConnectionState.clear();
  8. mProfilesConnected = 0;
  9. mProfilesConnecting = 0;
  10. mProfilesDisconnecting = 0;
  11. // adapterPropertyChangedCallback has already been received. Set the scan mode.
  12. setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE);//当前设备可以扫描和连接其他设备,其他设备无法扫描到当前设备
  13. // This keeps NV up-to date on first-boot after flash.
  14. setDiscoverableTimeout(mDiscoverableTimeout);//设置扫描的超时时长
  15. }
  16. }

我们可以在这里设置希望的蓝牙工作模式和扫描超时时长,这样蓝牙的启动工作就基本结束了。

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

闽ICP备14008679号