手把手教你aosp13/14上实现PRODUCT_BOOT_JARS/boot jar(有源码)-千里马framework

本文介绍了如何在Android开源项目(AOSP)中使用Bootjar解决不同芯片厂商接口不一致的问题,通过创建公共接口库并将其作为中间件,降低设备厂商App的维护成本。详细讲解了Bootjar的原理、集成方法以及在系统应用和第三方应用中的调用策略。

背景:

经常设备厂商可能开发一些功能时候会有一些和芯片厂商打交道,比如mtk,海思,amlogic,高通啥的。这些芯片商一些相关功能比如Tv啥的,可能接口各不一样。但是对于设备厂商肯定想要统一的接口对于上层,不可能让设备厂商app根据每个平台出个不一样app。

在这里插入图片描述
这种会大大增加app维护成本,故是不推荐的方案。

是否可以把Tv相关app需要接口都做成公共接口jar,然后这个接口jar自己去实现各个平台差异,即每个平台都会有不同的实现,但是对于Tv这个app来说并不关心,因为他只依赖一个公共接口jar就行,至于你这个接口jar具体实现自己根据平台自己来实现。类似依赖是中间件jar,中间层,apk只依赖中间层接口,具体差异中间层自己去平台对接。

在这里插入图片描述
但是这个中间件怎么集成好呢?如果依旧编译到apk里面那就和老方案就没啥大差别,一样会让Tv这个apk需要频繁打包,如果中间件的jar放到公共framework的部分,那么这个时候apk就不需要进行针对平台单独打包,所以这个时候就需要学习今天问题重点:
手把手教你实现aosp14上的boot jar。

先直观认识boot jar:
字面意思理解就是一开机启动系统就已经自动加载好了的jar包
具体验证方式:输入$BOOTCLASSPATH命令

emulator_x86_64:/system/etc/permissions # $BOOTCLASSPATH
/system/bin/sh: /apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/framework-graphics.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/boot_jar.jar:/system/framework/ims-common.jar:/apex/com.android.i18n/javalib/core-icu4j.jar:/apex/com.android.adservices/javalib/framework-adservices.jar:/apex/com.android.adservices/javalib/framework-sdksandbox.jar:/apex/com.android.appsearch/javalib/framework-appsearch.jar:/apex/com.android.btservices/javalib/framework-bluetooth.jar:/apex/com.android.configinfrastructure/javalib/framework-configinfrastructure.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.devicelock/javalib/framework-devicelock.jar:/apex/com.android.healthfitness/javalib/framework-healthfitness.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.ondevicepersonalization/javalib/framework-ondevicepersonalization.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.permission/javalib/framework-permission-s.jar:/apex/com.android.scheduling/javalib/framework-scheduling.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.tethering/javalib/framework-connectivity.jar:/apex/com.android.tethering/javalib/framework-connectivity-t.jar:/apex/com.android.tethering/javalib/framework-tethering.jar:/apex/com.android.uwb/javalib/framework-uwb.jar:/apex/com.android.virt/javalib/framework-virtualization.jar:/apex/com.android.wifi/javalib/framework-wifi.jar: inaccessible or not found


实现业务jar包和预制到system/framework目录

framework/base路径下做一个简单的接口实现jar包

commit 10f6d3189f290820f1f7d2b2f88a8ca66855cd56 (HEAD -> android-14.0.0_r15)
Author: Your Name <you@example.com>
Date:   Wed Mar 27 22:58:39 2024 +0800

    add boot  jar modify
    
    Change-Id: I27645a05b65c743c8200b4a3b190d6d6908caeee

diff --git a/cmds/boot_jar/Android.bp b/cmds/boot_jar/Android.bp
new file mode 100644
index 000000000000..0ca613d3b077
--- /dev/null
+++ b/cmds/boot_jar/Android.bp
@@ -0,0 +1,10 @@
+// Copyright 2008 The Android Open Source Project
+//
+
+java_library {
+    name: "boot_jar",
+    srcs: [
+        "src/**/*.java",
+    ],
+    installable: true,
+}
\ No newline at end of file
diff --git a/cmds/boot_jar/src/com/hello/BootTest.java b/cmds/boot_jar/src/com/hello/BootTest.java
new file mode 100644
index 000000000000..9f1a90d774ec
--- /dev/null
+++ b/cmds/boot_jar/src/com/hello/BootTest.java
@@ -0,0 +1,7 @@
+package  com.hello;
+
+public  class BootTest {
+    public void testBootJar(){
+        android.util.Log.i("lsm","testBootJar --- realPart");
+    }
+}
\ No newline at end of file


接下来还有关键步骤预制成bootjar
路径build/make/target/product/default_art_config.mk

test@test:~/disk2/aosp14/build/make/target/product$ git diff
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index d970203470..72033c1b77 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -45,6 +45,7 @@ PRODUCT_BOOT_JARS += \
     ext \
     telephony-common \
     voip-common \
+    boot_jar \
     ims-common
 
 # APEX boot jars. Keep the list sorted by module names and then library names.

到这里boot_jar这个jar包就被放入到system/framework目录了

需要添加相关的白名单

build/soong下面对package_allowed_list进行相关包名添加

test@test:~/disk2/aosp14/build/soong$ git diff
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index 869fd3f83..c00aa29b5 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -254,3 +254,7 @@ com\.google\.i18n\.phonenumbers
 # Packages used for Android in Chrome OS
 org\.chromium\.arc
 org\.chromium\.arc\..*
+###################################################
+# Packages used for com.hello
+com\.hello
+com\.hello\..*
\ No newline at end of file

测试程序

上面只是写好了一个bootjar需要开始验证是否可以使用这个bootjar

1、验证一下系统启动后是否已经有了这个jar

emulator_x86_64:/system/etc/permissions # $BOOTCLASSPATH
/system/bin/sh: /apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/framework-graphics.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/boot_jar.jar:/system/framework/ims-common.jar:/apex/com.android.i18n/javalib/core-icu4j.jar:/apex/com.android.adservices/javalib/framework-adservices.jar:/apex/com.android.adservices/javalib/framework-sdksandbox.jar:/apex/com.android.appsearch/javalib/framework-appsearch.jar:/apex/com.android.btservices/javalib/framework-bluetooth.jar:/apex/com.android.configinfrastructure/javalib/framework-configinfrastructure.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.devicelock/javalib/framework-devicelock.jar:/apex/com.android.healthfitness/javalib/framework-healthfitness.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.ondevicepersonalization/javalib/framework-ondevicepersonalization.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.permission/javalib/framework-permission-s.jar:/apex/com.android.scheduling/javalib/framework-scheduling.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.tethering/javalib/framework-connectivity.jar:/apex/com.android.tethering/javalib/framework-connectivity-t.jar:/apex/com.android.tethering/javalib/framework-tethering.jar:/apex/com.android.uwb/javalib/framework-uwb.jar:/apex/com.android.virt/javalib/framework-virtualization.jar:/apex/com.android.wifi/javalib/framework-wifi.jar: inaccessible or not found


看看是否包含上面设置的boot_jar.jar的这个包
确定有了之后在进入下一步进行app层面调用,注意这里调用又分为系统应用和普通第三方应用:

1、系统应用的情况,这种最为简单,因为不需要考虑相关权限访问的问题
路径packages/apps/Launcher3:
修改patch如下

diff --git a/Android.bp b/Android.bp
index a7edf2a9b9..1be5c49586 100644
--- a/Android.bp
+++ b/Android.bp
@@ -295,6 +295,7 @@ android_library {
     resource_dirs: [],
     libs: [
         "framework-statsd",
+        "boot_jar",
     ],
     // Note the ordering here is important when it comes to resource
     // overriding. We want the most specific resource overrides defined
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 66690431ec..a0e0fe6eb4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -591,7 +591,6 @@ public class Launcher extends StatefulActivity<LauncherState>
         setTitle(R.string.home_screen);
         mStartupLatencyLogger.logEnd(LAUNCHER_LATENCY_STARTUP_ACTIVITY_ON_CREATE);
     }
-
     /**
      * Create {@link StartupLatencyLogger} that only collects launcher startup latency metrics
      * without sending them anywhere. Child class can override this method to create logger
@@ -2120,6 +2119,8 @@ public class Launcher extends StatefulActivity<LauncherState>
                 mTouchInProgress = false;
                 break;
         }
+        android.util.Log.i("lsm","Launcher dispatchTouchEvent event = " + ev);
+        new com.hello.BootTest().testBootJar();
         TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
         return super.dispatchTouchEvent(ev);
     }
(END)

这里只要触摸了Launcher就会有相关的打印如下

03-27 23:33:16.197  1216  1216 I lsm     : testBootJar --- realPart
03-27 23:33:16.339  1216  1216 I lsm     : Launcher dispatchTouchEvent event = MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=836.9385, y[0]=1386.8682, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=315711, downTime=315567, deviceId=4, source=0xd002, displayId=0, eventId=973480578 }
03-27 23:33:16.340  1216  1216 I lsm     : testBootJar --- realPart

2、第三方应用情况
这种相比系统应用主要会多一个访问系统hidden api的权限问题,这里的话就可以参考另一个文章:
https://blog.youkuaiyun.com/learnframework/article/details/124440160

更多framework干货请关注“千里马学框架”

<think>我们正在处理关于Android构建过程中与boot jars相关的白名单配置的问题。 根据Android的构建系统,boot jars是指那些在系统启动过程中由引导类加器加的核心JAR包。这些JAR包通常位于/system/framework目录下,例如core-oj.jar、core-libart.jar等。 在Android构建系统中,有一个白名单机制来指定哪些包可以包含在boot classpath中。这个白名单通常是通过构建系统的配置文件来管理的。 在AOSPAndroid Open Source Project)中,与boot jars相关的配置可能位于以下位置: 1. `build/make/core/`目录下的文件,特别是`boot_jars.mk`或类似的.mk文件。 2. 在Android 10及更高版本中,可能使用`build/make/core/pathmap.mk`或`build/make/core/artifact_path_requirements.mk`等文件。 具体来说,我们可以查找一个名为`boot_jars_package_whitelist.txt`的文件,或者类似命名的文件,它可能包含了允许在boot jars中出现的包名前缀。 另外,在Android 10中,谷歌引入了更严格的boot jars检查,以确保只有特定的包可以出现在boot jars中。这个白名单配置通常在一个名为`boot_jars_package_whitelist.txt`的文件中,该文件可能位于`build/make/core/`目录下。 但是,请注意,不同的Android版本可能配置位置不同。例如,在Android 11中,可能使用`build/soong/java/config/config.go`或`build/soong/java/config/bootclasspath.go`等文件来配置boot jars。 根据用户提供的引用[1]中提到了Android 11的编译注意事项,我们可以推测在Android 11及之后,构建系统有更严格的检查,包括对boot jars的包名白名单。 因此,我们可以这样回答: 在AOSP中,与boot jars相关的白名单配置通常通过以下方式之一: - 一个文本文件,例如`build/make/core/boot_jars_package_whitelist.txt`,其中每行是一个允许的包名前缀。 - 在Soong构建系统的配置文件中(如`build/soong/java/config/config.go`)定义了一个变量,例如`bootJarsPackageWhitelist`。 具体步骤: 1. 在AOSP源码中,可以尝试查找`boot_jars_package_whitelist.txt`文件: ```bash find . -name boot_jars_package_whitelist.txt ``` 2. 如果找不到,可以查找Soong构建系统的配置文件,例如在`build/soong/java/config/config.go`中,可能有类似以下代码: ```go var bootJarsPackageWhitelist = []string{ "android", "com.android", "com.google", ... // 其他允许的包名前缀 } ``` 另外,在构建过程中,系统会检查boot jars中的所有类是否属于这些白名单包。如果发现不在白名单中的类,构建会失败。 用户提到的引用[1]中,关于在framework/base/core目录下添加文件后需要更新API,并且提到了使用`metalava`工具进行API检查。同样,对于boot jars的白名单检查,也是构建过程中的一部分。 因此,总结如下: 在Android构建系统中,boot jars的白名单配置可能位于: - `build/make/core/boot_jars_package_whitelist.txt`(在较早的版本中) - 或Soong构建系统的Go配置文件(如`build/soong/java/config/config.go`)中。 例如,在Android 11的AOSP源码中,我们可以在`build/soong/java/config/config.go`文件中找到`bootJarsPackageWhitelist`变量,它定义了允许的包名前缀。 注意:如果用户需要添加自己的包到boot jars中,那么必须将这个包的包名前缀添加到白名单中,否则构建会失败。添加方法取决于具体的配置位置。 如果白名单是一个文本文件,则直接添加一行新的包名前缀。如果是在Go文件中,则需要修改该文件并重新编译Soong。 但是,修改boot jars白名单通常需要谨慎,因为只有系统核心的包才应该出现在boot classpath中。 下面给出一个示例,展示在Soong的`config.go`中如何添加: 假设我们有一个自定义的包名为`com.example.boot`,我们需要将其添加到白名单中: 在`build/soong/java/config/config.go`中找到`bootJarsPackageWhitelist`,然后添加一行: "com.example.boot", 然后重新构建Soong(执行`m nothing`或`m soong`),再构建整个系统。 注意:修改构建系统的配置需要重新构建Soong,这可能会影响整个构建过程。 另外,在Android 10之后,Google还引入了另一个机制,即通过`hiddenapi`来限制对非公开API的访问,而boot jars的白名单也是hiddenapi机制的一部分。因此,修改boot jars白名单后,可能还需要更新hiddenapi相关的配置文件。 由于问题只关注白名单的配置位置,我们主要回答配置的位置。 因此,最终回答:</think>### Android构建中boot jars白名单配置指南 在Android构建系统中,boot jars是指由系统引导加器加的核心Java库(如`framework.jar`)。白名单配置决定了哪些包/类可以出现在这些核心JAR文件中。以下是关键配置位置和方法: #### 一、核心配置文件位置 1. **包名白名单** `build/make/core/boot_jars_package_whitelist.txt` 每行定义一个允许出现在boot jars中的包名前缀,例如: ``` android. com.android. java. javax. ``` 2. **类级白名单** `frameworks/base/config/hiddenapi-*.txt` 包含三类配置文件: - `hiddenapi-flags.csv`:定义API可见性(`public`/`private`) - `hiddenapi-unsupported.csv`:禁止使用的API - `hiddenapi-removed.txt`:已移除的API 3. **构建系统配置** `build/soong/java/config/config.go` 包含白名单的Go语言定义: ```go var BootJarsPackageWhitelist = []string{ "android", "com.android", "dalvik", "libcore", "java", } ``` #### 二、自定义白名单流程 1. **添加包名前缀** 在`boot_jars_package_whitelist.txt`追加新行: ```diff + com.yourcompany. ``` 2. **绕过Metalava检查** 在模块的`Android.bp`中添加: ```python metalava_framework_docs_args = [ "--api-lint-ignore-prefix com.yourcompany.", ] ``` 3. **处理HiddenAPI限制** 在`hiddenapi-flags.csv`中为自定义API添加可见性标记: ``` Lcom/yourcompany/YourClass;->yourMethod()Landroid/content/Intent;,public-api ``` #### 三、验证配置 1. 编译后检查生成的签名文件: ```bash adb pull /system/etc/hiddenapi-force-blacklist.txt grep "com.yourcompany" hiddenapi-force-blacklist.txt ``` 2. 使用`adb shell dumpsys package`检查boot classpath: ```bash adb shell dumpsys package | grep -A 10 "Boot Classpath" ``` #### 四、注意事项 1. **API稳定性** 白名单中的API将成为SDK的一部分,需添加`@SystemApi`注解: ```java /** * @hide */ @SystemApi public class YourSystemClass { ... } ``` 2. **Android版本差异** - Android 10-:配置在`build/core/tasks/check_boot_jars/package_whitelist.txt` - Android 11+:迁移至Soong构建系统,需修改Go文件 3. **严格模式检查** 启用完整验证: ```bash ENABLE_METALAVA_STRICT_CHECKS=true m ``` > 提示:完整文档参考AOSP源码中的`build/soong/docs/best_practices.md#boot-jars`[^1]。修改后务必执行`make update-api`更新API签名。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值