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 <zhomart@google.com>
This commit is contained in:
parent
daa86e9024
commit
6aa5fb0bbe
4 changed files with 51 additions and 13 deletions
|
@ -61,6 +61,17 @@ purpose only.
|
||||||
6. Push OTA packages to the device.
|
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
|
## Development
|
||||||
|
|
||||||
- [x] Create a UI with list of configs, current version,
|
- [x] Create a UI with list of configs, current version,
|
||||||
|
@ -72,12 +83,12 @@ purpose only.
|
||||||
- [x] Prepare streaming update (partially downloading package)
|
- [x] Prepare streaming update (partially downloading package)
|
||||||
- [x] Add applying streaming update
|
- [x] Add applying streaming update
|
||||||
- [x] Add stop/reset the update
|
- [x] Add stop/reset the update
|
||||||
|
- [x] Add demo for passing HTTP headers to `UpdateEngine#applyPayload`
|
||||||
- [ ] Add tests for `MainActivity`
|
- [ ] Add tests for `MainActivity`
|
||||||
- [ ] Verify system partition checksum for package
|
|
||||||
- [ ] HAL compatibility check
|
- [ ] HAL compatibility check
|
||||||
- [ ] Change partition demo
|
- [ ] Change partition demo
|
||||||
|
- [ ] Verify system partition checksum for package
|
||||||
- [ ] Add non-A/B updates demo
|
- [ ] Add non-A/B updates demo
|
||||||
- [ ] Add docs for passing HTTP headers to `UpdateEngine#applyPayload`
|
|
||||||
|
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"ab_streaming_metadata": {
|
"ab_streaming_metadata": {
|
||||||
"__": "streaming_metadata is required only for streaming update",
|
"__": "streaming_metadata is required only for streaming update",
|
||||||
"__property_files": "name, offset and size of files",
|
"__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": [
|
"property_files": [
|
||||||
{
|
{
|
||||||
"__filename": "name of the file in package",
|
"__filename": "name of the file in package",
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
"offset": 531,
|
"offset": 531,
|
||||||
"size": 5012323
|
"size": 5012323
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"authorization": "Basic my-secret-token"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An update description. It will be parsed from JSON, which is intended to
|
* 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("offset"),
|
||||||
p.getLong("size"));
|
p.getLong("size"));
|
||||||
}
|
}
|
||||||
c.mAbStreamingMetadata = new StreamingMetadata(propertyFiles);
|
c.mAbStreamingMetadata = new StreamingMetadata(
|
||||||
|
propertyFiles,
|
||||||
|
meta.getString("authorization_token"));
|
||||||
}
|
}
|
||||||
c.mRawJson = json;
|
c.mRawJson = json;
|
||||||
return c;
|
return c;
|
||||||
|
@ -178,17 +181,23 @@ public class UpdateConfig implements Parcelable {
|
||||||
/** defines beginning of update data in archive */
|
/** defines beginning of update data in archive */
|
||||||
private PackageFile[] mPropertyFiles;
|
private PackageFile[] mPropertyFiles;
|
||||||
|
|
||||||
public StreamingMetadata() {
|
/** SystemUpdaterSample receives the authorization token from the OTA server, in addition
|
||||||
mPropertyFiles = new PackageFile[0];
|
* 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.mPropertyFiles = propertyFiles;
|
||||||
|
this.mAuthorization = authorization;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PackageFile[] getPropertyFiles() {
|
public PackageFile[] getPropertyFiles() {
|
||||||
return mPropertyFiles;
|
return mPropertyFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<String> getAuthorization() {
|
||||||
|
return Optional.of(mAuthorization);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,7 +233,6 @@ public class UpdateConfig implements Parcelable {
|
||||||
public long getSize() {
|
public long getSize() {
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes;
|
||||||
import com.example.android.systemupdatersample.util.UpdateEngineStatuses;
|
import com.example.android.systemupdatersample.util.UpdateEngineStatuses;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@ -51,6 +52,10 @@ public class MainActivity extends Activity {
|
||||||
|
|
||||||
private static final String TAG = "MainActivity";
|
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 TextView mTextViewBuild;
|
||||||
private Spinner mSpinnerConfigs;
|
private Spinner mSpinnerConfigs;
|
||||||
private TextView mTextViewConfigsDirHint;
|
private TextView mTextViewConfigsDirHint;
|
||||||
|
@ -295,12 +300,17 @@ public class MainActivity extends Activity {
|
||||||
.show();
|
.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateEngineApplyPayload(payload);
|
updateEngineApplyPayload(payload, null);
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Starting PrepareStreamingService");
|
Log.d(TAG, "Starting PrepareStreamingService");
|
||||||
PrepareStreamingService.startService(this, config, (code, payloadSpec) -> {
|
PrepareStreamingService.startService(this, config, (code, payloadSpec) -> {
|
||||||
if (code == PrepareStreamingService.RESULT_CODE_SUCCESS) {
|
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 {
|
} else {
|
||||||
Log.e(TAG, "PrepareStreamingService failed, result code is " + code);
|
Log.e(TAG, "PrepareStreamingService failed, result code is " + code);
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
@ -317,14 +327,21 @@ public class MainActivity extends Activity {
|
||||||
*
|
*
|
||||||
* UpdateEngine works asynchronously. This method doesn't wait until
|
* UpdateEngine works asynchronously. This method doesn't wait until
|
||||||
* end of the update.
|
* 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 {
|
try {
|
||||||
mUpdateEngine.applyPayload(
|
mUpdateEngine.applyPayload(
|
||||||
payloadSpec.getUrl(),
|
payloadSpec.getUrl(),
|
||||||
payloadSpec.getOffset(),
|
payloadSpec.getOffset(),
|
||||||
payloadSpec.getSize(),
|
payloadSpec.getSize(),
|
||||||
payloadSpec.getProperties().toArray(new String[0]));
|
properties.toArray(new String[0]));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "UpdateEngine failed to apply the update", e);
|
Log.e(TAG, "UpdateEngine failed to apply the update", e);
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
|
Loading…
Reference in a new issue