diff options
7 files changed, 89 insertions, 20 deletions
diff --git a/updater_sample/README.md b/updater_sample/README.md index 8ec43d3c6..11b55eb91 100644 --- a/updater_sample/README.md +++ b/updater_sample/README.md @@ -140,6 +140,9 @@ Start an update attempt to download an apply the provided `payload_url` if no other update is running. The extra `key_value_pair_headers` will be included when fetching the payload. +`key_value_pair_headers` argument also accepts properties other than HTTP Headers. +List of allowed properties can be found in `system/update_engine/common/constants.cc`. + ### UpdateEngine#cancel Cancel the ongoing update. The update could be running or suspended, but it @@ -181,9 +184,8 @@ Called whenever an update attempt is completed. - [x] Deferred switch slot demo - [x] Add UpdateManager; extract update logic from MainActivity - [x] Add Sample app update state (separate from update_engine status) -- [-] Add smart update completion detection using onStatusUpdate -- [ ] Add pause/resume demo -- [ ] Add demo for passing NETWORK_ID to `UpdateEngine#applyPayload` +- [x] Add smart update completion detection using onStatusUpdate +- [x] Add pause/resume demo - [ ] Verify system partition checksum for package - [?] Add non-A/B updates demo diff --git a/updater_sample/res/layout/activity_main.xml b/updater_sample/res/layout/activity_main.xml index 7cde42cec..b560827d8 100644 --- a/updater_sample/res/layout/activity_main.xml +++ b/updater_sample/res/layout/activity_main.xml @@ -197,6 +197,29 @@ android:text="Reset" /> </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:orientation="horizontal"> + + <Button + android:id="@+id/buttonSuspend" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:onClick="onSuspendClick" + android:text="Suspend" /> + + <Button + android:id="@+id/buttonResume" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:onClick="onResumeClick" + android:text="Resume" /> + </LinearLayout> + <TextView android:id="@+id/textViewUpdateInfo" android:layout_width="wrap_content" diff --git a/updater_sample/src/com/example/android/systemupdatersample/UpdateManager.java b/updater_sample/src/com/example/android/systemupdatersample/UpdateManager.java index e4c09346b..a9783e70a 100644 --- a/updater_sample/src/com/example/android/systemupdatersample/UpdateManager.java +++ b/updater_sample/src/com/example/android/systemupdatersample/UpdateManager.java @@ -198,6 +198,24 @@ public class UpdateManager { } /** + * Suspend running update. + */ + public synchronized void suspend() throws UpdaterState.InvalidTransitionException { + Log.d(TAG, "suspend invoked"); + setUpdaterState(UpdaterState.PAUSED); + mUpdateEngine.cancel(); + } + + /** + * Resume suspended update. + */ + public synchronized void resume() throws UpdaterState.InvalidTransitionException { + Log.d(TAG, "resume invoked"); + setUpdaterState(UpdaterState.RUNNING); + updateEngineReApplyPayload(); + } + + /** * Updates {@link this.mState} and if state is changed, * it also notifies {@link this.mOnStateChangeCallback}. */ @@ -237,10 +255,6 @@ public class UpdateManager { /** * Requests update engine to stop any ongoing update. If an update has been applied, * leave it as is. - * - * <p>Sometimes it's possible that the - * update engine would throw an error when the method is called, and the only way to - * handle it is to catch the exception.</p> */ public synchronized void cancelRunningUpdate() throws UpdaterState.InvalidTransitionException { Log.d(TAG, "cancelRunningUpdate invoked"); @@ -250,10 +264,6 @@ public class UpdateManager { /** * Resets update engine to IDLE state. If an update has been applied it reverts it. - * - * <p>Sometimes it's possible that the - * update engine would throw an error when the method is called, and the only way to - * handle it is to catch the exception.</p> */ public synchronized void resetUpdate() throws UpdaterState.InvalidTransitionException { Log.d(TAG, "resetUpdate invoked"); @@ -506,7 +516,7 @@ public class UpdateManager { synchronizeUpdaterStateWithUpdateEngineStatus(); } - getOnProgressUpdateCallback().ifPresent(callback -> callback.accept(progress)); + getOnProgressUpdateCallback().ifPresent(callback -> callback.accept(mProgress.get())); if (previousStatus != status) { getOnEngineStatusUpdateCallback().ifPresent(callback -> callback.accept(status)); diff --git a/updater_sample/src/com/example/android/systemupdatersample/UpdaterState.java b/updater_sample/src/com/example/android/systemupdatersample/UpdaterState.java index 573d336e9..4eb0b68c7 100644 --- a/updater_sample/src/com/example/android/systemupdatersample/UpdaterState.java +++ b/updater_sample/src/com/example/android/systemupdatersample/UpdaterState.java @@ -52,12 +52,12 @@ public class UpdaterState { */ private static final ImmutableMap<Integer, ImmutableSet<Integer>> TRANSITIONS = ImmutableMap.<Integer, ImmutableSet<Integer>>builder() - .put(IDLE, ImmutableSet.of(ERROR, RUNNING)) + .put(IDLE, ImmutableSet.of(IDLE, ERROR, RUNNING)) + .put(ERROR, ImmutableSet.of(IDLE)) .put(RUNNING, ImmutableSet.of( - ERROR, PAUSED, REBOOT_REQUIRED, SLOT_SWITCH_REQUIRED)) + IDLE, ERROR, PAUSED, REBOOT_REQUIRED, SLOT_SWITCH_REQUIRED)) .put(PAUSED, ImmutableSet.of(ERROR, RUNNING, IDLE)) - .put(SLOT_SWITCH_REQUIRED, ImmutableSet.of(ERROR, IDLE)) - .put(ERROR, ImmutableSet.of(IDLE)) + .put(SLOT_SWITCH_REQUIRED, ImmutableSet.of(ERROR, REBOOT_REQUIRED, IDLE)) .put(REBOOT_REQUIRED, ImmutableSet.of(IDLE)) .build(); 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 6c71cb6f4..fc9fddd70 100644 --- a/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java +++ b/updater_sample/src/com/example/android/systemupdatersample/ui/MainActivity.java @@ -55,6 +55,8 @@ public class MainActivity extends Activity { private Button mButtonApplyConfig; private Button mButtonStop; private Button mButtonReset; + private Button mButtonSuspend; + private Button mButtonResume; private ProgressBar mProgressBar; private TextView mTextViewUpdaterState; private TextView mTextViewEngineStatus; @@ -79,6 +81,8 @@ public class MainActivity extends Activity { this.mButtonApplyConfig = findViewById(R.id.buttonApplyConfig); this.mButtonStop = findViewById(R.id.buttonStop); this.mButtonReset = findViewById(R.id.buttonReset); + this.mButtonSuspend = findViewById(R.id.buttonSuspend); + this.mButtonResume = findViewById(R.id.buttonResume); this.mProgressBar = findViewById(R.id.progressBar); this.mTextViewUpdaterState = findViewById(R.id.textViewUpdaterState); this.mTextViewEngineStatus = findViewById(R.id.textViewEngineStatus); @@ -209,9 +213,34 @@ public class MainActivity extends Activity { } /** + * suspend button clicked + */ + public void onSuspendClick(View view) { + try { + mUpdateManager.suspend(); + } catch (UpdaterState.InvalidTransitionException e) { + Log.e(TAG, "Failed to suspend running update", e); + } + } + + /** + * resume button clicked + */ + public void onResumeClick(View view) { + try { + uiResetWidgets(); + uiResetEngineText(); + mUpdateManager.resume(); + } catch (UpdaterState.InvalidTransitionException e) { + Log.e(TAG, "Failed to resume running update", e); + } + } + + /** * switch slot button clicked */ public void onSwitchSlotClick(View view) { + uiResetWidgets(); mUpdateManager.setSwitchSlotOnReboot(); } @@ -289,6 +318,8 @@ public class MainActivity extends Activity { mButtonApplyConfig.setEnabled(false); mButtonStop.setEnabled(false); mButtonReset.setEnabled(false); + mButtonSuspend.setEnabled(false); + mButtonResume.setEnabled(false); mProgressBar.setEnabled(false); mProgressBar.setVisibility(ProgressBar.INVISIBLE); mButtonSwitchSlot.setEnabled(false); @@ -303,6 +334,7 @@ public class MainActivity extends Activity { private void uiStateIdle() { uiResetWidgets(); + mButtonReset.setEnabled(true); mSpinnerConfigs.setEnabled(true); mButtonReload.setEnabled(true); mButtonApplyConfig.setEnabled(true); @@ -314,6 +346,7 @@ public class MainActivity extends Activity { mProgressBar.setEnabled(true); mProgressBar.setVisibility(ProgressBar.VISIBLE); mButtonStop.setEnabled(true); + mButtonSuspend.setEnabled(true); } private void uiStatePaused() { @@ -321,6 +354,7 @@ public class MainActivity extends Activity { mButtonReset.setEnabled(true); mProgressBar.setEnabled(true); mProgressBar.setVisibility(ProgressBar.VISIBLE); + mButtonResume.setEnabled(true); } private void uiStateSlotSwitchRequired() { diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java index 3ba84c116..03086930e 100644 --- a/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java +++ b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java @@ -65,7 +65,7 @@ public class PayloadSpecsTest { mTargetContext = InstrumentationRegistry.getTargetContext(); mTestContext = InstrumentationRegistry.getContext(); - mTestDir = mTargetContext.getFilesDir(); + mTestDir = mTargetContext.getCacheDir(); mPayloadSpecs = new PayloadSpecs(); } diff --git a/updater_sample/tools/gen_update_config.py b/updater_sample/tools/gen_update_config.py index 7fb64f7fc..b43e49df8 100755 --- a/updater_sample/tools/gen_update_config.py +++ b/updater_sample/tools/gen_update_config.py @@ -131,10 +131,10 @@ def main(): # pylint: disable=missing-docstring choices=ab_install_type_choices, help='A/B update installation type') parser.add_argument('--ab_force_switch_slot', - type=bool, default=False, - help='if set true device will boot to a new slot, otherwise user manually ' - 'switches slot on the screen') + action='store_true', + help='if set device will boot to a new slot, otherwise user ' + 'manually switches slot on the screen') parser.add_argument('package', type=str, help='OTA package zip file') |