转载请标明出处: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 整体结构图https://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;
}
...............
}
这里我们看重点代码 mAdapterStateMachine.sendMessage(m); 跳到 Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/ AdapterState 下面, 尼妈。。。。。。。状态机 ,什么状态机啊。。。不懂啊,,看这里吧,了解一下也好android StateMachine 状态机
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
};
在这个结构体里边 可以看到蓝牙的所有抽象层 HAL 的操作。包括蓝牙初始化,打开蓝牙,关闭蓝牙,等等。到这里Bluetooth enable 基本上结束了,接下来实现 bt_interface_t bluetoothInterface 接口就是各个蓝牙生产商 自己实现了,一般代生产商的代码会放在 vendor 目录下边。
总结:借鉴了网上很多人的博客,写的不是很详细,继续研究。