Android藍(lán)牙打開和關(guān)閉的流程基本一致,這里就從打開的流程進(jìn)行分析。
1 UI
從UI上看藍(lán)牙開關(guān)就是設(shè)置settings里那個(gè)switch開關(guān)派近,藍(lán)牙開關(guān)操作封裝在Settings/bluetooth/BluetoothEnabler.java中描沟,BluetoothEnabler便于藍(lán)牙開關(guān)管理。里面實(shí)現(xiàn)SwitchBar.OnSwitchChangeListener接口沟于,監(jiān)聽狀態(tài)改變尽纽。
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
...........
//在LocalBluetoothAdapter中打開藍(lán)牙
if (mLocalAdapter != null) {
mLocalAdapter.setBluetoothEnabled(isChecked);
}
mSwitch.setEnabled(false);
}
onSwitchChanged里面調(diào)用LocalBluetoothAdapter的setBluetoothEnabled方法念逞,這是藍(lán)牙打開或者關(guān)閉的一個(gè)接口蹭越。接下來看一下LocalBluetoothAdapter:
public void setBluetoothEnabled(boolean enabled) {
boolean success = enabled ? mAdapter.enable() : mAdapter.disable();
......設(shè)置藍(lán)牙狀態(tài).....
}
LocalBluetoothAdapter在Settings app和Framworks之間提供了一個(gè)接口去改變藍(lán)牙開關(guān)狀態(tài)昏兆。setBluetoothEnabled調(diào)用BluetoothAdapter.enable方法匙握。然后我們就進(jìn)入framework的BluetoothAdapter中繼續(xù)分析晾咪。
2 framework
public boolean enable() {
int state = STATE_OFF;
//已經(jīng)打開返回
if (isEnabled() == true){
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true;
}
//Use service interface to get the exact state
if (mService != null) {
try {
state = mService.getState();
} catch (RemoteException e) {Log.e(TAG, "", e);}
}
//當(dāng)前狀態(tài)為打開
if (state == BluetoothAdapter.STATE_BLE_ON) {
Log.e(TAG, "BT is in BLE_ON State");
notifyUserAction(true);
return true;
}
try {
//通過遠(yuǎn)程服務(wù)打開藍(lán)牙
return mManagerService.enable();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
這個(gè)方法中的關(guān)鍵代碼是“return mManagerService.enable();” mManagerService 對象是由IBluetoothManager 接口代碼實(shí)現(xiàn)的丐枉,IBluetoothManager實(shí)際定義的是AIDL文件朱沃,對應(yīng)的類就是 BluetoothManagerService 類榄攀,在路徑 frameworks/base/core/java/android/bluetooth/BluetoothManagerService 下面 嗜傅。
public boolean enable() {
if (isBluetoothDisallowed()) {
if (DBG) {
Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
}
return false;
}
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");//權(quán)限檢查
if (DBG) {
Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +
" mBinding = " + mBinding);
}
synchronized(mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// waive WRITE_SECURE_SETTINGS permission check
sendEnableMsg(false); //通過handler集中處理消息
}
if (DBG) Log.d(TAG, "enable returning");
return true;
}
方法中先判斷是否是系統(tǒng)app操作藍(lán)牙,檢查是否有操作藍(lán)牙的權(quán)限等檩赢,然后關(guān)鍵的代碼是“sendEnableMsg(false)”吕嘀,handler最后調(diào)用handleEnable方法處理該消息。
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
synchronized(mConnection) {
//檢查服務(wù)是否已經(jīng)啟動并且已經(jīng)綁定
if ((mBluetooth == null) && (!mBinding)) {
//Start 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());
//綁定服務(wù)贞瞒,UserHandle為多用戶考慮
if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
}
} else if (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();
}
//Enable bluetooth
try {
if (!mQuietEnable) {
//使能藍(lán)牙
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);
}
}
這里通過AIDL的方式偶房,調(diào)用Bluetooth App 中的AdapterService 。先綁定服務(wù)军浆,然后注冊Ibluetooth回調(diào)函數(shù)棕洋,之后調(diào)用enable方法方法開啟藍(lán)牙。所以之后就從Framworks 跳到 Bluetooth APP 中繼續(xù)分析乒融。
——————————————————————————————————
3 Bluetooth APP
代碼路徑“Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService ”掰盘,看里面的 enable(boolean) 的實(shí)現(xiàn)
public synchronized boolean enable(boolean quietMode) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);
mQuietmode = quietMode;
//由狀態(tài)機(jī)處理開啟操作
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
return true;
}
AdapterService.enable方法最終向狀態(tài)機(jī)AdapterState發(fā)送AdapterState.BLE_TURN_ON消息,由狀態(tài)機(jī)處理消息赞季。藍(lán)牙狀態(tài)機(jī)的代碼在Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState 下面愧捕,AdapterState狀態(tài)機(jī)在AdapterService的onCreate方法中他通過一個(gè)靜態(tài)函數(shù)AdapterState.make初始化。
private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
super("BluetoothAdapterState:");
addState(mOnState);
addState(mBleOnState);
addState(mOffState);
addState(mPendingCommandState);
mAdapterService = service;
mAdapterProperties = adapterProperties;
setInitialState(mOffState); //初始狀態(tài)為offstate
}
setInitialState設(shè)置了該狀態(tài)機(jī)的初始狀態(tài)是OffState申钩,AdapterState.BLE_TURN_ON消息由OffState首先處理次绘,狀態(tài)機(jī)中每個(gè)狀態(tài)通過調(diào)用public boolean processMessage方法處理每個(gè)消息。
public boolean processMessage(Message msg) {
AdapterService adapterService = mAdapterService;
if (adapterService == null) {
errorLog("Received message in OffState after cleanup: "+msg.what);
return false;
}
debugLog("Current state: OFF, message: " + msg.what);
switch(msg.what) {
//初始狀態(tài)是OffState,由OffState處理藍(lán)牙開啟操作
case BLE_TURN_ON:
//通知BluetoothmangerService藍(lán)牙正在開啟
notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
mPendingCommandState.setBleTurningOn(true);
transitionTo(mPendingCommandState);
//發(fā)送延遲消息邮偎,檢測打開超時(shí)任務(wù)
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
//批量啟動 profile service
adapterService.BleOnProcessStart();
break;
case USER_TURN_OFF:
//TODO: Handle case of service started
//and stopped without enable
break;
default:
return false;
}
return true;
}
BLE_TURN_ON里面通過回調(diào)通知BluetoothMangerService罗洗,藍(lán)牙正在啟動中,然后將狀態(tài)機(jī)中下個(gè)狀態(tài)設(shè)置為PendingCommandState钢猛,最后調(diào)用adapterService .BleOnProcessStart批量啟動所需的各個(gè)profile server。
void BleOnProcessStart() {
debugLog("BleOnProcessStart()");
//支持的profile service
Class[] supportedProfileServices = Config.getSupportedProfiles();
//Initialize data objects
for (int i=0; i < supportedProfileServices.length;i++) {
mProfileServicesState.put(supportedProfileServices[i].getName(),
BluetoothAdapter.STATE_OFF);
}
//初始化遠(yuǎn)程藍(lán)牙設(shè)備
mRemoteDevices = new RemoteDevices(this);
mAdapterProperties.init(mRemoteDevices);
debugLog("BleOnProcessStart() - Make Bond State Machine");
//啟動藍(lán)牙綁定狀態(tài)狀態(tài)
mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
//FIXME: Set static instance here???
setAdapterService(this);
//Start Gatt service
setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
}
BleOnProcessStart首先獲取支持的profile轩缤,支持的profile在 Config.java 中命迈。接著啟動新的狀態(tài)機(jī)BondStateMachine,最后調(diào)用setGattProfileServiceState方法火的,批量啟動支持的Profile server壶愤,包括GattService,啟動服務(wù)時(shí)會傳入?yún)?shù):ACTION_SERVICE_STATE_CHANGED和BluetoothAdapter.STATE_ON 馏鹤。
然后看packages/apps/Bluetooth/src/com/android/bluetooth/gatt/GattService.java啟動的入口onStartCommand征椒,里面沒有什么內(nèi)容,真正的實(shí)現(xiàn)在父類中:
public int onStartCommand(Intent intent, int flags, int startId) {
if (DBG) log("onStartCommand()");
if (mStartError || mAdapter == null) {
Log.w(mName, "Stopping profile service: device does not have BT");
doStop(intent);
return PROFILE_SERVICE_MODE;
}
if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM) != PackageManager.PERMISSION_GRANTED) {
Log.e(mName, "Permission denied!");
return PROFILE_SERVICE_MODE;
}
if (intent == null) {
Log.d(mName, "Restarting profile service...");
return PROFILE_SERVICE_MODE;
} else {
String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if(state==BluetoothAdapter.STATE_OFF) {
Log.d(mName, "Received stop request...Stopping profile...");
doStop(intent); //停止
} else if (state == BluetoothAdapter.STATE_ON) {
Log.d(mName, "Received start request. Starting profile...");
doStart(intent); //啟動
}}}
return PROFILE_SERVICE_MODE;
}
因?yàn)閱臃?wù)時(shí)傳入的參數(shù)是ACTION_SERVICE_STATE_CHANGED和BluetoothAdapter.STATE_ON湃累,所以調(diào)用doStart勃救。doStart里面調(diào)用了抽象方法start(實(shí)現(xiàn)是在子類GattService里面,做了一些預(yù)處理治力,包括initializeNative蒙秒、啟動一些manager)再調(diào)notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON),此方法會調(diào)用AdapterService.onProfileServiceStateChanged方法宵统,傳遞STATE_ON消息晕讲,該消息會包裝在MESSAGE_PROFILE_SERVICE_STATE_CHANGED類型里,由AdapterService的handler方法處理
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
debugLog("handleMessage() - Message: " + msg.what);
switch (msg.what) {
case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
processProfileServiceStateChanged((String) msg.obj, msg.arg1);
break;
}
........................
}
}
};
processProfileServiceStateChanged處理profile 狀態(tài)改變马澈,里面
//在OffState中瓢省,isBleTurningOn設(shè)置為true
if (isBleTurningOn) {
if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
debugLog("GattService is started");
mAdapterStateMachine.sendMessage(mAdapterStateMachine.
obtainMessage(AdapterState.BLE_STARTED));
return;
}
}
會向AdapterStateMachine狀態(tài)機(jī)發(fā)送BLE_STARTED消息,根據(jù)之前狀態(tài)機(jī)已經(jīng)由OffState切換成PendingCommandState痊班,所以消息由PendingCommandState狀態(tài)處理,看processMessage的處理
case BLE_STARTED:
//Remove start timeout
removeMessages(BLE_START_TIMEOUT);
//Enable,調(diào)用底層方法勤婚,開啟藍(lán)牙
if (!adapterService.enableNative()) {
errorLog("Error while turning Bluetooth on");
//開啟失敗,狀態(tài)通知辩块,切換到OffState狀態(tài)
notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
transitionTo(mOffState);
} else {
//超時(shí)檢測
sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
}
break;
通過調(diào)用adapterService.enableNative()方法蛔六,開始調(diào)用JNI方法,進(jìn)入C/C++層废亭。adapterService.enableNative對應(yīng)的cpp文件為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 || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE; //判斷是打開還是關(guān)閉狀態(tài)国章;
return result;
}
通過調(diào)用“int ret = sBluetoothInterface->enable()”來驅(qū)動底層打開藍(lán)牙開關(guān)。接下來就是C里面對打開藍(lán)牙的實(shí)現(xiàn)豆村。
——————————————————————————————————
4 藍(lán)牙協(xié)議棧
對應(yīng)的代碼在/system/bt/btif/src/bluetooth.cc里面:
static int enable(void) {
LOG_INFO("%s", __func__);
if (!interface_ready())//狀態(tài)判斷液兽,已經(jīng)初始化,向下執(zhí)行
return BT_STATUS_NOT_READY;
stack_manager_get_interface()->start_up_stack_async();
return BT_STATUS_SUCCESS;
}
enable方法會調(diào)用start_up_stack_async方法,start_up_stack_async的實(shí)現(xiàn)在stack_manager.c 文件中:
static void start_up_stack_async(void) {
thread_post(management_thread, event_start_up_stack, NULL);
}
通過thread_post異步event_start_up_stack四啰,來啟動藍(lán)牙棧
// Synchronous function to start up the stack
static void event_start_up_stack(UNUSED_ATTR void *context) {
if (stack_is_running) {
LOG_DEBUG("%s stack already brought up.", __func__);
return;
}
ensure_stack_is_initialized();//確保宁玫,棧已經(jīng)初始化
LOG_DEBUG("%s is bringing up the stack.", __func__);
hack_future = future_new();
// Include this for now to put btif config into a shutdown-able state
//加載配置文件,配置文件位于手機(jī)系統(tǒng)目錄/data/misc/bluedroid/bt_config.xml
module_start_up(get_module(BTIF_CONFIG_MODULE));
bte_main_enable();//BTE部分的enable
if (future_await(hack_future) != FUTURE_SUCCESS) {//啟動失敗
stack_is_running = true; // So stack shutdown actually happens
event_shut_down_stack(NULL); //關(guān)閉藍(lán)牙棧柑晒,里面還會調(diào)用
return;}
stack_is_running = true;
LOG_DEBUG("%s finished", __func__);
btif_thread_post(event_signal_stack_up, NULL); //發(fā)送藍(lán)牙棧啟動信息:
}
bte_main_enable()方法中進(jìn)行btsnoop_module和hci_module的啟動以及啟動BTU操作欧瘪,這里就不深入下去了。
如果打開藍(lán)牙成功匙赞,走到btif_thread_post(event_signal_stack_up, NULL)這里佛掖,會在event_signal_stack_up函數(shù)里面調(diào)用HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON) ,然后通過回調(diào)調(diào)用adapter_state_changed_cb方法涌庭,通知藍(lán)牙當(dāng)前狀態(tài)BT_STATE_ON芥被。
adapter_state_changed_cb在hardware/libhardware/include/hardware/bluetooth.h文件中被定義:
/** Bluetooth DM callback structure. */
typedef struct {
/** set to sizeof(bt_callbacks_t) */
size_t size;
adapter_state_changed_callback adapter_state_changed_cb;
...........
} bt_callbacks_t;
如果C++層有消息傳遞到j(luò)ava層,回調(diào)接口都定義在這里坐榆,adapter_state_changed_cb對應(yīng)的是adapter_state_changed_callback 拴魄。然后通過JNI回調(diào)通知到JAVA層,上層就會收到打開藍(lán)牙的通知席镀。至此匹中,打開藍(lán)牙流程分析到這里。