Android藍(lán)牙服務(wù)啟動(dòng)流程分析探索
首先我們要知道,主要系統(tǒng)服務(wù)都是在 SystemServer 啟動(dòng)的,藍(lán)牙也是如此:
1、SystemServer
源碼路徑:/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) { if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) { Slog.i(TAG, "No Bluetooth Service (factory test)"); } else if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) { Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)"); } else { t.traceBegin("StartBluetoothService"); mSystemServiceManager.startService(BluetoothService.class); t.traceEnd(); } }
SystemServer 在啟動(dòng)其他服務(wù)的方法里,啟動(dòng)了 BluetoothService。
2、BluetoothService
class BluetoothService extends SystemService { private BluetoothManagerService mBluetoothManagerService; public BluetoothService(Context context) { super(context); //創(chuàng)建BluetoothManagerService的實(shí)例 mBluetoothManagerService = new BluetoothManagerService(context); } ...... @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { //將BluetoothManagerService實(shí)例發(fā)布到系統(tǒng)中,這樣就可以Context根據(jù)BT的service名去獲取它的Binder代理操作API了 publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService); } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { //此時(shí)系統(tǒng)應(yīng)該啟動(dòng)到一個(gè)比較晚的階段了,可以使用AMS去Bind需要的Service了 mBluetoothManagerService.handleOnBootPhase(); } } ...... }
可以看到,真正獲取的服務(wù)是BluetoothManagerService 而非 BluetoothService??梢酝ㄟ^(guò) ServiceManager.getService(BLUETOOTH_MANAGER _SERVICE) 獲取藍(lán)牙服務(wù)。
onBootPhase(int):這個(gè)函數(shù)應(yīng)該是 systemserver 在啟動(dòng)的時(shí)候會(huì)多次調(diào)用,參數(shù)代表當(dāng)前啟動(dòng)進(jìn)行到了什么階段,用戶定義的 service 針對(duì)各個(gè)階段需要做怎樣的處理或者是不做任何處理。
3、BluetoothManagerService
BluetoothManagerService(Context context) { //創(chuàng)建內(nèi)部處理msg的handler mHandler = new BluetoothHandler(IoThread.get().getLooper()); mContext = context; ...... //false表示此次enable需要觸發(fā)auto connect device和保存狀態(tài),BluetoothAdapter::enableNoAutoConnect()可以改變此狀態(tài) mQuietEnableExternal = false; mEnableExternal = false; ...... IntentFilter filter = new IntentFilter(); //監(jiān)聽(tīng)App通過(guò)接口修改BT 名稱的廣播 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); //監(jiān)聽(tīng)bt地址改變的廣播 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED); //監(jiān)聽(tīng)當(dāng)前設(shè)置需要restore回上一次設(shè)置的廣播,此時(shí)需要重新保存name和addr為上一次的信息 filter.addAction(Intent.ACTION_SETTING_RESTORED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(mReceiver, filter); //從數(shù)據(jù)庫(kù)中加載本機(jī)Bt的local name和address loadStoredNameAndAddress(); //查看上一次關(guān)機(jī)時(shí),BT是否為enable狀態(tài);如果是,這次開(kāi)機(jī)也需要enable BT if (isBluetoothPersistedStateOn()) { if (DBG) { Slog.d(TAG, "Startup: Bluetooth persisted state is ON."); } mEnableExternal = true;//表明開(kāi)機(jī)過(guò)程中需要enable BT } }
在服務(wù)啟動(dòng)到一定階段就會(huì)回調(diào)到 SystemService 的 onBootPhase(int) 方法,即 2 中的該方法,然后調(diào)用 BMS 中的 handleOnBootPhase() 方法。
public void handleOnBootPhase() { ...... final boolean isSafeMode = mContext.getPackageManager().isSafeMode(); if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && && !isSafeMode) { sendEnableMsg(mQuietEnableExternal/*默認(rèn)false,表示此次enable需要自動(dòng)連接device/保存enable狀態(tài)*/, BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT, mContext.getPackageName()); } else if (!isNameAndAddressSet()) { Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); mHandler.sendMessage(getMsg); } ...... }
handleOnBootPhase()的內(nèi)容比較單一,根據(jù)一些flag判斷是否需要enable BT;而enable藍(lán)牙這里是通過(guò)觸發(fā)send msg實(shí)現(xiàn)。
private void sendEnableMsg(boolean quietMode, int reason, String packageName) { //發(fā)送MESSAGE_ENABLE msg mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0)); addActiveLog(reason, packageName, true); mLastEnabledTime = SystemClock.elapsedRealtime(); } case MESSAGE_ENABLE: int quietEnable = msg.arg1; mQuietEnable = (quietEnable == 1);//此時(shí)為false //mBluetooth是后面綁定Bt apk中AdapterService時(shí)拿到的Binder代理對(duì)象;用以把操作bypass到BT核心框架中 if (mBluetooth == null) { handleEnable(mQuietEnable); } else {//如果mBluetooth不是null,說(shuō)明之前已經(jīng)啟動(dòng)過(guò)了;此時(shí)是Restart flow,以MESSAGE_RESTART_BLUETOOTH_SERVICE觸發(fā) mWaitForEnableRetry = 0; Message enableDelayedMsg = mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED); mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS); } break;
handleEnable() 去 Bind AdapterService 拿到它的Binder句柄。同樣的在調(diào)用 BluetoothManagerService 中的 enable()、disable()等方法時(shí),也是調(diào)到 handleEnable() 方法,從而最終調(diào)用 AdapterService 中的 enable()、disable() 方法。
private void handleEnable(boolean quietMode) { mQuietEnable = quietMode; try { mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS); Intent i = new Intent(IBluetooth.class.getName()); if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); } else { mBinding = true; } } } finally { mBluetoothLock.writeLock().unlock(); } }
然后我們看一下 doBind() 方法中的 mConnection 參數(shù):
private BluetoothServiceConnection mConnection = new BluetoothServiceConnection(); private class BluetoothServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName componentName, IBinder service) { String name = componentName.getClassName(); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); if (name.equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; } else if (name.equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { Slog.e(TAG, "Unknown service connected: " + name); return; } msg.obj = service; mHandler.sendMessage(msg); } public void onServiceDisconnected(ComponentName componentName) { // Called if we unexpectedly disconnect. String name = componentName.getClassName(); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); if (name.equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; } else if (name.equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { Slog.e(TAG, "Unknown service disconnected: " + name); return; } mHandler.sendMessage(msg); } }
拿到 AdapterService 服務(wù)后,發(fā)送MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息且 arg1 = SERVICE_IBLUETOOTH。
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: { IBinder service = (IBinder) msg.obj; try { mBluetoothLock.writeLock().lock(); mBinding = false; mBluetoothBinder = service; mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service)); //Register callback object try { mBluetooth.registerCallback(mBluetoothCallback, mContext.getAttributionSource()); } catch (RemoteException re) { Slog.e(TAG, "Unable to register BluetoothCallback", re); } //Inform BluetoothAdapter instances that service is up sendBluetoothServiceUpCallback(); //Do enable request try { if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())) { Slog.e(TAG, "IBluetooth.enable() returned false"); } } catch (RemoteException e) { Slog.e(TAG, "Unable to call enable()", e); } } finally { mBluetoothLock.writeLock().unlock(); } if (!mEnable) { waitForState(Set.of(BluetoothAdapter.STATE_ON)); handleDisable(); waitForState(Set.of(BluetoothAdapter.STATE_OFF, BluetoothAdapter.STATE_TURNING_ON, BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_BLE_TURNING_ON, BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_BLE_TURNING_OFF)); } }
主要操作:
1、拿到 bind 服務(wù)的 onBinder() 句柄,并轉(zhuǎn)成 IBluetooth 類型
2、通過(guò) IBluetooth 類型的 obj,調(diào)用 enable() 接口,將 flow 轉(zhuǎn)到 AdapterService 中,做一些初始化、并向 stack 下 enable 藍(lán)牙的 cmd
至此,enable 藍(lán)牙的 flow 就從 BluetoothManagerService 轉(zhuǎn)到 AdapterService 中了;實(shí)際上,通過(guò) BluetoothAdapter 下來(lái)的大部分 API 調(diào)用最終都是調(diào)用到 AdapterService,再通過(guò)它下cmd 給 stack。
兩個(gè)常見(jiàn)到的flag:
mEnable:用來(lái)標(biāo)記系統(tǒng)運(yùn)行時(shí),藍(lán)牙狀態(tài)的變化,它有些時(shí)候跟 mEnableExternal 值一致。但如果藍(lán)牙的狀態(tài)是因?yàn)槟承┰颍?stack 崩潰,導(dǎo)致藍(lán)牙需要重啟,重新啟動(dòng)時(shí),需要靠這個(gè) flag 來(lái)標(biāo)記這種 case 的 enable/disable 狀態(tài)。
mEnableExternal:它主要是記錄通過(guò)用戶手動(dòng)操作導(dǎo)致的BT使能狀態(tài),如通過(guò)藍(lán)牙功能按鈕來(lái) enable/disable 藍(lán)牙。
到此這篇關(guān)于Android藍(lán)牙服務(wù)啟動(dòng)流程分析探索的文章就介紹到這了,更多相關(guān)Android藍(lán)牙服務(wù)啟動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TextView中URL等指定特殊字符串與點(diǎn)擊事件解析
這篇文章主要為大家詳細(xì)介紹了TextView中URL等指定特殊字符串與點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11Android多線程+單線程+斷點(diǎn)續(xù)傳+進(jìn)度條顯示下載功能
這篇文章主要介紹了Android多線程+單線程+斷點(diǎn)續(xù)傳+進(jìn)度條顯示下載功能,需要的朋友可以參考下2017-06-06Android垃圾回收機(jī)制及程序優(yōu)化System.gc
這篇文章主要介紹了Android垃圾回收機(jī)制及程序優(yōu)化System.gc的相關(guān)資料,需要的朋友可以參考下2016-01-01Android實(shí)現(xiàn)button居中的方法
這篇文章主要介紹了Android實(shí)現(xiàn)button居中的方法,涉及Android的XML布局技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09基于Flutter制作一個(gè)火箭發(fā)射動(dòng)畫(huà)
北京時(shí)間10月16日0時(shí)23分,神舟十三號(hào)飛船成功發(fā)射,為慶祝這一喜事,本文將用Flutter制作一個(gè)火箭發(fā)射動(dòng)畫(huà),感興趣的小伙伴可以動(dòng)手試一試2022-03-03Android自定義垂直拖動(dòng)seekbar進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義垂直拖動(dòng)seekbar進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11Android仿微信公眾號(hào)文章頁(yè)面加載進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android仿微信公眾號(hào)文章頁(yè)面加載進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06