Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程

转载请标明出处: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: [email protected]
D/BluetoothAdapter( 2281): onBluetoothServiceUp: com.[email protected]423091e0
D/BluetoothAdapter( 1646): onBluetoothServiceUp: [email protected]
D/BluetoothAdapter( 1982): onBluetoothServiceUp: [email protected]
D/BluetoothAdapter( 1756): onBluetoothServiceUp: [email protected]
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: [email protected]
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: [email protected]
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: [email protected]
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: [email protected]
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: [email protected]
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: [email protected]
D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
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: [email protected]
D/BluetoothA2dp( 1982): Proxy object connected
D/BluetoothInputDevice( 1982): Proxy object connected
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
D/BluetoothPan( 1982): BluetoothPAN Proxy object connected
D/BluetoothHeadset( 1982): Proxy object connected
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
V/BluetoothEventManager( 1982): Received android.bluetooth.adapter.action.STATE_CHANGED
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: [email protected]
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: [email protected], channel: 19, state: CLOSED
D/BluetoothSocket( 2281): close() in, this: [email protected], 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;
            }

        	...............

        }

这里我们看重点代码  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;
}

看到没???  调用 int ret = sBluetoothInterface->enable(); 来驱动底层 打开 蓝牙开关。那么我们找找 sBluetoothInterface是什么吧???

当前文件路径下 找到如下定义

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 目录下边。

总结:借鉴了网上很多人的博客,写的不是很详细,继续研究。

时间: 2024-08-05 23:41:30

Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程的相关文章

[Android]Volley源码分析(二)

上一篇介绍了Volley的使用,主要接触了Request与RequestQueue这两个类,这篇就来了解一下这两个类的具体实现. Request类图: Request类: Request是一个抽象类,其中的主要属性: mMethod: 请求方法,目前支持GET, POST, PUT, DELETE, HEAD, OPTIONS,TRACE, PATCH方法 mUrl: 请求Url mErrorListener: 错误处理监听器,请求出错时调用 mSequence: 请求的序号,相同优先级的请求在

Android 4.2 Bluetooth 分析总结(一)

因为是新手,之前没有研究过蓝牙功能,也不知到Bluetooth 在android 其他版本上的情况,但是大概了解之后发现,Android4.2 之后的Bluetooth 模块和之前版本的android有很大的出入,具体表现在哪里我就不研究了,因此我是直接拿Android4.2 Bluetooth 来研究的,当然这也参考了网上很多前辈的文章:android -- 蓝牙 bluetooth (一) 入门等.在这里表示感谢!!! 一.蓝牙模块相关的代码 在Android 4.2上的分布如下: sett

Android bluetooth介绍(二): android 蓝牙代码架构及其uart 到rfcomm流程

关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP RFCOMM  版本:基于android4.2之前版本 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载,请注明作者,请尊重版权谢谢)欢迎指正错误,共同学习.共同进步!!一.Android Bluetooth Architecture蓝牙代码架构部分(google 官方蓝牙框架) Android的蓝牙系统,自下而上包括以下一些

Android多线程分析之二:Thread的实现

Android多线程分析之二:Thread 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在前文<Android多线程分析之一:使用Thread异步下载图像>中演示了如何使用 Thread 处理异步事务.示例中这个 Java Thread 类都是位于 Framework 层的类,它自身是通过 JNI 转调 dalvik 里面的 Thread 相关方法实现的.因此要分析 Androd 中的线程,就需要分析这两层中的与线程相关的代码,这就是本文要

[Android]Volley源码分析(二)Cache

Cache作为Volley最为核心的一部分,Volley花了重彩来实现它.本章我们顺着Volley的源码思路往下,来看下Volley对Cache的处理逻辑. 我们回想一下昨天的简单代码,我们的入口是从构造一个Request队列开始的,而我们并不直接调用new来构造,而是将控制权反转给Volley这个静态工厂来构造. com.android.volley.toolbox.Volley: public static RequestQueue newRequestQueue(Context conte

[Android]Fragment源码分析(二) 状态

我们上一讲,抛出来一个问题,就是当Activity的onCreateView的时候,是如何构造Fragment中的View参数.要回答这个问题我们先要了解Fragment的状态,这是Fragment管理中非常重要的一环.我们先来看一下FragmentActivity提供的一些核心回调: @Override protected void onCreate(Bundle savedInstanceState) { mFragments.attachActivity(this, mContainer,

android 休眠唤醒机制分析(二) — early_suspend

本文转自:http://blog.csdn.net/g_salamander/article/details/7982170 early_suspend是Android休眠流程的第一阶段即浅度休眠,不会受到wake_lock的阻止,一般用于关闭lcd.tp等设备为运行的应用节约电能.Android的PowerManagerService会根据用户的操作情况调整电源状态,如果需要休眠则会调用到HAL层的set_screen_state()接口,在set_screen_state()中会向/sys/

Cordova Android源码分析系列二(CordovaWebView相关类分析)

本篇文章是Cordova Android源码分析系列文章的第二篇,主要分析CordovaWebView和CordovaWebViewClient类,通过分析代码可以知道Web网页加载的过程,错误出来,多线程处理等. CordovaWebView类分析 CordovaWebView类继承了Android WebView类,这是一个很自然的实现,共1000多行代码.包含了PluginManager pluginManager,BroadcastReceiver receiver,CordovaInt

【Android SDK程序逆向分析与破解系列】之二:Android可执行程序DEX分析(一)

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWells [Android SDK程序逆向分析与破解系列]章节索引 一 DEX文件数据结构 DEX使用的数据类型如下表所示: u1~u8:表示1~8字节的无符号数. sleb128.uled128和uled128pl:DEX文件特有的LEB128数据类型.每个LEB128由1~5个字节组成,所有的字节组合在一起