转载请标明出处:Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程
现在开始我们分析 Android4.2 Bluetooth 打开的整个过程,由于是新手,难免有很多错误,记录只是为了以后方便查找,如发错误敬请指出。
我们整个分析过程有可能有点繁琐,但请仔细阅读,读完之后必然发现还是会有一点点收获的,虽然写的不好。搜先我们上一份enable 打开蓝牙整个过程的打印:然后我们跟踪打印来窥探 Android4.2Bluetooth 工作的流程。
D/BluetoothManagerService( 1646): enable(): mBluetooth =null mBinding = false D/BluetoothManagerService( 1646): Message: 1 D/BluetoothManagerService( 1646): MESSAGE_ENABLE: mBluetooth = null D/BluetoothManagerService( 1646): handleEnable quietMode = false D/BluetoothManagerService( 1646): starting bind timeout and bind D/BluetoothAdapterService( 2281): REFCOUNT: CREATED. INSTANCE_COUNT2 D/BluetoothAdapterState( 2281): make I/bluedroid( 2281): init I/bte_conf( 2281): Attempt to load stack conf from /etc/bluetooth/bt_stack.conf I/bluedroid( 2281): get_profile_interface socket I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=1 [BTIF] starting I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:2 len:6 D/BluetoothManagerService( 1646): BluetoothServiceConnection: connected to AdapterService D/BluetoothManagerService( 1646): Message: 40 D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_SERVICE_CONNECTED D/BluetoothManagerService( 1646): Calling onBluetoothServiceUp callbacks D/BluetoothManagerService( 1646): Broadcasting onBluetoothServiceUp() to 5 receivers. D/BluetoothAdapter( 1849): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@422dc8a8 D/BluetoothAdapter( 2281): onBluetoothServiceUp: com.android.bluetooth.btservice.AdapterService$AdapterServiceBinder@423091e0 D/BluetoothAdapter( 1646): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@425040e0 D/BluetoothAdapter( 1982): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@42c8f358 D/BluetoothAdapter( 1756): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@4409f528 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:1 len:16 D/BluetoothManagerService( 1646): Bluetooth Adapter name changed to Bluedroid TV 1.0 D/BluetoothManagerService( 1646): Stored Bluetooth name: Bluedroid TV 1.0 D/BluetoothAdapterService( 2281): Broadcasting updateAdapterState() to 1 receivers. D/BluetoothManagerService( 1646): Message: 60 D/BluetoothBondStateMachine( 2281): make D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = 10, newState=11 D/BluetoothManagerService( 1646): Bluetooth State Change Intent: 10 -> 11 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 I/BluetoothBondStateMachine( 2281): StableState(): Entering Off State D/HeadsetService( 2281): onCreate D/HeadsetService( 2281): onStartCo[ 74.984550] #######bt_usb0: Open called count 2######### mmand() D/HeadsetService( 2281)[ 74.993399] bt_usb0: open complete : Received start request. Starting profile... D/HeadsetService( 2281): start() D/HeadsetStateMachine( 2281): make I/bluedroid( 2281): get_profile_interface handsfree E/bt-btif ( 2281): btif_enable_service: current services:0x100040 D/A2dpService( 2281): onCreate D/A2dpService( 2281): onStartCommand() D/A2dpService( 2281): Received start request. Starting profile... D/A2dpService( 2281): start() D/A2dpStateMachine( 2281): make I/bluedroid( 2281): get_profile_interface a2dp I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=2 [A2DP-MEDIA] starting E/bt-btif ( 2281): btif_enable_service: current services:0x140040 D/HidService( 2281): onCreate D/A2dpStateMachine( 2281): Enter Disconnected: -2 D/HidService( 2281): onStartCommand() D/HidService( 2281): Received start request. Starting profile... D/HidService( 2281): start() I/bluedroid( 2281): get_profile_interface hidhost E/bt-btif ( 2281): btif_enable_service: current services:0x140040 D/HealthService( 2281): onCreate D/HealthService( 2281): onStartCommand() D/HealthService( 2281): Received start request. Starting profile... D/HealthService( 2281): start() I/bluedroid( 2281): get_profile_interface health D/PanService( 2281): onCreate D/PanService( 2281): onStartCommand() D/PanService( 2281): Received start request. Starting profile... D/PanService( 2281): start() D/BluetoothPanServiceJni( 2281): initializeNative(L110): pan I/bluedroid( 2281): get_profile_interface pan D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.pan.PanService I/bluedroid( 2281): enable I/bt_hci_bdroid( 2281): init I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=0 [BTU] starting V/BluetoothEventManager( 1982): Received android.bluetooth.adapter.action.STATE_CHANGED I/bt_hci_bdroid( 2281): bt_hc_worker_thread started D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date ==222 W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == I/bt_vendor( 2281): *********usb vendor open: opening /dev/bt_usb0 I/ ( 2281): BTE_InitTraceLevels -- TRC_HCI I/ ( 2281): BTE_InitTraceLevels -- TRC_L2CAP I/ ( 2281): BTE_InitTraceLevels -- TRC_RFCOMM I/ ( 2281): BTE_InitTraceLevels -- TRC_AVDT I/ ( 2281): BTE_InitTraceLevels -- TRC_AVRC I/ ( 2281): BTE_InitTraceLevels -- TRC_A2D I/ ( 2281): BTE_InitTraceLevels -- TRC_BNEP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTM I/ ( 2281): BTE_InitTraceLevels -- TRC_PAN I/ ( 2281): BTE_InitTraceLevels -- TRC_SDP I/ ( 2281): BTE_InitTraceLevels -- TRC_GATT I/ ( 2281): BTE_InitTraceLevels -- TRC_SMP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTAPP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTIF E/bt-btif ( 2281): ################################## E/bt-btif ( 2281): bta_dm_co_ble_load_local_keys: TBD Load local keys if any are persisted E/bt-btif ( 2281): ################################## E/bt-btm ( 2281): BTM_SecRegister:p_cb_info->p_le_callback == 0x5f72e6ed E/bt-btm ( 2281): BTM_SecRegister: btm_cb.api.p_le_callback = 0x5f72e6ed E/bt-btif ( 2281): Calling BTA_HhEnable E/bt-btif ( 2281): lehid_enable E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## E/bt-btif ( 2281): btif_storage_get_adapter_property service_mask:0x140040 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:2 len:6 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:1 len:16 W/bt-smp ( 2281): Key(LSB ~ MSB) = 2f 15 17 1d 64 e9 09 88 e1 5a cc d6 89 06 1c 8f W/bt-smp ( 2281): Plain text(LSB ~ MSB) = 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 W/bt-smp ( 2281): Encrypted text(LSB ~ MSB) = da f7 3d 81 37 58 7e 20 c2 e6 c6 45 cf 10 45 c7 W/bt-smp ( 2281): Key(LSB ~ MSB) = 2f 15 17 1d 64 e9 09 88 e1 5a cc d6 89 06 1c 8f W/bt-smp ( 2281): Plain text(LSB ~ MSB) = 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 W/bt-smp ( 2281): Encrypted text(LSB ~ MSB) = d3 67 6a 77 1a 6d 44 e8 4d b2 77 67 d2 58 9d 34 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:7 len:4 D/BluetoothManagerService( 1646): Bluetooth Adapter name changed to Bluedroid TV 1.0 D/BluetoothManagerService( 1646): Stored Bluetooth name: Bluedroid TV 1.0 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:9 len:4 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:8 len:6 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:3 len:48 E/BluetoothRemoteDevices( 2281): devicePropertyChangedCallback: bdDevice: F8:A4:5F:A0:64:CD, value is empty for type: 11 E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf D/ ( 2281): bta_pan_co_init I/bt-pan ( 2281): PAN_SetRole() called with role 0x5 I/bt-pan ( 2281): PAN role set to: 5 I/bte_conf( 2281): [1] primary_record=1 vendor_id=0x000F vendor_id_source=0x0001 product_id=0x1200 version=0x1436 I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf D/BluetoothAdapterProperties( 2281): ScanMode = 20 D/BluetoothAdapterProperties( 2281): State = 11 D/BluetoothAdapterService( 2281): Broadcasting updateAdapterState() to 1 receivers. D/BluetoothManagerService( 1646): Message: 60 D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = 11, newState=12 D/BluetoothManagerService( 1646): Broadcasting onBluetoothStateChange(true) to 8 receivers. D/BluetoothHeadset( 1849): onBluetoothStateChange: up=true D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## W/bt-btif ( 2281): btif_dm_cback : unhandled event (20) D/BluetoothPanServiceJni( 2281): control_state_callback(L61): state:0, local_role:0, ifname:bt-pan I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:7 len:4 D/HeadsetService( 2281): onBind D/BluetoothA2dp( 1982): onBluetoothStateChange: up=true D/BluetoothHeadset( 1849): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothA2dp$1.onBluetoothStateChange:131 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:9 len:4 E/bt_usb ( 2281): vendor lib postload completed D/A2dpService( 2281): onBind D/BluetoothInputDevice( 1982): onBluetoothStateChange: up=true W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothInputDevice$1.onBluetoothStateChange:209 D/HidService( 2281): onBind D/BluetoothHeadset( 1849): onBluetoothStateChange: up=true D/BluetoothPan( 1982): onBluetoothStateChange(on) call bindService D/BluetoothHeadset( 1849): Proxy object connected W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothPan$1.onBluetoothStateChange:173 D/PanService( 2281): onBind D/BluetoothPan( 1982): BluetoothPan(), bindService called D/BluetoothHeadset( 1646): onBluetoothStateChange: up=true D/BluetoothHeadset( 1646): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/ApplicationContext( 1646): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.bluetooth.BluetoothHeadset$1.onBluetoothStateChange:244 com.android.server.BluetoothManagerService.sendBluetoothStateCallback:486 D/BluetoothHeadset( 1982): onBluetoothStateChange: up=true D/BluetoothA2dp( 1646): onBluetoothStateChange: up=true W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothHeadset$1.onBluetoothStateChange:244 D/BluetoothA2dp( 1646): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/ApplicationContext( 1646): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.bluetooth.BluetoothA2dp$1.onBluetoothStateChange:131 com.android.server.BluetoothManagerService.sendBluetoothStateCallback:486 D/BluetoothManagerService( 1646): Bluetooth State Change Intent: 11 -> 12 W/bt-btif ( 2281): btif_dm_cback : unhandled event (21) D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothManagerService( 1646): checkIfCallerIsForegroundUser: valid=true callingUser=0 foregroundUser=0 W/BluetoothAdapter( 2281): getBluetoothService() called with no BluetoothManagerCallback E/BluetoothServiceJni( 2281): SOCK FLAG = 1 *********************** V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.NAME_CHANGED V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.CLASS_CHANGED V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.UUID D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothA2dp( 1982): Proxy object connected D/BluetoothInputDevice( 1982): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothPan( 1982): BluetoothPAN Proxy object connected D/BluetoothHeadset( 1982): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 V/BluetoothEventManager( 1982): Received android.bluetooth.adapter.action.STATE_CHANGED D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapter( 1982): enable(): BT is already enabled..! W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1352 android.content.ContextWrapper.startService:450 android.content.ContextWrapper.startService:450 D/DockEventReceiver( 1982): finishStartingService: stopping service E/BtOppService( 2281): insertShare found null URI at cursor! D/BluetoothManagerService( 1646): checkIfCallerIsForegroundUser: valid=true callingUser=0 foregroundUser=0 W/BluetoothAdapter( 2281): getBluetoothService() called with no BluetoothManagerCallback E/BluetoothServiceJni( 2281): SOCK FLAG = 0 *********************** I/BtOppRfcommListener( 2281): Accept thread started. E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! D/BtOppService( 2281): updateShare() called for ID 1 with null URI D/BtOppService( 2281): updateShare() called for ID 2 with null URI D/BtOppService( 2281): updateShare() called for ID 3 with null URI D/BtOppService( 2281): updateShare() called for ID 4 with null URI D/BtOppService( 2281): updateShare() called for ID 5 with null URI D/BtOppService( 2281): updateShare() called for ID 6 with null URI D/BtOppService( 2281): updateShare() called for ID 7 with null URI D/BtOppService( 2281): updateShare() called for ID 8 with null URI D/BtOppService( 2281): updateShare() called for ID 9 with null URI D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......I. 0,0-0,0 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 G.E..... ......ID 0,0-0,0 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......I. 0,0-0,0 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 G.E..... ......ID 0,0-0,0 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......ID 0,0-669,96 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 V.E..... ......ID 0,0-669,96 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......ID 0,0-669,96 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 V.E..... ......ID 0,0-669,96 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/TvCommonClient( 1646): getCurrentInputSource, return int 34 D/TvCommonManager( 1764): getCurrentInputSource, return EnumInputSource E_INPUT_SOURCE_STORAGE D/dalvikvm( 2281): GC_CONCURRENT freed 340K, 19% free 2506K/3064K, paused 8ms+6ms, total 40ms W/BluetoothAdapterService( 2281): *************service already starting to cleanup... Ignoring cleanup request......... D/BluetoothAdapterService( 2281): REFCOUNT: FINALIZED. INSTANCE_COUNT= 1 D/BluetoothSocket( 2281): close() in, this: android.bluetooth.BluetoothSocket@42312c28, channel: 19, state: CLOSED D/BluetoothSocket( 2281): close() in, this: android.bluetooth.BluetoothSocket@422e5970, channel: 12, state: CLOSED
1.从UI操作开始,我们在设置界面中打开蓝牙设备,这部分代码在 Settings/bluetooth/BluetoothEnabler 类中。
/** * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox * preference. It turns on/off Bluetooth and ensures the summary of the * preference reflects the current state. */ public final class BluetoothEnabler implements CompoundButton.OnCheckedChangeListener { private final Context mContext; private final LocalBluetoothAdapter mLocalAdapter; .................................. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // Show toast message if Bluetooth is not allowed in airplane mode // if (isChecked // &&!WirelessSettings.isRadioAllowed(mContext, // Settings.System.RADIO_BLUETOOTH) // ) { // Toast.makeText(mContext, R.string.wifi_in_airplane_mode, // Toast.LENGTH_SHORT).show(); // // Reset switch to off // buttonView.setChecked(false); // } if (mLocalAdapter != null) { mLocalAdapter.setBluetoothEnabled(isChecked); } mSwitch.setEnabled(false); } ................................... }
从注释中我们可以知道,这是一个蓝牙开/关 的一个帮组类,类里面实现了接口
CompoundButton.OnCheckedChangeListener 中的public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)方法。代码中注释掉的不管,那些是有关飞行模式下蓝牙状态的一个操作。我们看mLocalAdapter.setBluetoothEnabled(isChecked);是蓝牙打开或者关闭的一个接口。我们查看mLocalAdapter类在哪里???private final LocalBluetoothAdapter mLocalAdapter; 到了 Settings/bluetooth/LocalBluetoothAdapter 类中。
/** * LocalBluetoothAdapter provides an interface between the Settings app and the * functionality of the local {@link BluetoothAdapter}, specifically those * related to state transitions of the adapter itself. * <p> * Connection and bonding state changes affecting specific devices are handled * by {@link CachedBluetoothDeviceManager}, {@link BluetoothEventManager}, and * {@link LocalBluetoothProfileManager}. */ public final class LocalBluetoothAdapter { private static final String TAG = "LocalBluetoothAdapter"; /** This class does not allow direct access to the BluetoothAdapter. */ private final BluetoothAdapter mAdapter; .................... public void setBluetoothEnabled(boolean enabled) { boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); if (success) { setBluetoothStateInt(enabled ? BluetoothAdapter.STATE_TURNING_ON : BluetoothAdapter.STATE_TURNING_OFF); } else { if (Utils.V) { Log.v(TAG, "setBluetoothEnabled call, manager didn't return " + "success for enabled: " + enabled); } syncBluetoothState(); } } }
我们看注释知道这个类在Settings app 和 Framworks 之间提供了一个接口去改变 蓝牙开关状态。关键代码 看第 19行
boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); 因为这里的enable = true;也就是打开蓝牙,所以我们走mAdapter.enable(),接着看下去,如果enable
成功,那么 走 if 语句 (一般情况下能成功)我们看看 setBluetoothStateInt()的实现 在同一个文件目录下
synchronized void setBluetoothStateInt(int state) { mState = state; if (state == BluetoothAdapter.STATE_ON) { // if mProfileManager hasn't been constructed yet, it will // get the adapter UUIDs in its constructor when it is. if (mProfileManager != null) { mProfileManager.setBluetoothStateOn(); } } }这里关注 mProfileManager.setBluetoothStateOn(),设置蓝牙的状态开关,继续跟踪代码
frameworks/base/core/java/android/bluetooth/LocalBluetoothProfileManager
下面,
final class LocalBluetoothProfileManager { ........... // Called from LocalBluetoothAdapter when state changes to ON void setBluetoothStateOn() { ParcelUuid[] uuids = mLocalAdapter.getUuids(); if (uuids != null) { updateLocalProfiles(uuids); } mEventManager.readPairedDevices(); } .............. }由上面的方法可以看出,当打开蓝牙成功后,更新本地蓝牙配置文件 和读取 本地 蓝牙设备列表显示。
我们回到这里,看boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); 到底是怎么打开蓝牙开关的,接着看mAdapter对象的类 BluetoothAdapter会在哪里呢??????????
我们看继续查找 在 frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java下,这会跳到了Frameworks中去了。(由原来的Settings APP 跳到 Framewoeks API中)
public final class BluetoothAdapter { ............ BluetoothAdapter(IBluetoothManager managerService) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) {Log.e(TAG, "", e);} mManagerService = managerService; mServiceRecordHandler = null; } .............. public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (b != null) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); sAdapter = new BluetoothAdapter(managerService); } else { Log.e(TAG, "Bluetooth binder is null"); } } return sAdapter; } .................. public boolean enable() { if (isEnabled() == true){ if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); return true; } try { return mManagerService.enable(); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; } .................. }
这里我们看第 33 行 中的 enable() 方法中的第 39行 关键代码 return mManagerService.enable(); mManagerService 对象是由 第 22 行的 IBluetoothManager 接口代码实现的,一般这种远程服务对应的类名就是 BluetoothManagerService 类,在路径 frameworks/base/core/java/android/bluetooth/BluetoothManagerService 下面 ,我们进一步深入敌后看看 里面什么情况,
class BluetoothManagerService extends IBluetoothManager.Stub { ................... private void sendEnableMsg(boolean quietMode) { mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0)); } ............. private class BluetoothHandler extends Handler { public BluetoothHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (DBG) Log.d (TAG, "Message: " + msg.what); switch (msg.what) { .................... case MESSAGE_ENABLE: if (DBG) { Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; handleEnable(msg.arg1 == 1); break; ............. } private void handleEnable(boolean quietMode) { mQuietEnable = quietMode; Log.d(TAG, "handleEnable quietMode = " + quietMode); synchronized(mConnection) { if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Log.d(TAG, "starting bind timeout and bind"); Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); mConnection.setGetNameAddressOnly(false); Intent i = new Intent(IBluetooth.class.getName()); if (!mContext.bindService(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName()); } else { mBinding = true; } } else if (mBluetooth != null) { Log.d(TAG, "mBluetooth != null"); if (mConnection.isGetNameAddressOnly()) { // if GetNameAddressOnly is set, we can clear this flag, // so the service won't be unbind // after name and address are saved mConnection.setGetNameAddressOnly(false); //Register callback object try { mBluetooth.registerCallback(mBluetoothCallback); } catch (RemoteException re) { Log.e(TAG, "Unable to register BluetoothCallback",re); } //Inform BluetoothAdapter instances that service is up sendBluetoothServiceUpCallback(); } Log.d(TAG, "Try enable bluetooth"); //Enable bluetooth try { if (!mQuietEnable) { if(!mBluetooth.enable()) { Log.e(TAG,"IBluetooth.enable() returned false"); } } else { if(!mBluetooth.enableNoAutoConnect()) { Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); } } } catch (RemoteException e) { Log.e(TAG,"Unable to call enable()",e); } } } } ...................... public boolean enable() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) { Log.w(TAG,"enable(): not allowed for non-active and non system user"); return false; } mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); if (DBG) { Log.d(TAG,"enable(): mBluetooth =" + mBluetooth + " mBinding = " + mBinding); } synchronized(mReceiver) { mQuietEnableExternal = false; mEnableExternal = true; // waive WRITE_SECURE_SETTINGS permission check long callingIdentity = Binder.clearCallingIdentity(); persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); Binder.restoreCallingIdentity(callingIdentity); sendEnableMsg(false); } return true; } ................... }
enable()方法中一直分析下来,
判断是否是系统app 操作蓝牙,检查是否有操作蓝牙的权限等,关键代码 在第120行sendEnableMsg(false)这里。看第 5行sendEnableMsg()方法
,继续找 第25行 handler 中的 case MESSAGE_ENABLE:处理 第38行 handleEnable(msg.arg1 == 1); 最后跳到低 51行 绑定了一个远程服务,这个远程服务在哪里????????是关键啊。。。。。。同一个目录下
查找到了如下代码
public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) Log.d(TAG, "BluetoothServiceConnection: connected to AdapterService"); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); msg.obj = service; mHandler.sendMessage(msg); }
D/BluetoothManagerService( 1646): BluetoothServiceConnection: connected to AdapterService 在我们贴出来的打印里面也可以找到这句话 ,在打印的第 13行就有。。。我们查找全局代码 发现 AdapterService 类服务 在Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService 下面。
注意了:我们从
Framworks 跳到 Bluetooth APP 中了 这个过程也正好符合我们前面贴出来的 Android4.2 Bluetooth 整体结构图http://img.blog.csdn.net/20141114141134245?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVpZHVjbGVhcl91cA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
我们看看Bluetooth 里面是怎么实现的吧!!!代码路径 Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService
看里面的 enable(boolean)
实现
public class AdapterService extends Service { ...................... mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); ................ public synchronized boolean enable(boolean quietMode) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); if (DBG)debugLog("Enable called with quiet mode status = " + mQuietmode); mQuietmode = quietMode; Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); mAdapterStateMachine.sendMessage(m); return true; } ............... }
final class AdapterState extends StateMachine { .................... private class PendingCommandState extends State { @Override public boolean processMessage(Message msg) { boolean isTurningOn= isTurningOn(); boolean isTurningOff = isTurningOff(); switch (msg.what) { ........................... case STARTED: { if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); //Remove start timeout removeMessages(START_TIMEOUT); //Enable boolean ret = mAdapterService.enableNative(); if (!ret) { Log.e(TAG, "Error while turning Bluetooth On"); notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); transitionTo(mOffState); } else { sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY); } } break; ................. } return true; } } ...................... }
我们看第 27行代码
//Enable
boolean ret = mAdapterService.enableNative(); 最终调用了 本地的 JNI 方法 来进行 enable 我们来到 Packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp 下面 看代码如下:
static jboolean enableNative(JNIEnv* env, jobject obj) { ALOGV("%s:",__FUNCTION__); jboolean result = JNI_FALSE; if (!sBluetoothInterface) return result; int ret = sBluetoothInterface->enable(); result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return result; }
当前文件路径下 找到如下定义
static const bt_interface_t *sBluetoothInterface = NULL;那么 bt_interface_t 结构体在哪里呢??我找了好久也没找到,因为这是依赖其他的库 找到的 结构体,所有我找当前目录下的 Android.mk 查看到里面 编译JNI的时候有依赖 一个库
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils \
libhardware
就是 libhardware 库了。自然找到 hardware/libhardware/include/hardware/bluetooth.h 有bluetooth.h 文件自然有 bluetooth.c 文件,我们查找全局代码 找到了 bluetooth.c 在 external/bluedroid/btif/src/bluetooth.c 下面。看代码如下:
static const bt_interface_t bluetoothInterface = { sizeof(bt_interface_t), init, enable, disable, cleanup, get_adapter_properties, get_adapter_property, set_adapter_property, get_remote_device_properties, get_remote_device_property, set_remote_device_property, get_remote_service_record, get_remote_services, start_discovery, cancel_discovery, create_bond, remove_bond, cancel_bond, pin_reply, ssp_reply, get_profile_interface, dut_mode_configure, dut_mode_send, enter_headless_mode, add_headless_mode_wakeup_device, delete_headless_mode_wakeup_device };
总结:借鉴了网上很多人的博客,写的不是很详细,继续研究。
Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程
原文地址:http://blog.csdn.net/feiduclear_up/article/details/41118943