Android系统开发--添加新设备
- 了解编译层
- 编译产品
- 编写配置产品的Makefile
- 配置产品的编译文件关系
- 使用编译类型
- 编译类型
- userdebug 准则
- 利用资源叠加层定制版本
- 设置 ANDROID_VENDOR_KEYS 以通过 USB 进行连接
了解编译层
编译层次结构包括与设备的物理结构对应的抽象层。下表中介绍了这些层。每个层都与上一层存在一对多的关系。例如,一个架构可以有多个板,一个板可以有多个产品。可以将指定层中的某个元素定义为同一层中某个元素的特化元素,从而免去复制操作并简化维护工作。
类图标识如下:
编译产品
编写配置产品的Makefile
以下步骤介绍了如何采用与设置 Nexus 6 产品线类似的方式设置产品 Makefile:
- 创建 device/<company_name>/<device_name> 目录,例如 device/moto/shamu。该目录中将包含设备的源代码以及编译这些代码所需的 Makefile。
- 创建一个用于声明设备所需文件和模块的 device.mk Makefile。有关示例,参阅Android源码中device目录下google或其他的device。
- 创建一个产品定义 Makefile,以便基于设备创建具体产品。以下示例 Makefile 来自于 device/moto/shamu/aosp_shamu.mk。该产品会通过引用 Makefile 沿用 device/moto/shamu/device.mk 和 vendor/moto/shamu/device-vendor.mk 文件中的内容,同时还会声明产品特定信息,例如名称、品牌和型号。
# Inherit from the common Open Source product configuration
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
PRODUCT_NAME := aosp_shamu
PRODUCT_DEVICE := shamu
PRODUCT_BRAND := Android
PRODUCT_MODEL := AOSP on Shamu
PRODUCT_MANUFACTURER := motorola
PRODUCT_RESTRICT_VENDOR_FILES := true
$(call inherit-product, device/moto/shamu/device.mk)
$(call inherit-product-if-exists, vendor/moto/shamu/device-vendor.mk)
PRODUCT_NAME := aosp_shamu
PRODUCT_PACKAGES += \
Launcher3
可添加到 Makefile 的其他产品特定变量,如下表:
4. 创建一个指向产品的 Makefile 的 AndroidProducts.mk 文件,内容仅需要引用定义产品的Makefile。以下示例来自于 device/moto/shamu/AndroidProducts.mk:
#
# This file should set PRODUCT_MAKEFILES to a list of product makefiles
# to expose to the build system. LOCAL_DIR will already be set to
# the directory containing this file.
#
# This file may not rely on the value of any variable other than
# LOCAL_DIR; do not use any conditionals, and do not look up the
# value of any variable that isn't set in this file or in a file that
# it includes.
#
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_shamu.mk
- 创建一个包含主板特定配置的 BoardConfig.mk Makefile,请参阅Android源码中device目录下已有device的产品示例。
- 创建一个 vendorsetup.sh 文件,将产品与编译变体(使用短划线将两者分隔开)一起添加到版本中。例如:
add_lunch_combo <PRODUCT_NAME>-userdebug
配置产品的编译文件关系
device.mk、device-vendor.mk:定义具体设备需要的文件和模块。同类文件,不同目录下。
aosp_shamu.mk:该文件时示例文件,具体文件名以实际添加为准。一个产品配置的入口文件,包括产品一些属性定义,如名称、品牌和型号等。
AndroidProducts.mk:配置产品列表,编译系统从该文件关联产品与产品配置文件
BoardConfig.mk:板设备配置文件,产品编译都会执行版设备的配置文件
vendorsetup.sh:Android源码source build/envsetup.sh时把产品添加到编译列表的入口文件,方便在lunch时选择具体产品
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
`test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
`test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
do
echo "including $f"
. $f
done
unset f
添加到设备列表
function add_lunch_combo()
{
local new_combo=$1
local c
for c in ${LUNCH_MENU_CHOICES[@]} ; do
if [ "$new_combo" = "$c" ] ; then
return
fi
done
LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}
关系图如下:
调用流程:
AndroidProducts.mk、BoardConfig.mk在编译时执行
使用编译类型
在针对特定产品进行编译时,如果能在最终发布版本的基础上进行细微修改,通常会非常有用。在模块定义中,模块可以通过 LOCAL_MODULE_TAGS 指定标记,这些标记可以是以下一个或多个值:optional(默认)、debug、eng。
如果某个模块没有通过 LOCAL_MODULE_TAGS 指定标记,则其标记默认为 optional。仅当 PRODUCT_PACKAGES 的产品配置需要可选模块时,系统才会安装可选模块。
编译类型
以下是当前已定义的编译类型:
userdebug 准则
在测试中运行 userdebug 版本可帮助开发者了解开发中版本的性能和功耗。为了让 user 版本和 userdebug 版本保持一致,并在用于调试的版本中获得可靠的指标,设备开发者应遵循以下准则:
- userdebug 定义为已启用 root 权限的 user 版本,以下情况除外:
- 仅由用户视需要运行且仅用于 userdebug 版本的应用
- 仅在空闲维护状态(连接充电器/充满电)下执行的操作,例如,使用 dex2oatd 与 dex2oat 比较后台编译情况
- 请勿使用任何依靠编译类型以在默认状态下启用/不启用的功能。建议开发者不要使用任何影响电池续航时间的日志记录形式(例如调试日志记录或堆转储)。
- 在 userdebug 版本中默认启用的任何调试功能都应明确定义,并告知负责该项目的所有开发者。请仅在限定时间里启用这些调试功能,直到问题得以解决。
利用资源叠加层定制版本
Android 编译系统会在编译时利用资源叠加层定制产品。资源叠加层用于指定在默认文件之上应用的资源文件。要使用资源叠加层,请修改项目编译文件,将 PRODUCT_PACKAGE_OVERLAYS 设为相对于顶级目录的路径。当编译系统搜索资源时,该路径会变为影子根目录,系统除了在当前根目录中进行搜索外,还会一并在该路径中进行搜索。
最常用的自定义设置包含在文件 frameworks/base/core/res/res/values/config.xml 中。
要在此文件上设置资源叠加层,请将叠加层目录添加到项目编译文件中,如下所示:
PRODUCT_PACKAGE_OVERLAYS := device/DEVICE_IMPLEMENTER/DEVICE_NAME/overlay
或
PRODUCT_PACKAGE_OVERLAYS := vendor/VENDOR_NAME/overlay
然后,将一个叠加层文件添加到该目录下,例如:
vendor/foobar/overlay/frameworks/base/core/res/res/config.xml
在叠加层 config.xml 文件中找到的所有字符串或字符串数组都将会替换在原始文件中找到的对应字符串或字符串数组。
设置 ANDROID_VENDOR_KEYS 以通过 USB 进行连接
借助 ANDROID_VENDOR_KEYS 环境变量,设备制造商可以通过 adb 访问正式版。为每个版本生成每台设备都可以接受的密钥并将其存储在内部(如存储在 vendor/oem-name/security/adb/),然后通过 ANDROID_VENDOR_KEYS 让 adb 使用这些规范密钥,而不是随机密钥。
使用 ANDROID_VENDOR_KEYS 环境变量指向生成的加密用 adb 公钥和私钥所在的目录。私钥存储在文件中。公钥存储在 file.pub 中。ANDROID_VENDOR_KEYS 环境变量指向存储生成的密钥对的文件或目录。
该变量被设为一个文件或目录,其中包含使用 adb keygen 文件命令生成的 2048 位 RSA 身份验证密钥对。 这些密钥对是对 ADB 服务器生成的 RSA 密钥对的补充。首次使用 adb 通过 USB 进行连接时,需要使用 RSA 密钥对。
您必须接受主机的 RSA 密钥,才能显式授予 adb 对设备的访问权限。默认情况下,ADB 服务器生成的密钥对以 adbkey(私钥)和 adbkey.pub(公钥)的形式存储在以下密钥存储库目录中:
在 MacOS 上,文件位置可能为:$HOME/.android。在 Windows 和 Linux 上,文件位置为:%USERPOFILE%.android。在 Windows 上,RSA 身份验证密钥在某些情况下也可能存储在 C:\Windows\System32\config\systemprofile.android 中。当 ADB 服务器需要密钥时,它会先搜索 ADB 服务器密钥存储库目录。如果找不到任何密钥,它会接着检查 ANDROID_VENDOR_KEYS 环境变量。如果还是找不到任何密钥,本地 ADB 服务器会生成一个新密钥对,并将其保存在 ADB 服务器密钥存储库目录中。
注意: 您可以通过设置 ANDROID_SDK_HOME 环境变量来替换 ADB 服务器存储 RSA 密钥的默认目录。在设备上,密钥存储在 /data/misc/adb/adb_keys/ 文件中,新的经过授权的密钥会在您接受它们后附加到同一个文件中。