Android Frameworks 啟動過程--以 Radio Frameworks 為例
Radio Frameworks
- 收音機(jī)服務(wù)進(jìn)程在 Android 中在
frameworks/base/services/java/com/android/server/SystemServer.java/startOtherServices中被調(diào)用啟動
一、加載 Radio 權(quán)限配置文件

- SystemConfig 在構(gòu)造函數(shù)中加載權(quán)限配置文件時,會在多個文件目錄下找權(quán)限配置文件,比如環(huán)境變量中設(shè)置的目錄,如 /system/etc/permissions/,還允許自定義設(shè)置環(huán)境變量目錄,比如 /vendor/etc/permissions/
- 但是這些配置文件都是由
frameworks/native/data/etc/目錄下拷貝過去的,比如收音機(jī)的權(quán)限配置文件是名為android.hardware.broadcastradio.xml - 拷貝命令一般都位于編譯的 mk 文件中,使用系統(tǒng)變量
PRODUCT_COPY_FILES,- 如想要移動收音機(jī)的配置權(quán)限從目錄
frameworks/native/data/etc/移動到/vendor/etc/permissions, PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.broadcastradio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.broadcastradio.xml
- 如想要移動收音機(jī)的配置權(quán)限從目錄
二、啟動 Radio frameworks 進(jìn)程
// frameworks/base/core/java/android/content/pm/PackageManager.java
// 就是收音機(jī)權(quán)限配置文件中的 feature name
public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
...
// 判斷收音機(jī)是否需要加載
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BROADCAST_RADIO)) {
traceBeginAndSlog("StartBroadcastRadioService");
mSystemServiceManager.startService(BroadcastRadioService.class); // 啟動 RadioHalService
traceEnd();
}
...
}
// frameworks/base/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
public class BroadcastRadioService extends SystemService {
public void onStart() {
publishBinderService(Context.RADIO_SERVICE, mServiceImpl); // 注冊 Radio 的服務(wù)
}
}
三、Radio App 啟動過程
- Radio 的服務(wù)是由 App 的進(jìn)程調(diào)用,如以 Android 原生 APP 的調(diào)用
- APP 的啟動是由 Launcher 服務(wù)啟動的

packages/apps/Car/Radio/src/com/android/car/radio文件夾是原始的 Radio APP 代碼,主要是 Android 界面上 HMI 的代碼packages/apps/Car/Radio/src/com/android/car/radio/platform/是 RadioService 也就是訪問 Frameworks 接口的代碼。- 一個是 HMI 專注于用戶交互,一個負(fù)責(zé)接收上層業(yè)務(wù)調(diào)用,并且調(diào)用 Android 原生的內(nèi)核接口傳遞請求到內(nèi)層。個人理解是前后依賴后者即可,但是在前者的原始 APP 代碼中,即 RadioService.java 文件中還引入了
import android.hardware.radio.RadioManager;。該設(shè)計不知道目的是什么?
至此就完成了 RadioHalService 的啟動,注冊,上層應(yīng)用進(jìn)程獲取,使用的整個啟動過程。
四、RadioService 使用 Frameworks 接口步驟
- 獲取 RadioManager 的實(shí)例化
public RadioManagerExt(@NonNull Context ctx) {
mRadioManager = (RadioManager)ctx.getSystemService(Context.RADIO_SERVICE);
...
}
- 初始化 Modules,每個連接 RadioManager 的服務(wù)都有一個 ModuleId,用來支持多進(jìn)程訪問 Radio 服務(wù)的
private void initModules() {}
- 打開一個 RadioTuner 實(shí)例,用來控制 Radio 設(shè)備的類,里面提供了 Radio 操作的功能,如 tune,scan,mute 等功能
RadioTuner tuner = mRadioManager.openTuner( module.getId(), null, true, cbExt, hwHandler);
- 使用 Tuner 的功能,如 tune,scan
mRadioTuner.tune(ProgramSelectorExt.createAmFmSelector(lastChannel));
mRadioTuner.scan(RadioTuner.DIRECTION_UP, true);
---- END ----

浙公網(wǎng)安備 33010602011771號