Android Frameworks 启动过程--以 Radio Frameworks 为例

Radio Frameworks

  • 收音机服务进程在 Android 中在 frameworks/base/services/java/com/android/server/SystemServer.java/startOtherServices 中被调用启动

一、加载 Radio 权限配置文件

image

  1. SystemConfig 在构造函数中加载权限配置文件时,会在多个文件目录下找权限配置文件,比如环境变量中设置的目录,如 /system/etc/permissions/,还允许自定义设置环境变量目录,比如 /vendor/etc/permissions/
  2. 但是这些配置文件都是由 frameworks/native/data/etc/ 目录下拷贝过去的,比如收音机的权限配置文件是名为 android.hardware.broadcastradio.xml
  3. 拷贝命令一般都位于编译的 mk 文件中,使用系统变量 PRODUCT_COPY_FILES
    1. 如想要移动收音机的配置权限从目录 frameworks/native/data/etc/ 移动到 /vendor/etc/permissions
    2. PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.broadcastradio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.broadcastradio.xml

二、启动 Radio frameworks 进程

// frameworks/base/core/java/android/content/pm/PackageManager.java
// 就是收音机权限配置文件中的 feature name
public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
    ...
    // 判断收音机是否需要加载
    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 的服务
    }
}

三、Radio App 启动过程

  • Radio 的服务是由 App 的进程调用,如以 Android 原生 APP 的调用
  • APP 的启动是由 Launcher 服务启动的

image

  1. packages/apps/Car/Radio/src/com/android/car/radio 文件夹是原始的 Radio APP 代码,主要是 Android 界面上 HMI 的代码
  2. packages/apps/Car/Radio/src/com/android/car/radio/platform/ 是 RadioService 也就是访问 Frameworks 接口的代码。
  3. 一个是 HMI 专注于用户交互,一个负责接收上层业务调用,并且调用 Android 原生的内核接口传递请求到内层。个人理解是前后依赖后者即可,但是在前者的原始 APP 代码中,即 RadioService.java 文件中还引入了 import android.hardware.radio.RadioManager;。该设计不知道目的是什么?

至此就完成了 RadioHalService 的启动,注册,上层应用进程获取,使用的整个启动过程。

四、RadioService 使用 Frameworks 接口步骤

  1. 获取 RadioManager 的实例化
    public RadioManagerExt(@NonNull Context ctx) {
        mRadioManager = (RadioManager)ctx.getSystemService(Context.RADIO_SERVICE);
        ...
    }
  1. 初始化 Modules,每个连接 RadioManager 的服务都有一个 ModuleId,用来支持多进程访问 Radio 服务的
private void initModules() {}
  1. 打开一个 RadioTuner 实例,用来控制 Radio 设备的类,里面提供了 Radio 操作的功能,如 tune,scan,mute 等功能
RadioTuner tuner = mRadioManager.openTuner( module.getId(),               null, true, cbExt, hwHandler);
  1. 使用 Tuner 的功能,如 tune,scan
mRadioTuner.tune(ProgramSelectorExt.createAmFmSelector(lastChannel));
mRadioTuner.scan(RadioTuner.DIRECTION_UP, true);

---- END ----

posted @ 2024-04-01 15:01  王清河  阅读(186)  评论(0编辑  收藏  举报