From 6aa5fb0bbe8d074208648593d177553e732e6d9d Mon Sep 17 00:00:00 2001 From: Zhomart Mukhamejanov Date: Wed, 9 May 2018 14:28:49 -0700 Subject: updater_sample: add http header demo Added demo passing http headers to UpdateEngine#applyPayload. Bug: 79483768 Test: manually Change-Id: I3e9c812dba2066acadbcea8d07c933368806e20c Signed-off-by: Zhomart Mukhamejanov --- updater_sample/README.md | 15 +++++++++++-- updater_sample/res/raw/sample.json | 4 +++- .../android/systemupdatersample/UpdateConfig.java | 20 +++++++++++------ .../systemupdatersample/ui/MainActivity.java | 25 ++++++++++++++++++---- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/updater_sample/README.md b/updater_sample/README.md index 2c1f0ced5..7e25b070c 100644 --- a/updater_sample/README.md +++ b/updater_sample/README.md @@ -61,6 +61,17 @@ purpose only. 6. Push OTA packages to the device. +## Sending HTTP headers from UpdateEngine + +Sometimes OTA package server might require some HTTP headers to be present, +e.g. `Authorization` header to contain valid auth token. While performing +streaming update, `UpdateEngine` allows passing on certain HTTP headers; +as of writing this sample app, these headers are `Authorization` and `User-Agent`. + +`android.os.UpdateEngine#applyPayload` contains information on +which HTTP headers are supported. + + ## Development - [x] Create a UI with list of configs, current version, @@ -72,12 +83,12 @@ purpose only. - [x] Prepare streaming update (partially downloading package) - [x] Add applying streaming update - [x] Add stop/reset the update +- [x] Add demo for passing HTTP headers to `UpdateEngine#applyPayload` - [ ] Add tests for `MainActivity` -- [ ] Verify system partition checksum for package - [ ] HAL compatibility check - [ ] Change partition demo +- [ ] Verify system partition checksum for package - [ ] Add non-A/B updates demo -- [ ] Add docs for passing HTTP headers to `UpdateEngine#applyPayload` ## Running tests diff --git a/updater_sample/res/raw/sample.json b/updater_sample/res/raw/sample.json index b6f4cdce6..7ac8ffab7 100644 --- a/updater_sample/res/raw/sample.json +++ b/updater_sample/res/raw/sample.json @@ -8,6 +8,7 @@ "ab_streaming_metadata": { "__": "streaming_metadata is required only for streaming update", "__property_files": "name, offset and size of files", + "__authorization": "it will be sent to OTA package server as value of HTTP header - Authorization", "property_files": [ { "__filename": "name of the file in package", @@ -17,6 +18,7 @@ "offset": 531, "size": 5012323 } - ] + ], + "authorization": "Basic my-secret-token" } } diff --git a/updater_sample/src/com/example/android/systemupdatersample/UpdateConfig.java b/updater_sample/src/com/example/android/systemupdatersample/UpdateConfig.java index 1851724ed..b08bfd0f6 100644 --- a/updater_sample/src/com/example/android/systemupdatersample/UpdateConfig.java +++ b/updater_sample/src/com/example/android/systemupdatersample/UpdateConfig.java @@ -25,6 +25,7 @@ import org.json.JSONObject; import java.io.File; import java.io.Serializable; +import java.util.Optional; /** * An update description. It will be parsed from JSON, which is intended to @@ -78,7 +79,9 @@ public class UpdateConfig implements Parcelable { p.getLong("offset"), p.getLong("size")); } - c.mAbStreamingMetadata = new StreamingMetadata(propertyFiles); + c.mAbStreamingMetadata = new StreamingMetadata( + propertyFiles, + meta.getString("authorization_token")); } c.mRawJson = json; return c; @@ -178,17 +181,23 @@ public class UpdateConfig implements Parcelable { /** defines beginning of update data in archive */ private PackageFile[] mPropertyFiles; - public StreamingMetadata() { - mPropertyFiles = new PackageFile[0]; - } + /** SystemUpdaterSample receives the authorization token from the OTA server, in addition + * to the package URL. It passes on the info to update_engine, so that the latter can + * fetch the data from the package server directly with the token. */ + private String mAuthorization; - public StreamingMetadata(PackageFile[] propertyFiles) { + public StreamingMetadata(PackageFile[] propertyFiles, String authorization) { this.mPropertyFiles = propertyFiles; + this.mAuthorization = authorization; } public PackageFile[] getPropertyFiles() { return mPropertyFiles; } + + public Optional getAuthorization() { + return Optional.of(mAuthorization); + } } /** @@ -224,7 +233,6 @@ public class UpdateConfig implements Parcelable { public long getSize() { return mSize; } - } } diff --git a/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java b/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java index 359e2b10c..170825635 100644 --- a/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java +++ b/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java @@ -41,6 +41,7 @@ import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes; import com.example.android.systemupdatersample.util.UpdateEngineStatuses; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -51,6 +52,10 @@ public class MainActivity extends Activity { private static final String TAG = "MainActivity"; + /** HTTP Header: User-Agent; it will be sent to the server when streaming the payload. */ + private static final String HTTP_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"; + private TextView mTextViewBuild; private Spinner mSpinnerConfigs; private TextView mTextViewConfigsDirHint; @@ -295,12 +300,17 @@ public class MainActivity extends Activity { .show(); return; } - updateEngineApplyPayload(payload); + updateEngineApplyPayload(payload, null); } else { Log.d(TAG, "Starting PrepareStreamingService"); PrepareStreamingService.startService(this, config, (code, payloadSpec) -> { if (code == PrepareStreamingService.RESULT_CODE_SUCCESS) { - updateEngineApplyPayload(payloadSpec); + List extraProperties = new ArrayList<>(); + extraProperties.add("USER_AGENT=" + HTTP_USER_AGENT); + config.getStreamingMetadata() + .getAuthorization() + .ifPresent(s -> extraProperties.add("AUTHORIZATION=" + s)); + updateEngineApplyPayload(payloadSpec, extraProperties); } else { Log.e(TAG, "PrepareStreamingService failed, result code is " + code); Toast.makeText( @@ -317,14 +327,21 @@ public class MainActivity extends Activity { * * UpdateEngine works asynchronously. This method doesn't wait until * end of the update. + * + * @param payloadSpec contains url, offset and size to {@code PAYLOAD_BINARY_FILE_NAME} + * @param extraProperties additional properties to pass to {@link UpdateEngine#applyPayload} */ - private void updateEngineApplyPayload(PayloadSpec payloadSpec) { + private void updateEngineApplyPayload(PayloadSpec payloadSpec, List extraProperties) { + ArrayList properties = new ArrayList<>(payloadSpec.getProperties()); + if (extraProperties != null) { + properties.addAll(extraProperties); + } try { mUpdateEngine.applyPayload( payloadSpec.getUrl(), payloadSpec.getOffset(), payloadSpec.getSize(), - payloadSpec.getProperties().toArray(new String[0])); + properties.toArray(new String[0])); } catch (Exception e) { Log.e(TAG, "UpdateEngine failed to apply the update", e); Toast.makeText( -- cgit v1.2.3