Merge "updater_sample: add http header demo"
am: fe5b3e2b2d
Change-Id: I5f76d9f27d69fcdbe4f95194b34bad548f7e28e2
diff --git a/updater_sample/README.md b/updater_sample/README.md
index 2c1f0ce..7e25b07 100644
--- a/updater_sample/README.md
+++ b/updater_sample/README.md
@@ -61,6 +61,17 @@
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 @@
- [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 b6f4cdc..7ac8ffa 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 1851724..b08bfd0 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 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 @@
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 @@
/** 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<String> getAuthorization() {
+ return Optional.of(mAuthorization);
+ }
}
/**
@@ -224,7 +233,6 @@
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 359e2b1..1708256 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.UpdateEngineStatuses;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -51,6 +52,10 @@
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 @@
.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<String> 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 @@
*
* 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<String> extraProperties) {
+ ArrayList<String> 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(