編輯:關於Android編程
轉載請標明出處: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: CLOSED1.從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.
*
* 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
};
總結:借鑒了網上很多人的博客,寫的不是很詳細,繼續研究。
基於Android2.3.5系統:JNI與HAL實例解析[一]
一:Android系統下JNI簡介 Android系統下的JNI的全稱是:Java Native Interface (JNI),JNI標准是java平台的
Android開發之給應用簽名打包
Android開發之給應用簽名打包什麼是簽名打包?在Android 系統中,所有安裝到系統的應用程序都必有一個數字證書,此數字證書用於標識應用程序的作者和在應用程序之間建
Android -- Camera2(Android5.0)
Android -- Camera2(Android5.0) Camera2 Camera2是Android5.0中的其中一個新的特性,新的API。與原來的
Android中AsyncTask與handler用法實例分析
本文實例講述了Android中AsyncTask與handler用法。分享給大家供大家參考,具體如下:首先,我們得明確下一個概念,什麼是UI線程。顧名思義,ui線程就是管