網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
首先我們要知道,主要系統(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。可以通過 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)聽App通過接口修改BT 名稱的廣播
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
//監(jiān)聽bt地址改變的廣播
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
//監(jiān)聽當(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);如果是,這次開機(jī)也需要enable BT
if (isBluetoothPersistedStateOn()) {
if (DBG) {
Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
}
mEnableExternal = true;//表明開機(jī)過程中需要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)牙這里是通過觸發(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,說明之前已經(jīng)啟動(dòng)過了;此時(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、通過 IBluetooth 類型的 obj,調(diào)用 enable() 接口,將 flow 轉(zhuǎn)到 AdapterService 中,做一些初始化、并向 stack 下 enable 藍(lán)牙的 cmd
至此,enable 藍(lán)牙的 flow 就從 BluetoothManagerService 轉(zhuǎn)到 AdapterService 中了;實(shí)際上,通過 BluetoothAdapter 下來的大部分 API 調(diào)用最終都是調(diào)用到 AdapterService,再通過它下cmd 給 stack。
兩個(gè)常見到的flag:
mEnable:用來標(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 來標(biāo)記這種 case 的 enable/disable 狀態(tài)。
mEnableExternal:它主要是記錄通過用戶手動(dòng)操作導(dǎo)致的BT使能狀態(tài),如通過藍(lán)牙功能按鈕來 enable/disable 藍(lán)牙。
原文鏈接:https://blog.csdn.net/c19344881x/article/details/128718529
相關(guān)推薦
- 2024-03-15 Gitea Webhook報(bào)錯(cuò) webhook.ALLOWED_HOST_LIST setting
- 2023-02-09 詳解如何使用Python實(shí)現(xiàn)復(fù)制粘貼的功能_python
- 2022-07-10 深拷貝的三種實(shí)現(xiàn)方式
- 2022-11-07 python多進(jìn)程使用apply_async的使用方法詳解_python
- 2022-11-27 通過源碼分析Golang?cron的實(shí)現(xiàn)原理_Golang
- 2023-01-05 C++模板?index_sequence使用示例詳解_C 語(yǔ)言
- 2022-01-19 正則——時(shí)間 時(shí)分秒 12小時(shí)制 24小時(shí)制 moment可以轉(zhuǎn)化的時(shí)間 HH:mm:ss hh:m
- 2022-11-27 Windows批處理文件(.bat和.cmd)及區(qū)別詳解_DOS/BAT
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支