aosp环境搭建
更新环境
1 | 更新系统环境 |
下载源码
创建aosp目录(例aosp11),进入目录下载repo,不需要设置环境变量。参考镜像下载
额外添加-b 可以指定分支 -b可以指定下载路径
在aosp下创建android目录,下载源码,详细步骤查看清华镜像,提供了两种方式
- 每月更新的初始化包
- 传统初始化方法,例如使用指定版本android-12.1.0_r27,版本号可以去谷歌官网查看
- 执行
repo sync -c -j4同步代码
编译
1 | 加载aosp环境 |
其中sdk_phone_x86_64(64位),sdk_phone_x86(32位)为模拟器Product,其他可以使用lunch命令查看
模拟器文档
编译失败
out/soong/make_vars-lunch:No such file问题,多试几次
1 | 加载aosp环境 |
其他常用编译命令
1 | 删除整个 out/ 目录 |
新增product
官网文档
举个栗子:小米公司创建正在开发米13的手机
- 在aosp下新建
device/<company-name>/<device-name>目录,例如device/xiaomi/mi13 - 创建一个产品定义 Makefile文件,
mi13.mk
该文件中PRODUCT_DEVICE字段对应的就是所代表的device - 创建一个指向产品的 Makefile 的
AndroidProducts.mk文件1
2
3
4
5
6
7
8产品mk文件
PRODUCT_MAKEFILES := \
(LOCAL_DIR)/mi13.mk \
启动类型
COMMON_LUNCH_CHOICES := \
mi13-userdebug \
mi13-eng \ - 创建一个包含主板特定配置的
BoardConfig.mkMakefile
相关文件可以在aosp/build/target目录下找到模板文件进行修改
build/target: aosp 提供的product配置一般保存在该目录
device:芯片以及方案厂商放置的目录
源码方式预置apk
假设需要添加一个名为MyFirstSystemApp的预置apk,步骤如下
在我们的product目录下创建MyFirstSystemApp目录,并创建res目录和src目录,接着将app源码中的res目录和java目录下内容分别复制到res和src目录即可。
将AndroidManifest.xml文件拷贝到MyFirstSystemApp目录中。(需要注意的AndroidManifest需要为合并处理后的没有gradle构建为我们自动添加packageName等属性)
最后在MyFirstSystemApp目录下创建Android.bp文件(aosp中没有gradle,通过bp和mk文件去描述构建),内容大致如下
1 | android_app { |
然后我们需要修改product的mk文件,我这里对应 device/xiaomi/mi13/mi13.mk,添加
1 | PRODUCT_PACKAGES += MyFirstSystemApp |
执行编译
1 | source build/envsetup.sh |
添加依赖
添加已有依赖
1 | static_libs: [ |
在 AOSP 中,很多常用的库均以预编译模块的方式添加到系统源码中。
比如常用的 AndroidX 库定义在prebuilts/sdk/current/androidx 目录下,这些库通过 prebuilts/sdk/current/androidx/Android.bp 引入,而prebuilts/tools/common/m2目录下引入了大量的三方库
自定义lib
与创建app工程方式一样,创建lib工程。
aar包形式引入
假设 需要引入 lottie 这个动画库,首先我们这里下载好 lottie 库的 aar 打包文件。
在 device/xiaomi/mi13 目录下创建如下的目录结构:
liblottie/
├── Android.bp
└── lottie-5.2.0.aar
其中 Android.bp 的内容如下
1 | android_library_import { |
然后我们修改 FirstSystemApp 中的 Android.bp 引入这个库:
1 | static_libs: ["androidx.appcompat_appcompat", |
这样就可以在 App 中使用 lottie 库了
注意事项
这种方式和app开发使用gradle插件开发方式差别很大,gradle插件内部做了很多事情,比如AndroidManifest合并处理,xml一些属性的添加以及第三方库的引用,这些都需要我们自己完成
编译错误
可能会遇到artifact_path_requirements Offending entries Build failed相关的错误
- 这是因为对预置apk做了检测,我们在编译前关闭这个检查即可,在make命令之前执行
1 | export DISABLE_ARTIFACT_PATH_REQUIREMENTS="true" |
- 解决方式二就是将预置apk预置到product分区即可,在android.bp文件中添加分区描述,推荐方式
1
2
3
4
5
6android_app {
name: "MyFirstSystemApp",
//指定分区product/app
product_specific: true
//...
}
sdk版本
1 | platform_apis: true, |
当 platform_apis 为 true 时,sdk_version 必须为空。这种情况下我们的 app 会使用平台 API 进行编译而不是 SDK,这样我们的 App 就能访问到非 SDK API 了。关于 SDK API 和非 SDK API 的内容可以参考官方文档
系统 App 的签名
AOSP 内置了 APK 签名文件,我们可以在 Android.bp 中通过 certificate 配置系统 app 的签名文件,certificate 的值主要有一下几个选项:
- testkey:普通 APK,默认情况下使用
- platform:该 APK 完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的 APK 所在进程的 UID 为system
- shared:该 APK 需要和 home/contacts 进程共享数据
- media:该 APK 是 media/download 系统中的一环
- presigned:表示 这个 apk 已经签过名了,系统不需要再次签名;
系统 App 能使用更多的权限
当 Android.bp 中的 privileged 被配置为 true 时,我们的系统 App 在添加特许权限许可名单后,能使用 signature 和 signatureOrSystem 级别的权限,而普通 App 是不能使用这些权限的。
参考资料
https://mp.weixin.qq.com/s/HHhycjkjMlIsZYgQoYi6PA
通过apk方式集成app
在product目录下创建一个app目录,假设我们需要集成myTest.apk,创建device/<company-name>/<device-name>/myTest目录,product目录见新增product部分。
然后将apk文件复制到myTest目录下,并创建android.bp文件,文件内容如下
1 | android_app_import { |
最后我们需要修改product的mk文件,我这里对应 device/<company-name>/<device-name>/your.mk,添加
1 | PRODUCT_PACKAGES += myTest \ |
集成完毕,编译验证
1 | source build/envsetup.sh |
签名配置
在上面的签名配置中我们还可以使用
1 | android_app_import { |
certificate其他选项如下
- testkey:普通 APK,默认情况下使用
- platform:该 APK 完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的 APK 所在进程的 UID 为system
- shared:该 APK 需要和 home/contacts 进程共享数据
- media:该 APK 是 media/download 系统中的一环
- presigned:表示 这个 apk 已经签过名了,系统不需要再次签名;
集成位置
- system/app,不指定时默认在该目录下
1
2
3
4
5
6
7
8
9android_app_import {
name: "myTest",
//使用apk自签名,不用重签名
presigned: true,
dex_preopt: {
enabled: false,
},
apk: "myTest.apk",
} - system_ext/app
1
2
3
4
5
6
7
8
9
10
11android_app_import {
name: "myTest",
//存储app在system镜像中位置
system_ext_specific: true,
//使用apk自签名,不用重签名
presigned: true,
dex_preopt: {
enabled: false,
},
apk: "myTest.apk",
} - system/pri-app
1
2
3
4
5
6
7
8
9
10
11android_app_import {
name: "myTest",
//系统权限
privileged: true,
//使用apk自签名,不用重签名
presigned: true,
dex_preopt: {
enabled: false,
},
apk: "myTest.apk",
} - product/app
1
2
3
4android_app_import {
//product/app
product_specific: true
} - vendor/app
1
2
3
4android_app_import {
//proprietary: true,
proprietary: true,
}
system/pri-app
该目录下的app具有系统权限,其他目录下跟该目录下app签名一致的app也具有系统权限。
所以我们在集成第三方应用时,三方应用没有系统签名,却又需要使用system级别权限时,我们可以把第三方应用集成到system/pri-app目录即可;反过来,如果预装第三方应用,却不想让其拥有system级别权限时,可以将其集成到system/app目录下即可。
权限机制
https://www.404bugs.com/index.php/details/1101289176044457984