OTA Ready: Developing a Robust Over-the-Air Update Strategy for Custom Android Things Builds
While Google officially sunsetted Android Things for new commercial projects, its underlying architecture, based on AOSP, remains a powerful foundation for custom IoT devices. For manufacturers deploying these custom Android Things builds, a robust Over-the-Air (OTA) update strategy isn’t just a feature; it’s a critical operational necessity. This guide delves into developing such a strategy, focusing on custom OS image creation and deployment.
Why OTA Updates Are Crucial for IoT Devices
IoT devices often operate in remote, hard-to-reach locations. Manual updates are costly, time-consuming, and impractical at scale. OTA updates enable:
- Security Patches: Addressing vulnerabilities promptly to protect devices and user data.
- Bug Fixes: Resolving software issues without physical interaction.
- Feature Enhancements: Adding new capabilities to extend device lifespan and value.
- Compliance: Meeting regulatory requirements and certifications through software updates.
Without a reliable OTA mechanism, your custom Android Things deployment becomes a static, high-maintenance burden.
Understanding the Android Things Update Mechanism
Android Things leveraged the standard Android update mechanism, which is fundamentally built around A/B (seamless) system updates. This approach minimizes downtime during updates and provides a fallback in case of failure. Key components include:
- Update Engine: A userspace component responsible for applying updates.
- A/B Partitions: The device has two sets of system partitions (A and B). While one set is active, the other can be updated in the background.
- Boot Control: Manages which partition set to boot from.
When an update is initiated, the new image is written to the inactive partition set. Upon reboot, the device attempts to boot from the newly updated partition. If successful, it becomes the active partition. If it fails, the device can fall back to the previously working partition.
Preparing Your Custom Android Things Build for OTA
The journey to OTA readiness begins at the build system level. You need to ensure your custom Android Things OS image is configured correctly to generate and accept OTA packages.
1. Source Code Setup
Start with a relevant AOSP branch that matches your hardware’s support or a fork of the Android Things repository if you started there. Ensure your device-specific `device/vendor/your-company/your-device` directory is set up.
2. Device Configuration for A/B Updates
Your device’s `device.mk` (or an included `.mk` file) must enable A/B updates. This typically involves setting certain build flags. Here’s an example of essential configurations:
# device/vendor/your-company/your-device/device.mk
# Enable A/B updates
AB_OTA_UPDATER := true
# Define A/B update groups (e.g., system, vendor, product)
AB_OTA_PARTITIONS :=
system
vendor
product
# Required for A/B updates and boot control HAL
PRODUCT_PACKAGES +=
update_engine
update_engine_sideload
boot_control.your_device_hal
# Include A/B update specific properties
PRODUCT_PROPERTY_OVERRIDES +=
ro.boot.dynamic_partitions=true
ro.ota.allow_downgrade=false
# Ensure bootloader and other critical partitions are configured correctly
# This varies significantly by SoC and board. Consult your board's documentation.
The `boot_control.your_device_hal` is critical. This is a hardware abstraction layer (HAL) that your bootloader must implement to allow the Android Update Engine to switch active partitions. If your SoC vendor provides an AOSP-compliant Board Support Package (BSP), this HAL might already be available.
3. Secure Signing Keys
All OTA packages must be cryptographically signed. This prevents unauthorized or malicious updates. Google uses its own private keys for official Android builds. For custom builds, you MUST generate and manage your own set of release keys. Never use the default AOSP test keys (`build/target/product/security/testkey`) for production devices.
To generate new keys:
subject='/C=US/ST=CA/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
for x in releasekey platform shared media; do
./development/tools/make_key ${x} "${subject}";
done
These keys (`.pk8` and `.x509.pem` files) should be kept extremely secure. You’ll reference them in your `build/target/product/your_device_product.mk` or similar:
# product.mk
PRODUCT_DEFAULT_DEV_CERTIFICATE := vendor/your-company/your-device/security/releasekey
Building an OTA Package
Once your source code is ready, building an OTA package is straightforward using the AOSP build system.
1. Full OTA Package Generation
A full OTA package contains the complete system image and can be used to update any device to the specified build version. This is typically used for major version upgrades or initial deployment.
source build/envsetup.sh
lunch your_device-userdebug # or your_device-user
m otapackage
This command generates a `your_device-ota-BUILD_ID.zip` file in your `out/target/product/your_device` directory. This ZIP file is a complete, signed OTA package.
2. Incremental OTA Package Generation
Incremental OTAs are much smaller as they only contain the changes between two specific build versions. They are preferred for minor updates to save bandwidth and installation time.
To build an incremental OTA, you need the previous build’s OTA package or the path to its `target_files` ZIP:
source build/envsetup.sh
lunch your_device-userdebug
# Make sure your current build is the NEWER one
# Path to the target_files.zip of the OLDER build
OLD_TARGET_FILES=out/target/product/your_device/full_target_files_OLD_BUILD.zip
# Path to the target_files.zip of the NEWER (current) build
NEW_TARGET_FILES=out/target/product/your_device/full_target_files_NEW_BUILD.zip
# Build the incremental package
./build/tools/releasetools/ota_from_target_files
-i $OLD_TARGET_FILES
$NEW_TARGET_FILES
incremental_ota_package.zip
Implementing a Custom OTA Server
Since Google’s Android Things Console is no longer active, you’ll need to host your own OTA server. This typically involves a simple web server to serve OTA packages and a backend service to manage device registration, update manifests, and rollouts.
1. Server Architecture Overview
A basic setup might involve:
- Web Server (e.g., Nginx, Apache): To host the `.zip` OTA files.
- Database (e.g., PostgreSQL, MongoDB): To store device information, update manifests, and release details.
- API Backend (e.g., Node.js, Python/Django, Java/Spring): To serve update requests from devices and manage the database.
2. Update Manifest Structure
Devices will query your API for available updates. The API should respond with an update manifest, typically a JSON object, containing details about the latest available update. This allows devices to determine if an update is applicable to them.
{
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →