Add New Product in AOSP Source Tree
Building on the foundation of our previous discussions about compiling Android’s built-in products for verification, we now shift our focus to the process of adding our own products. Adding a new product allows you to customise the Android system for your specific device and use case, and that it also enables you to contribute to the open source community by sharing your product with other developers.
Adding a new product to the Android Open Source Project (AOSP) source code can be a daunting task, but it doesn’t have to be. In this article, we’ll guide you through the process of creating your own product step by step. Generally speaking, a product has four elements:
- AndroidProducts.mk: This file specifies the product configuration and outlines crucial details like the built-in software modules defined by PRODUCT_MAKEFILES in AndroidProducts.mk.
- BoardConfig.mk: This file contains hardware-related configurations, encompassing elements such as chip hardware settings and partition configurations. It’s pivotal for tailoring your product’s hardware requirements.
- Product.mk: This file encapsulates instructions pertaining to software modules and complements the definitions found in AndroidProducts.mk i.e. it contains software-related configuration of a product, such as which built-in software modules are specified by PRODUCT_MAKEFILES in AndroidProducts.mk.
- Vendorsetup.sh: Historically significant, this file used to play a key role in adding products to the lunch selections. However, with the advent of Android 10, the functions once housed in vendorsetup.sh have been migrated to AndroidProducts.mk, making it obsolete for modern product additions.
Below I refer to the aosp_x86_64 product to create our own product step by step.
- Device directory
- New Board level config
- New Product Config
- Android Product config
1. Create device directory:
As mentioned earlier, a product encompasses four essential components, each with its designated place within the Android system. These four elements find their home in two distinct directories: the ‘device’ directory for manufacturers’ product configurations and the ‘build/target’ directory for Google’s official built-in AOSP products.
In the ‘build/target’ directory, you’ll discover AndroidProducts.mk and product.mk, while ‘build/target/board’ houses BoardConfig.mk, among others.
My focus is on adding a product to the ‘device’ directory, and we’ll begin by creating this directory structure:
mkdir -p device/[company]/[device]
For example, if you want to create a new product for the company "Android Champ" and device "Sample" then
mkdir -p device/AndroidChamp/Sample
Please note that this pertains to the ‘device’ directory, not the ‘product’ directory. To grasp the distinction, consider ‘device’ as the domain for hardware-related chip platform-level configuration, and ‘product’ as the arena for software-related configuration. It’s worth highlighting that multiple products can coexist under a single device, allowing for diverse software modules to be integrated into the same hardware board. This arrangement underscores the flexibility and versatility of Android’s product configurations, accommodating a wide array of hardware and software customisation.
2. Create a new board-level configuration BoardConfig.mk
Within the Android system, the BoardConfig.mk file plays a pivotal role, encompassing hardware chip architecture configurations, partition size settings, and other essential information.
To streamline the process, you can directly incorporate the BoardConfig.mk from the aosp_x86_64 product:
include $(SRC_TARGET_DIR)/board/generic_x86_64/BoardConfig.mk
This straightforward approach simplifies the hardware configuration aspect and ensures compatibility with the aosp_x86_64 product, making it accessible and comprehensible for all.
You need to change the values of variables such as TARGET_ARCH, TARGET_CPU_ABI, BOARD_KERNEL_CMDLINE, BOARD_SYSTEMIMAGE_PARTITION_SIZE, etc.
3. Create a new product configuration sample.mk
We streamline our product configuration process by directly inheriting the settings from the aosp_x86_64 product while making some necessary adjustments:
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_x86_64.mk)
// inherits the product configuration from the aosp_x86_64 product, which is a generic x86_64 emulator image.
# Customize product-specific variables
PRODUCT_NAME := Demo
PRODUCT_DEVICE := sample
Here, two vital variables come into play, namely PRODUCT_NAME and `PRODUCT_DEVICE. These variables require our manual intervention for customization:
- PRODUCT_NAME must align with the name of the configuration file. This variable plays a pivotal role in determining the output directory for our compilation.
- PRODUCT_DEVICE is closely tied to BoardConfig.mk. The compilation system utilises this variable to load the corresponding BoardConfig.mk file from the designated directory based on
$
PRODUCT_DEVICE. setting. It’s a way to make sure everything works together the way we want.
4. Create new AndroidProducts.mk
In Android, there’s a variable called PRODUCT_MAKEFILES defined in AndroidProducts.mk. This variable lists the configuration files of the product you added in the previous steps. For this example, we have one configuration file named sample.mk.
In Android 10, there’s another variable called COMMON_LUNCH_CHOICE. It essentially takes over the role of vendorsetup.sh, a file used in older versions.
Here’s what the code looks like:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/sample.mk
COMMON_LUNCH_CHOICES := \
demo-eng
This code makes it simple for us to choose the product when building Android. It adds an option called “demo-eng” to the lunch menu. In this case:
- “demo” is the name of the product.
- “eng” stands for the engineering version, which includes all modules, allows for debugging, and runs with full system access (ROOT state).
- Other versions like “userdebug” are for debugging without ROOT access, and “user” is the final version released to users with debugging and ROOT access turned off.
5. Compilation verification
Now, having configured the simplest product, your directory structure appears as follows:
androidchamp
└── sample
├── AndroidProducts.mk
├── BoardConfig.mk
└── sample.mk
With everything in place, it’s time to compile and test your configuration on a virtual machine. Should any issues arise, it’s essential to carefully review the previous steps to identify and resolve potential problems.
You can execute the following commands to compile and run your customised Android product on an emulator:
source build/envsetup.sh
lunch demo-eng
make -j
emulator
These commands facilitate the building and testing of your unique Android product using an emulator. If you encounter challenges, be sure to revisit the earlier steps to ensure a correct setup.
6. Conclusion
With this guide, you’ve learned how to add a new product to the AOSP source tree, enhancing the flexibility and adaptability of the Android source code for your specific requirements.
Now, you’re well-equipped to explore further and tailor Android to your unique needs. Happy coding!