Android OTA Update Client
The Android SDK includes a full OTA Update Client since version 3.7.0, which uses the Memfault Android OTA service to manage the OTA update process. This supports:
RecoverySystem
-based updates.- Update Engine-based updates (also known as A/B or Seamless updates).
- Checking for updates (both regularly in the background, and manually via the system Settings menu). Check interval can be configured dynamically on the Memfault dashboard.
- Downloading updates (and resuming interrupted downloads).
- UI notifications of available updates, and download progress.
- Incremental updates, referred to as Delta Releases in Memfault lingo.
In future updates, additional features will be supported:
- Further remote configuration of update behavior (e.g. headless update behavior, force-update policy).
OTA Update Client behavior
This behavior can be customized by modifying the bort-ota
application. More
behavior will be remotely configurable in future releases of the OTA Update
Client.
The OTA Update Client will periodically check for updates. By default, this happens every 12 hours. When an update is found, a notification is displayed.
The default behaviour is a fully user-in-the-loop update process. To download or install updates automatically without user intervention, see below.
A "Software Updates" system settings screen is added. Users can manually check for updates on this screen.
When an update is found, the notification will redirect users to the settings screen, where they can read release notes, download, and apply the update.
Update Check API
A broadcast Intent
API is available, to request that the OTA update client
checks for a new version (in addition to the regular scheduled checks). This can
be used either over adb, or from another app on the device which holds the
BORT_CONTROL_PERMISSION
. Replace your.bort.ota.app.id
with your Bort OTA
application ID.
Using the Bort CLI:
bort_cli.py ota-check --bort-ota-app-id your.bort.ota.app.id
Using adb
(by default this requires adb root
to gain the
com.memfault.bort.permission.CONTROL
permission):
adb shell am broadcast -a com.memfault.intent.action.OTA_CHECK_FOR_UPDATES -n your.bort.ota.app.id/com.memfault.bort.ota.lib.CheckForUpdatesReceiver
From another app:
Intent("com.memfault.intent.action.OTA_CHECK_FOR_UPDATES").apply {
component = ComponentName(
"your.bort.ota.app.id", // Whatever you have chosen for the Bort OTA application ID
"com.memfault.bort.ota.lib.CheckForUpdatesReceiver"
)
}.also {
context.sendBroadcast(it)
}
OTA Update Client architecture
The OTA Update Client is included in the Android SDK as a separate app and can be found on GitHub in the bort-ota project.
The OTA Update Client is optional, and will not be included in your system image if not required.
The bort-ota
app is designed to be customizable (for example, to customize the
notification UI). All customizations should be made within the bort-ota
project.
The bort-ota-lib
library project contains the core OTA logic, and is not
intended to be customized.
The OTA Update Client requires the main Bort application to be installed and running, in order to function correctly.
Enable OTA Update Client
Ensure that the Bort OTA application ID is set (see
Patch the SDK or
manually update BORT_OTA_APPLICATION_ID
in bort.properties
).
The OTA app also needs to be configured with a keystore. See Create a keystore for the OTA Update Client app.
Once the OTA application is configured, setting the TARGET_USES_MFLT_OTA
environment variable will include it in the system image. e.g.
export TARGET_USES_MFLT_OTA=1
Ensure this variable is set whenever you build the Android SDK.
After building and installing the system image, the Memfault OTA app will be active. A Release can now be activated in the Cohort containing this device.
Customizing the OTA Update Client
Applying OTA updates in the background
By default, the OTA Update Client will create a notification (see above) when an update is available - which requires user interaction before the update is installed.
From version 4.2.0, this behavior can be changed to automatically apply updates
in the background, by setting the OTA_AUTO_INSTALL
flag in bort.properties
:
OTA_AUTO_INSTALL=true
From version 4.8.0, additional customization options are available to configure exactly when an update will be downloaded and installed in the background.
Bort's periodic check for new updates was changed in 4.8.0 to remove storage/battery/unmetered network constraints. This means that the constraints to the download/install steps can be customized using the available OTA update metadata.
Configuring background download and install behavior.
If OTA_AUTO_INSTALL
flag is true
, once an update has been found then Bort
will use the configuration found in
AutoInstallRules.kt
to decide whether to download the update in the background (see
canAutoDownloadOtaUpdateNow
and downloadRules
), then once an update has been
downloaded, whether to install the update in the background (see
canAutoInstallOtaUpdateNow
and installRules
).
To customise this logic, make changes to AutoInstallRules.kt
before you
compile the Bort OTA app.
Bort will schedule JobScheduler
jobs for download/install based on the
constraints defined in downloadRules
/installrules
. When these jobs run (i.e.
when the constraints have been satisfied) the custom logic in
canAutoDownloadOtaUpdateNow
/canAutoInstallOtaUpdateNow
respectively will be
executed - the download or install will only take place when true
is returned.
Note: overrideNetworkConstraint
is null by default - this means that the
dashboard configuration (Settings / Data Sources / Allow OTA downloads
on Metered Networks) will take effect. Setting this to an explicit
NetworkType
will override the dashboard configuration.
An OTA
object is passed to both of these methods - this includes metadata
describing the OTA release which is available for download. This can be used in
the custom logic to determine e.g. the urgency of installing an update in the
background:
Property | Description |
---|---|
url | The URL used to download the update (provided for information only). |
version | The new version. |
releaseNotes | Release notes, as added with the CLI or in the dashboard. |
artifactMetadata | Memfault-internal metadata describing the OTA Artifact. |
releaseMetadata | Contains any custom metadata added when uploading the Artifact using the Memfault CLI using the --extra-metadata option. |
isDelta | Is the update a delta/incremental update? |
size | The size of the update image (bytes). |
String translations
The strings used in the various UI elements (notifications, check for updates
screen) are located in bort-ota/src/main/res/values/strings.xml
. You may want
to either customize, or translate these into other languages. See the
Android documentation for more information.
Updating the OTA Update Client
The OTA Update Client application can (just like the main Bort application) be updated using the Android package manager. If a device has an MDM capability, then this can be used to update the OTA apk in the future, without a full OS update.
It may still be necessary to update the OS for certain new features, if they required AOSP modifications.
Testing OTA updates
It is recommended to thoroughly test the entire OTA update process after integrating the OTA Update Client. This should always include testing the ability to update from any new OS version.
Troubleshooting
Ensure that the TARGET_USES_MFLT_OTA
environment variable is set in the
environments where both the gradle build, and AOSP build, take place.
Without this, the OTA app will not be included, or may not be correctly
configured.