Over-the-air (OTA) or Firmware Over-the-air (FOTA) are remote updates to the Android operating system (OS) running on a mobile device. Android devices connected to a network can receive and install OTA updates to the OS, application software, and time zone rules.
All components are involved in building an OTA system for Android 7.0 or newer devices via an approach known as seamless updates or A/B updates. It requires a frontend and backend component, and of course, the stack that runs on the devices.
Let’s briefly discuss Android device partitions before we dive into the technical implementation.
A Note on Android Device Partitions
Android OTA can range from a full OS upgrade to a much smaller change, such as a minor fix to a single device component. However, Android devices ALL have a partition-based structure which is necessary to support the open-source OS.
Android devices are composed of a flash storage that’s partitioned and formatted for different purposes. An OTA is sent to a device over the network in the form of a zip which consists of images that need to be flashed to device partitions.
Some of the most common partitions are:
These partitions are MUST for a device to be able to run Android of any form. But, they’re not necessarily the only partitions found on an Android device. Several device makers have added extra firmware-required partitions to the core set of five outlined above.
How OTA Works for Connected Android Devices
Partitions need to be flashed with the respective images that were shipped inside the zip, which means the zip must be extracted before images can be flashed on the device.
But, how is any of that possible when a device is up and running?
Installing updates to non-mobile operating systems such as Windows, Ubuntu, and macOS means a machine has to be put into update mode. Regular operations on a non-mobile OS are impossible until updates are complete. This was also the case with Android until Android 7.0 Nougat was released in 2016.
Prior to 7.0 Nougat, Android devices had to boot into recovery mode to install updates by extracting images from a zip file and installing images to device partitions. When updates were finished, the device then booted up into an upgraded OS.
But, things changed. With Android 7.0 Nougat, ‘seamless updates’ were introduced, which are also known as A/B updates.
Streaming A/B Updates for Android
A/B updates introduced a new way to install Android updates OTA. This approach involves two copies of each device partition, copy A and copy B. Android devices apply the update to a currently-unused partition when the system is running and idle.
A/B devices don’t need space to download an update package because they can apply the update as they read it from the network – or, stream updates. That’s why this OTA approach is called Streaming A/B.
Android 7.0 or newer devices that support A/B updates have two copies of each partition. These devices have a new partition scheme which typically involves:
Implementation Overview for A/B Android OTA
Here’s an overview of the implementation requirements for A/B Android OTA.
1. Device Implementation
The Android OS needs to be shipped with an updater which can check for updates by comparing a key. If an update is available, the updater will download the zip and perform a basic integrity check.
If integrity checks are passed, the device updater passes the zip to the update_engine. The update_engine is a system service enabled by default on devices to support A/B updates.
Along with the zip, a config needs to be processed by the device updater. The config contains the file names and offset of the files inside the zip. Typically, an A/B update zip contains only one file – payload.bin – which contains compressed images of all partitions.
A/B Android OTA updates can either be STREAMING or NON_STREAMING:
- STREAMING reads the contents of the zip over the network and applies changes to a powered-up device.
- NON_STREAMING involves downloading the zip before applying device updates.
There are no device mode requirements to apply A/B Android OTA updates. These updates are simply applied to the second slot of each device partition. Once the update is complete, a reboot will switch the Android device to the newly-updated partition slot.
The A/B method leaves room for Android to revert back to the previous OS if there is a failure or performance issues.
2. Backend Implementation
First, an API should work in the following fashion to check for updates:
- Device name
- Device ID
- Current OS version on the device
- Update channel
- The latest version of the OS available for that device. Device ID is useful to perform staged rollouts where certain Device IDs are exempted from the latest version.
- Link to an incremental zip which creates a bridge between the current OS version on the device and the latest device. If no incremental zip is available, then a link to a full zip file should be returned.
- Config details for the zip.
Here’s a Sample Config:
"name": "SAMPLE-cake-release BUILD-12345",
Second and last, an API should deploy the device update:
- Zip file
- Target Device Name
- OS Version Info
- Incremental OR Full zip status.
- If the zip is incremental, it should provide an incremental update from source version to the destination version. Multiple incremental zips can exist and must be uploaded.
- Incremental zips need to be provided for each version represented on devices, and when that’s not possible, it’s necessary to provide a full zip.
- Config details for each zip
- Update channel
- Sample Config
Questions about Android OTA or Esper’s custom Android OS version, Esper Enhanced Android? Click here to read Esper’s docs for developers.