Merge "updater_sample: add UpdaterState"

This commit is contained in:
Zhomart Mukhamejanov 2018-05-30 01:36:36 +00:00 committed by Gerrit Code Review
commit 721f6d851f
4 changed files with 128 additions and 68 deletions

View file

@ -25,7 +25,6 @@ import com.example.android.systemupdatersample.services.PrepareStreamingService;
import com.example.android.systemupdatersample.util.PayloadSpecs;
import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes;
import com.example.android.systemupdatersample.util.UpdateEngineProperties;
import com.example.android.systemupdatersample.util.UpdaterStates;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.AtomicDouble;
@ -59,7 +58,7 @@ public class UpdateManager {
new AtomicInteger(UpdateEngine.UpdateStatusConstants.IDLE);
private AtomicInteger mEngineErrorCode = new AtomicInteger(UpdateEngineErrorCodes.UNKNOWN);
private AtomicDouble mProgress = new AtomicDouble(0);
private AtomicInteger mState = new AtomicInteger(UpdaterStates.IDLE);
private UpdaterState mUpdaterState = new UpdaterState(UpdaterState.IDLE);
private AtomicBoolean mManualSwitchSlotRequired = new AtomicBoolean(true);
@ -111,7 +110,7 @@ public class UpdateManager {
/**
* Sets SystemUpdaterSample app state change callback. Value of {@code state} will be one
* of the values from {@link UpdaterStates}.
* of the values from {@link UpdaterState}.
*
* @param onStateChangeCallback a callback with parameter {@code state}.
*/
@ -193,8 +192,14 @@ public class UpdateManager {
* it also notifies {@link this.mOnStateChangeCallback}.
*/
private void setUpdaterState(int updaterState) {
int previousState = mState.get();
mState.set(updaterState);
int previousState = mUpdaterState.get();
try {
mUpdaterState.set(updaterState);
} catch (UpdaterState.InvalidTransitionException e) {
// Note: invalid state transitions should be handled properly,
// but to make sample app simple, we just throw runtime exception.
throw new RuntimeException("Can't set state " + updaterState, e);
}
if (previousState != updaterState) {
getOnStateChangeCallback().ifPresent(callback -> callback.accept(updaterState));
}
@ -211,7 +216,7 @@ public class UpdateManager {
public void cancelRunningUpdate() {
try {
mUpdateEngine.cancel();
setUpdaterState(UpdaterStates.IDLE);
setUpdaterState(UpdaterState.IDLE);
} catch (Exception e) {
Log.w(TAG, "UpdateEngine failed to stop the ongoing update", e);
}
@ -227,7 +232,7 @@ public class UpdateManager {
public void resetUpdate() {
try {
mUpdateEngine.resetStatus();
setUpdaterState(UpdaterStates.IDLE);
setUpdaterState(UpdaterState.IDLE);
} catch (Exception e) {
Log.w(TAG, "UpdateEngine failed to reset the update", e);
}
@ -241,7 +246,7 @@ public class UpdateManager {
*/
public void applyUpdate(Context context, UpdateConfig config) {
mEngineErrorCode.set(UpdateEngineErrorCodes.UNKNOWN);
setUpdaterState(UpdaterStates.RUNNING);
setUpdaterState(UpdaterState.RUNNING);
synchronized (mLock) {
// Cleaning up previous update data.
@ -269,7 +274,7 @@ public class UpdateManager {
builder.setPayload(mPayloadSpecs.forNonStreaming(config.getUpdatePackageFile()));
} catch (IOException e) {
Log.e(TAG, "Error creating payload spec", e);
setUpdaterState(UpdaterStates.ERROR);
setUpdaterState(UpdaterState.ERROR);
return;
}
updateEngineApplyPayload(builder.build());
@ -290,7 +295,7 @@ public class UpdateManager {
updateEngineApplyPayload(builder.build());
} else {
Log.e(TAG, "PrepareStreamingService failed, result code is " + code);
setUpdaterState(UpdaterStates.ERROR);
setUpdaterState(UpdaterState.ERROR);
}
});
}
@ -332,7 +337,7 @@ public class UpdateManager {
properties.toArray(new String[0]));
} catch (Exception e) {
Log.e(TAG, "UpdateEngine failed to apply the update", e);
setUpdaterState(UpdaterStates.ERROR);
setUpdaterState(UpdaterState.ERROR);
}
}
@ -396,9 +401,11 @@ public class UpdateManager {
mEngineErrorCode.set(errorCode);
if (errorCode == UpdateEngine.ErrorCodeConstants.SUCCESS
|| errorCode == UpdateEngineErrorCodes.UPDATED_BUT_NOT_ACTIVE) {
setUpdaterState(UpdaterStates.FINISHED);
setUpdaterState(isManualSwitchSlotRequired()
? UpdaterState.SLOT_SWITCH_REQUIRED
: UpdaterState.REBOOT_REQUIRED);
} else if (errorCode != UpdateEngineErrorCodes.USER_CANCELLED) {
setUpdaterState(UpdaterStates.ERROR);
setUpdaterState(UpdaterState.ERROR);
}
getOnEngineCompleteCallback()

View file

@ -0,0 +1,103 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.systemupdatersample;
import android.util.SparseArray;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Controls updater state.
*/
public class UpdaterState {
public static final int IDLE = 0;
public static final int ERROR = 1;
public static final int RUNNING = 2;
public static final int PAUSED = 3;
public static final int SLOT_SWITCH_REQUIRED = 4;
public static final int REBOOT_REQUIRED = 5;
private static final SparseArray<String> STATE_MAP = new SparseArray<>();
static {
STATE_MAP.put(0, "IDLE");
STATE_MAP.put(1, "ERROR");
STATE_MAP.put(2, "RUNNING");
STATE_MAP.put(3, "PAUSED");
STATE_MAP.put(4, "SLOT_SWITCH_REQUIRED");
STATE_MAP.put(5, "REBOOT_REQUIRED");
}
/**
* Allowed state transitions. It's a map: key is a state, value is a set of states that
* are allowed to transition to from key.
*/
private static final ImmutableMap<Integer, ImmutableSet<Integer>> TRANSITIONS =
ImmutableMap.of(
IDLE, ImmutableSet.of(RUNNING),
RUNNING, ImmutableSet.of(ERROR, PAUSED, REBOOT_REQUIRED, SLOT_SWITCH_REQUIRED),
PAUSED, ImmutableSet.of(RUNNING),
SLOT_SWITCH_REQUIRED, ImmutableSet.of(ERROR)
);
private AtomicInteger mState;
public UpdaterState(int state) {
this.mState = new AtomicInteger(state);
}
/**
* Returns updater state.
*/
public int get() {
return mState.get();
}
/**
* Sets the updater state.
*
* @throws InvalidTransitionException if transition is not allowed.
*/
public void set(int newState) throws InvalidTransitionException {
int oldState = mState.get();
if (!TRANSITIONS.get(oldState).contains(newState)) {
throw new InvalidTransitionException(
"Can't transition from " + oldState + " to " + newState);
}
mState.set(newState);
}
/**
* Converts status code to status name.
*/
public static String getStateText(int state) {
return STATE_MAP.get(state);
}
/**
* Defines invalid state transition exception.
*/
public static class InvalidTransitionException extends Exception {
public InvalidTransitionException(String msg) {
super(msg);
}
}
}

View file

@ -33,11 +33,11 @@ import android.widget.TextView;
import com.example.android.systemupdatersample.R;
import com.example.android.systemupdatersample.UpdateConfig;
import com.example.android.systemupdatersample.UpdateManager;
import com.example.android.systemupdatersample.UpdaterState;
import com.example.android.systemupdatersample.util.PayloadSpecs;
import com.example.android.systemupdatersample.util.UpdateConfigs;
import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes;
import com.example.android.systemupdatersample.util.UpdateEngineStatuses;
import com.example.android.systemupdatersample.util.UpdaterStates;
import java.util.List;
@ -192,7 +192,7 @@ public class MainActivity extends Activity {
/**
* Invoked when SystemUpdaterSample app state changes.
* Value of {@code state} will be one of the
* values from {@link UpdaterStates}.
* values from {@link UpdaterState}.
*/
private void onUpdaterStateChange(int state) {
Log.i(TAG, "onUpdaterStateChange invoked state=" + state);
@ -233,8 +233,8 @@ public class MainActivity extends Activity {
runOnUiThread(() -> {
Log.i(TAG,
"Completed - errorCode="
+ UpdateEngineErrorCodes.getCodeName(errorCode) + "/" + errorCode
+ " " + completionState);
+ UpdateEngineErrorCodes.getCodeName(errorCode) + "/" + errorCode
+ " " + completionState);
setUiEngineErrorCode(errorCode);
if (errorCode == UpdateEngineErrorCodes.UPDATED_BUT_NOT_ACTIVE) {
// if update was successfully applied.
@ -323,7 +323,7 @@ public class MainActivity extends Activity {
* @param state updater sample state
*/
private void setUiUpdaterState(int state) {
String stateText = UpdaterStates.getStateText(state);
String stateText = UpdaterState.getStateText(state);
mTextViewUpdaterState.setText(stateText + "/" + state);
}

View file

@ -1,50 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.systemupdatersample.util;
import android.util.SparseArray;
/**
* SystemUpdaterSample app state.
*/
public class UpdaterStates {
public static final int IDLE = 0;
public static final int ERROR = 1;
public static final int RUNNING = 2;
public static final int PAUSED = 3;
public static final int FINISHED = 4;
private static final SparseArray<String> STATE_MAP = new SparseArray<>();
static {
STATE_MAP.put(0, "IDLE");
STATE_MAP.put(1, "ERROR");
STATE_MAP.put(2, "RUNNING");
STATE_MAP.put(3, "PAUSED");
STATE_MAP.put(4, "FINISHED");
}
/**
* converts status code to status name
*/
public static String getStateText(int state) {
return STATE_MAP.get(state);
}
private UpdaterStates() {}
}