1*e7c364b6SAndroid Build Coastguard Worker# SystemUpdaterSample 2*e7c364b6SAndroid Build Coastguard Worker 3*e7c364b6SAndroid Build Coastguard WorkerThis app demonstrates how to use Android system updates APIs to install 4*e7c364b6SAndroid Build Coastguard Worker[OTA updates](https://source.android.com/devices/tech/ota/). It contains a 5*e7c364b6SAndroid Build Coastguard Workersample client for `update_engine` to install A/B (seamless) updates. 6*e7c364b6SAndroid Build Coastguard Worker 7*e7c364b6SAndroid Build Coastguard WorkerA/B (seamless) update is available since Android Nougat (API 24), but this sample 8*e7c364b6SAndroid Build Coastguard Workertargets the latest android. 9*e7c364b6SAndroid Build Coastguard Worker 10*e7c364b6SAndroid Build Coastguard Worker 11*e7c364b6SAndroid Build Coastguard Worker## Workflow 12*e7c364b6SAndroid Build Coastguard Worker 13*e7c364b6SAndroid Build Coastguard WorkerSystemUpdaterSample app shows list of available updates on the UI. User is allowed 14*e7c364b6SAndroid Build Coastguard Workerto select an update and apply it to the device. App shows installation progress, 15*e7c364b6SAndroid Build Coastguard Workerlogs can be found in `adb logcat`. User can stop or reset an update. Resetting 16*e7c364b6SAndroid Build Coastguard Workerthe update requests update engine to cancel any ongoing update, and revert 17*e7c364b6SAndroid Build Coastguard Workerif the update has been applied. Stopping does not revert the applied update. 18*e7c364b6SAndroid Build Coastguard Worker 19*e7c364b6SAndroid Build Coastguard Worker 20*e7c364b6SAndroid Build Coastguard Worker## Update Config file 21*e7c364b6SAndroid Build Coastguard Worker 22*e7c364b6SAndroid Build Coastguard WorkerIn this sample updates are defined in JSON update config files. 23*e7c364b6SAndroid Build Coastguard WorkerThe structure of a config file is defined in 24*e7c364b6SAndroid Build Coastguard Worker`com.example.android.systemupdatersample.UpdateConfig`, example file is located 25*e7c364b6SAndroid Build Coastguard Workerat `res/raw/sample.json`. 26*e7c364b6SAndroid Build Coastguard Worker 27*e7c364b6SAndroid Build Coastguard WorkerIn real-life update system the config files expected to be served from a server 28*e7c364b6SAndroid Build Coastguard Workerto the app, but in this sample, the config files are stored on the device. 29*e7c364b6SAndroid Build Coastguard WorkerThe directory can be found in logs or on the UI. In most cases it should be located at 30*e7c364b6SAndroid Build Coastguard Worker`/data/user/0/com.example.android.systemupdatersample/files/configs/`. 31*e7c364b6SAndroid Build Coastguard Worker 32*e7c364b6SAndroid Build Coastguard WorkerSystemUpdaterSample app downloads OTA package from `url`. In this sample app 33*e7c364b6SAndroid Build Coastguard Worker`url` is expected to point to file system, e.g. `file:///data/my-sample-ota-builds-dir/ota-002.zip`. 34*e7c364b6SAndroid Build Coastguard Worker 35*e7c364b6SAndroid Build Coastguard WorkerIf `ab_install_type` is `NON_STREAMING` then app checks if `url` starts 36*e7c364b6SAndroid Build Coastguard Workerwith `file://` and passes `url` to the `update_engine`. 37*e7c364b6SAndroid Build Coastguard Worker 38*e7c364b6SAndroid Build Coastguard WorkerIf `ab_install_type` is `STREAMING`, app downloads only the entries in need, as 39*e7c364b6SAndroid Build Coastguard Workeropposed to the entire package, to initiate a streaming update. The `payload.bin` 40*e7c364b6SAndroid Build Coastguard Workerentry, which takes up the majority of the space in an OTA package, will be 41*e7c364b6SAndroid Build Coastguard Workerstreamed by `update_engine` directly. The ZIP entries in such a package need to be 42*e7c364b6SAndroid Build Coastguard Workersaved uncompressed (`ZIP_STORED`), so that their data can be downloaded directly 43*e7c364b6SAndroid Build Coastguard Workerwith the offset and length. As `payload.bin` itself is already in compressed 44*e7c364b6SAndroid Build Coastguard Workerformat, the size penalty is marginal. 45*e7c364b6SAndroid Build Coastguard Worker 46*e7c364b6SAndroid Build Coastguard Workerif `ab_config.force_switch_slot` set true device will boot to the 47*e7c364b6SAndroid Build Coastguard Workerupdated partition on next reboot; otherwise button "Switch Slot" will 48*e7c364b6SAndroid Build Coastguard Workerbecome active, and user can manually set updated partition as the active slot. 49*e7c364b6SAndroid Build Coastguard Worker 50*e7c364b6SAndroid Build Coastguard WorkerConfig files can be generated using `tools/gen_update_config.py`. 51*e7c364b6SAndroid Build Coastguard WorkerRunning `./tools/gen_update_config.py --help` shows usage of the script. 52*e7c364b6SAndroid Build Coastguard Worker 53*e7c364b6SAndroid Build Coastguard Worker 54*e7c364b6SAndroid Build Coastguard Worker## Sample App State vs UpdateEngine Status 55*e7c364b6SAndroid Build Coastguard Worker 56*e7c364b6SAndroid Build Coastguard WorkerUpdateEngine provides status for different stages of update application 57*e7c364b6SAndroid Build Coastguard Workerprocess. But it lacks of proper status codes when update fails. 58*e7c364b6SAndroid Build Coastguard Worker 59*e7c364b6SAndroid Build Coastguard WorkerThis creates two problems: 60*e7c364b6SAndroid Build Coastguard Worker 61*e7c364b6SAndroid Build Coastguard Worker1. If sample app is unbound from update_engine (MainActivity is paused, destroyed), 62*e7c364b6SAndroid Build Coastguard Worker app doesn't receive onStatusUpdate and onPayloadApplicationCompleted notifications. 63*e7c364b6SAndroid Build Coastguard Worker If app binds to update_engine after update is completed, 64*e7c364b6SAndroid Build Coastguard Worker only onStatusUpdate is called, but status becomes IDLE in most cases. 65*e7c364b6SAndroid Build Coastguard Worker And there is no way to know if update was successful or not. 66*e7c364b6SAndroid Build Coastguard Worker 67*e7c364b6SAndroid Build Coastguard Worker2. This sample app demostrates suspend/resume using update_engins's 68*e7c364b6SAndroid Build Coastguard Worker `cancel` and `applyPayload` (which picks up from where it left). 69*e7c364b6SAndroid Build Coastguard Worker When `cancel` is called, status is set to `IDLE`, which doesn't allow 70*e7c364b6SAndroid Build Coastguard Worker tracking suspended state properly. 71*e7c364b6SAndroid Build Coastguard Worker 72*e7c364b6SAndroid Build Coastguard WorkerTo solve these problems sample app implements its own separate update 73*e7c364b6SAndroid Build Coastguard Workerstate - `UpdaterState`. To solve the first problem, sample app persists 74*e7c364b6SAndroid Build Coastguard Worker`UpdaterState` on a device. When app is resumed, it checks if `UpdaterState` 75*e7c364b6SAndroid Build Coastguard Workermatches the update_engine's status (as onStatusUpdate is guaranteed to be called). 76*e7c364b6SAndroid Build Coastguard WorkerIf they doesn't match, sample app calls `applyPayload` again with the same 77*e7c364b6SAndroid Build Coastguard Workerparameters, and handles update completion properly using `onPayloadApplicationCompleted` 78*e7c364b6SAndroid Build Coastguard Workercallback. The second problem is solved by adding `PAUSED` updater state. 79*e7c364b6SAndroid Build Coastguard Worker 80*e7c364b6SAndroid Build Coastguard Worker 81*e7c364b6SAndroid Build Coastguard Worker## Sample App UI 82*e7c364b6SAndroid Build Coastguard Worker 83*e7c364b6SAndroid Build Coastguard Worker### Text fields 84*e7c364b6SAndroid Build Coastguard Worker 85*e7c364b6SAndroid Build Coastguard Worker- `Current Build:` - shows current active build. 86*e7c364b6SAndroid Build Coastguard Worker- `Updater state:` - SystemUpdaterSample app state. 87*e7c364b6SAndroid Build Coastguard Worker- `Engine status:` - last reported update_engine status. 88*e7c364b6SAndroid Build Coastguard Worker- `Engine error:` - last reported payload application error. 89*e7c364b6SAndroid Build Coastguard Worker 90*e7c364b6SAndroid Build Coastguard Worker### Buttons 91*e7c364b6SAndroid Build Coastguard Worker 92*e7c364b6SAndroid Build Coastguard Worker- `Reload` - reloads update configs from device storage. 93*e7c364b6SAndroid Build Coastguard Worker- `View config` - shows selected update config. 94*e7c364b6SAndroid Build Coastguard Worker- `Apply` - applies selected update config. 95*e7c364b6SAndroid Build Coastguard Worker- `Stop` - cancel running update, calls `UpdateEngine#cancel`. 96*e7c364b6SAndroid Build Coastguard Worker- `Reset` - reset update, calls `UpdateEngine#resetStatus`, can be called 97*e7c364b6SAndroid Build Coastguard Worker only when update is not running. 98*e7c364b6SAndroid Build Coastguard Worker- `Suspend` - suspend running update, uses `UpdateEngine#cancel`. 99*e7c364b6SAndroid Build Coastguard Worker- `Resume` - resumes suspended update, uses `UpdateEngine#applyPayload`. 100*e7c364b6SAndroid Build Coastguard Worker- `Switch Slot` - if `ab_config.force_switch_slot` config set true, 101*e7c364b6SAndroid Build Coastguard Worker this button will be enabled after payload is applied, 102*e7c364b6SAndroid Build Coastguard Worker to switch A/B slot on next reboot. 103*e7c364b6SAndroid Build Coastguard Worker 104*e7c364b6SAndroid Build Coastguard Worker 105*e7c364b6SAndroid Build Coastguard Worker## Sending HTTP headers from UpdateEngine 106*e7c364b6SAndroid Build Coastguard Worker 107*e7c364b6SAndroid Build Coastguard WorkerSometimes OTA package server might require some HTTP headers to be present, 108*e7c364b6SAndroid Build Coastguard Workere.g. `Authorization` header to contain valid auth token. While performing 109*e7c364b6SAndroid Build Coastguard Workerstreaming update, `UpdateEngine` allows passing on certain HTTP headers; 110*e7c364b6SAndroid Build Coastguard Workeras of writing this sample app, these headers are `Authorization` and `User-Agent`. 111*e7c364b6SAndroid Build Coastguard Worker 112*e7c364b6SAndroid Build Coastguard Worker`android.os.UpdateEngine#applyPayload` contains information on 113*e7c364b6SAndroid Build Coastguard Workerwhich HTTP headers are supported. 114*e7c364b6SAndroid Build Coastguard Worker 115*e7c364b6SAndroid Build Coastguard Worker 116*e7c364b6SAndroid Build Coastguard Worker## Used update_engine APIs 117*e7c364b6SAndroid Build Coastguard Worker 118*e7c364b6SAndroid Build Coastguard Worker### UpdateEngine#bind 119*e7c364b6SAndroid Build Coastguard Worker 120*e7c364b6SAndroid Build Coastguard WorkerBinds given callbacks to update_engine. When update_engine successfully 121*e7c364b6SAndroid Build Coastguard Workerinitialized, it's guaranteed to invoke callback onStatusUpdate. 122*e7c364b6SAndroid Build Coastguard Worker 123*e7c364b6SAndroid Build Coastguard Worker### UpdateEngine#applyPayload 124*e7c364b6SAndroid Build Coastguard Worker 125*e7c364b6SAndroid Build Coastguard WorkerStart an update attempt to download an apply the provided `payload_url` if 126*e7c364b6SAndroid Build Coastguard Workerno other update is running. The extra `key_value_pair_headers` will be 127*e7c364b6SAndroid Build Coastguard Workerincluded when fetching the payload. 128*e7c364b6SAndroid Build Coastguard Worker 129*e7c364b6SAndroid Build Coastguard Worker`key_value_pair_headers` argument also accepts properties other than HTTP Headers. 130*e7c364b6SAndroid Build Coastguard WorkerList of allowed properties can be found in `system/update_engine/common/constants.cc`. 131*e7c364b6SAndroid Build Coastguard Worker 132*e7c364b6SAndroid Build Coastguard Worker### UpdateEngine#cancel 133*e7c364b6SAndroid Build Coastguard Worker 134*e7c364b6SAndroid Build Coastguard WorkerCancel the ongoing update. The update could be running or suspended, but it 135*e7c364b6SAndroid Build Coastguard Workercan't be canceled after it was done. 136*e7c364b6SAndroid Build Coastguard Worker 137*e7c364b6SAndroid Build Coastguard Worker### UpdateEngine#resetStatus 138*e7c364b6SAndroid Build Coastguard Worker 139*e7c364b6SAndroid Build Coastguard WorkerReset the already applied update back to an idle state. This method can 140*e7c364b6SAndroid Build Coastguard Workeronly be called when no update attempt is going on, and it will reset the 141*e7c364b6SAndroid Build Coastguard Workerstatus back to idle, deleting the currently applied update if any. 142*e7c364b6SAndroid Build Coastguard Worker 143*e7c364b6SAndroid Build Coastguard Worker### Callback: onStatusUpdate 144*e7c364b6SAndroid Build Coastguard Worker 145*e7c364b6SAndroid Build Coastguard WorkerCalled whenever the value of `status` or `progress` changes. For 146*e7c364b6SAndroid Build Coastguard Worker`progress` values changes, this method will be called only if it changes significantly. 147*e7c364b6SAndroid Build Coastguard WorkerAt this time of writing this doc, delta for `progress` is `0.005`. 148*e7c364b6SAndroid Build Coastguard Worker 149*e7c364b6SAndroid Build Coastguard Worker`onStatusUpdate` is always called when app binds to update_engine, 150*e7c364b6SAndroid Build Coastguard Workerexcept when update_engine fails to initialize. 151*e7c364b6SAndroid Build Coastguard Worker 152*e7c364b6SAndroid Build Coastguard Worker### Callback: onPayloadApplicationComplete 153*e7c364b6SAndroid Build Coastguard Worker 154*e7c364b6SAndroid Build Coastguard WorkerCalled whenever an update attempt is completed or failed. 155*e7c364b6SAndroid Build Coastguard Worker 156*e7c364b6SAndroid Build Coastguard Worker 157*e7c364b6SAndroid Build Coastguard Worker## Running on a device 158*e7c364b6SAndroid Build Coastguard Worker 159*e7c364b6SAndroid Build Coastguard WorkerThe commands are expected to be run from `$ANDROID_BUILD_TOP` and for demo 160*e7c364b6SAndroid Build Coastguard Workerpurpose only. 161*e7c364b6SAndroid Build Coastguard Worker 162*e7c364b6SAndroid Build Coastguard Worker### Without the privileged system permissions 163*e7c364b6SAndroid Build Coastguard Worker 164*e7c364b6SAndroid Build Coastguard Worker1. Compile the app `mmma -j bootable/recovery/updater_sample`. 165*e7c364b6SAndroid Build Coastguard Worker2. Install the app to the device using `adb install <APK_PATH>`. 166*e7c364b6SAndroid Build Coastguard Worker3. Change permissions on `/data/ota_package/` to `0777` on the device. 167*e7c364b6SAndroid Build Coastguard Worker4. Set SELinux mode to permissive. See instructions below. 168*e7c364b6SAndroid Build Coastguard Worker5. Add update config files; look above at [Update Config file](#Update-Config-file). 169*e7c364b6SAndroid Build Coastguard Worker6. Push OTA packages to the device. 170*e7c364b6SAndroid Build Coastguard Worker7. Run the sample app. 171*e7c364b6SAndroid Build Coastguard Worker 172*e7c364b6SAndroid Build Coastguard Worker### With the privileged system permissions 173*e7c364b6SAndroid Build Coastguard Worker 174*e7c364b6SAndroid Build Coastguard WorkerTo run sample app as a privileged system app, it needs to be installed in `/system/priv-app/`. 175*e7c364b6SAndroid Build Coastguard WorkerThis directory is expected to be read-only, unless explicitly remounted. 176*e7c364b6SAndroid Build Coastguard Worker 177*e7c364b6SAndroid Build Coastguard WorkerThe recommended way to run the app is to build and install it as a 178*e7c364b6SAndroid Build Coastguard Workerprivileged system app, so it's granted the required permissions to access 179*e7c364b6SAndroid Build Coastguard Worker`update_engine` service as well as OTA package files. Detailed steps are as follows: 180*e7c364b6SAndroid Build Coastguard Worker 181*e7c364b6SAndroid Build Coastguard Worker1. [Prepare to build](https://source.android.com/setup/build/building) 182*e7c364b6SAndroid Build Coastguard Worker2. Add the module (SystemUpdaterSample) to the `PRODUCT_PACKAGES` list for the 183*e7c364b6SAndroid Build Coastguard Worker lunch target. 184*e7c364b6SAndroid Build Coastguard Worker e.g. add a line containing `PRODUCT_PACKAGES += SystemUpdaterSample` 185*e7c364b6SAndroid Build Coastguard Worker to `device/google/marlin/device-common.mk`. 186*e7c364b6SAndroid Build Coastguard Worker3. [Whitelist the sample app](https://source.android.com/devices/tech/config/perms-whitelist) 187*e7c364b6SAndroid Build Coastguard Worker * Add 188*e7c364b6SAndroid Build Coastguard Worker ``` 189*e7c364b6SAndroid Build Coastguard Worker <privapp-permissions package="com.example.android.systemupdatersample"> 190*e7c364b6SAndroid Build Coastguard Worker <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/> 191*e7c364b6SAndroid Build Coastguard Worker </privapp-permissions> 192*e7c364b6SAndroid Build Coastguard Worker ``` 193*e7c364b6SAndroid Build Coastguard Worker to `frameworks/base/data/etc/privapp-permissions-platform.xml` 194*e7c364b6SAndroid Build Coastguard Worker4. Add `privileged: true` to SystemUpdaterSample 195*e7c364b6SAndroid Build Coastguard Worker [building rule](https://android.googlesource.com/platform/bootable/recovery/+/refs/heads/master/updater_sample/Android.bp). 196*e7c364b6SAndroid Build Coastguard Worker5. Build sample app `make -j SystemUpdaterSample`. 197*e7c364b6SAndroid Build Coastguard Worker6. Build Android `make -j` 198*e7c364b6SAndroid Build Coastguard Worker7. [Flash the device](https://source.android.com/setup/build/running) 199*e7c364b6SAndroid Build Coastguard Worker8. Add update config files; look above at `## Update Config file`; 200*e7c364b6SAndroid Build Coastguard Worker `adb root` might be required. 201*e7c364b6SAndroid Build Coastguard Worker9. Push OTA packages to the device if there is no server to stream packages from; 202*e7c364b6SAndroid Build Coastguard Worker changing of SELinux labels of OTA packages directory might be required 203*e7c364b6SAndroid Build Coastguard Worker `chcon -R u:object_r:ota_package_file:s0 /data/my-sample-ota-builds-dir` 204*e7c364b6SAndroid Build Coastguard Worker10. Run the sample app. 205*e7c364b6SAndroid Build Coastguard Worker 206*e7c364b6SAndroid Build Coastguard Worker 207*e7c364b6SAndroid Build Coastguard Worker## Development 208*e7c364b6SAndroid Build Coastguard Worker 209*e7c364b6SAndroid Build Coastguard Worker- [x] Create a UI with list of configs, current version, 210*e7c364b6SAndroid Build Coastguard Worker control buttons, progress bar and log viewer 211*e7c364b6SAndroid Build Coastguard Worker- [x] Add `PayloadSpec` and `PayloadSpecs` for working with 212*e7c364b6SAndroid Build Coastguard Worker update zip file 213*e7c364b6SAndroid Build Coastguard Worker- [x] Add `UpdateConfig` for working with json config files 214*e7c364b6SAndroid Build Coastguard Worker- [x] Add applying non-streaming update 215*e7c364b6SAndroid Build Coastguard Worker- [x] Prepare streaming update (partially downloading package) 216*e7c364b6SAndroid Build Coastguard Worker- [x] Add applying streaming update 217*e7c364b6SAndroid Build Coastguard Worker- [x] Add stop/reset the update 218*e7c364b6SAndroid Build Coastguard Worker- [x] Add demo for passing HTTP headers to `UpdateEngine#applyPayload` 219*e7c364b6SAndroid Build Coastguard Worker- [x] [Package compatibility check](https://source.android.com/devices/architecture/vintf/match-rules) 220*e7c364b6SAndroid Build Coastguard Worker- [x] Deferred switch slot demo 221*e7c364b6SAndroid Build Coastguard Worker- [x] Add UpdateManager; extract update logic from MainActivity 222*e7c364b6SAndroid Build Coastguard Worker- [x] Add Sample app update state (separate from update_engine status) 223*e7c364b6SAndroid Build Coastguard Worker- [x] Add smart update completion detection using onStatusUpdate 224*e7c364b6SAndroid Build Coastguard Worker- [x] Add pause/resume demo 225*e7c364b6SAndroid Build Coastguard Worker- [x] Verify system partition checksum for package 226*e7c364b6SAndroid Build Coastguard Worker 227*e7c364b6SAndroid Build Coastguard Worker 228*e7c364b6SAndroid Build Coastguard Worker## Running tests 229*e7c364b6SAndroid Build Coastguard Worker 230*e7c364b6SAndroid Build Coastguard WorkerThe commands are expected to be run from `$ANDROID_BUILD_TOP`. 231*e7c364b6SAndroid Build Coastguard Worker 232*e7c364b6SAndroid Build Coastguard Worker1. Build `make -j SystemUpdaterSample` and `make -j SystemUpdaterSampleTests`. 233*e7c364b6SAndroid Build Coastguard Worker2. Install app 234*e7c364b6SAndroid Build Coastguard Worker `adb install $OUT/system/app/SystemUpdaterSample/SystemUpdaterSample.apk` 235*e7c364b6SAndroid Build Coastguard Worker3. Install tests 236*e7c364b6SAndroid Build Coastguard Worker `adb install $OUT/testcases/SystemUpdaterSampleTests/arm64/SystemUpdaterSampleTests.apk` 237*e7c364b6SAndroid Build Coastguard Worker4. Run tests 238*e7c364b6SAndroid Build Coastguard Worker `adb shell am instrument -w com.example.android.systemupdatersample.tests/android.support.test.runner.AndroidJUnitRunner` 239*e7c364b6SAndroid Build Coastguard Worker5. Run a test file 240*e7c364b6SAndroid Build Coastguard Worker ``` 241*e7c364b6SAndroid Build Coastguard Worker adb shell am instrument \ 242*e7c364b6SAndroid Build Coastguard Worker -w -e class com.example.android.systemupdatersample.UpdateManagerTest#applyUpdate_appliesPayloadToUpdateEngine \ 243*e7c364b6SAndroid Build Coastguard Worker com.example.android.systemupdatersample.tests/android.support.test.runner.AndroidJUnitRunner 244*e7c364b6SAndroid Build Coastguard Worker ``` 245*e7c364b6SAndroid Build Coastguard Worker 246*e7c364b6SAndroid Build Coastguard Worker 247*e7c364b6SAndroid Build Coastguard Worker## Accessing `android.os.UpdateEngine` API 248*e7c364b6SAndroid Build Coastguard Worker 249*e7c364b6SAndroid Build Coastguard Worker`android.os.UpdateEngine` APIs are marked as `@SystemApi`, meaning only system 250*e7c364b6SAndroid Build Coastguard Workerapps can access them. 251*e7c364b6SAndroid Build Coastguard Worker 252*e7c364b6SAndroid Build Coastguard Worker 253*e7c364b6SAndroid Build Coastguard Worker## Getting read/write access to `/data/ota_package/` 254*e7c364b6SAndroid Build Coastguard Worker 255*e7c364b6SAndroid Build Coastguard WorkerAccess to cache filesystem is granted only to system apps. 256*e7c364b6SAndroid Build Coastguard Worker 257*e7c364b6SAndroid Build Coastguard Worker 258*e7c364b6SAndroid Build Coastguard Worker## Setting SELinux mode to permissive (0) 259*e7c364b6SAndroid Build Coastguard Worker 260*e7c364b6SAndroid Build Coastguard Worker```txt 261*e7c364b6SAndroid Build Coastguard Workerlocal$ adb root 262*e7c364b6SAndroid Build Coastguard Workerlocal$ adb shell 263*e7c364b6SAndroid Build Coastguard Workerandroid# setenforce 0 264*e7c364b6SAndroid Build Coastguard Workerandroid# getenforce 265*e7c364b6SAndroid Build Coastguard Worker``` 266*e7c364b6SAndroid Build Coastguard Worker 267*e7c364b6SAndroid Build Coastguard Worker 268*e7c364b6SAndroid Build Coastguard Worker## License 269*e7c364b6SAndroid Build Coastguard Worker 270*e7c364b6SAndroid Build Coastguard WorkerSystemUpdaterSample app is released under 271*e7c364b6SAndroid Build Coastguard Worker[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). 272