Skip to content
Snippets Groups Projects
Commit c5ebf2a7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "SyncSM02: implement addState function" into main

parents 85c1247b 1d460b56
No related branches found
No related tags found
No related merge requests found
......@@ -18,11 +18,15 @@ package com.android.networkstack.tethering.util;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import com.android.internal.util.State;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* An implementation of a state machine, meant to be called synchronously.
......@@ -35,6 +39,7 @@ public class SyncStateMachine {
@NonNull private final String mName;
@NonNull private final Thread mMyThread;
private final boolean mDbg;
private final ArrayMap<State, StateInfo> mStateInfo = new ArrayMap<>();
// mCurrentState is the current state. mDestState is the target state that mCurrentState will
// transition to. The value of mDestState can be changed when a state processes a message and
......@@ -91,9 +96,9 @@ public class SyncStateMachine {
}
/**
* Add all of states to the state machine. Different StateInfos which have same state but have
* different parents are not allowed. A state can not have multiple parent states.
* This can only be called once either from mMyThread or before mMyThread started.
* Add all of states to the state machine. Different StateInfos which have same state are not
* allowed. In other words, a state can not have multiple parent states. #addAllStates can
* only be called once either from mMyThread or before mMyThread started.
*/
public final void addAllStates(@NonNull final List<StateInfo> stateInfos) {
ensureCorrectOrNotStartedThread();
......@@ -101,13 +106,39 @@ public class SyncStateMachine {
if (mCurrentState != null) {
throw new IllegalStateException("State only can be added before started");
}
if (stateInfos.isEmpty()) throw new IllegalStateException("Empty state is not allowed");
if (!mStateInfo.isEmpty()) throw new IllegalStateException("States are already configured");
final Set<Class> usedClasses = new ArraySet<>();
for (final StateInfo info : stateInfos) {
Objects.requireNonNull(info.state);
if (!usedClasses.add(info.state.getClass())) {
throw new IllegalStateException("Adding the same state multiple times in a state "
+ "machine is forbidden because it tends to be confusing; it can be done "
+ "with anonymous subclasses but consider carefully whether you want to "
+ "use a single state or other alternatives instead.");
}
mStateInfo.put(info.state, info);
}
// Check whether all of parent states indicated from StateInfo are added.
for (final StateInfo info : stateInfos) {
if (info.parent != null) ensureExistingState(info.parent);
}
}
/**
* Start the state machine. The initial state can't be child state.
*
* @param initialState the first state of this machine. The state must be exact state object
* setting up by {@link #addAllStates}, not a copy of it.
*/
public final void start(@NonNull final State initialState) {
ensureCorrectThread();
ensureExistingState(initialState);
mCurrentState = initialState;
mDestState = initialState;
......@@ -127,11 +158,13 @@ public class SyncStateMachine {
* This function can NOT be called inside the State enter and exit function. The transition
* target is always defined and can never be changed mid-way of state transition.
*
* @param destState will be the state to transition to.
* @param destState will be the state to transition to. The state must be the same instance set
* up by {@link #addAllStates}, not a copy of it.
*/
public final void transitionTo(@NonNull final State destState) {
if (mDbg) Log.d(mName, "transitionTo " + destState);
ensureCorrectThread();
ensureExistingState(destState);
if (mDestState == mCurrentState) {
mDestState = destState;
......@@ -151,4 +184,8 @@ public class SyncStateMachine {
ensureCorrectThread();
}
private void ensureExistingState(@NonNull final State state) {
if (!mStateInfo.containsKey(state)) throw new IllegalStateException("Invalid state");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment