Merge "Add base states with exception catching and utility functions"
This commit is contained in:
@@ -123,7 +123,7 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
private static final String DISCONNECT_REASON_UNDERLYING_NETWORK_LOST =
|
private static final String DISCONNECT_REASON_UNDERLYING_NETWORK_LOST =
|
||||||
"Underlying Network lost";
|
"Underlying Network lost";
|
||||||
private static final String DISCONNECT_REASON_TEARDOWN = "teardown() called on VcnTunnel";
|
private static final String DISCONNECT_REASON_TEARDOWN = "teardown() called on VcnTunnel";
|
||||||
private static final int TOKEN_ANY = Integer.MIN_VALUE;
|
private static final int TOKEN_ALL = Integer.MIN_VALUE;
|
||||||
|
|
||||||
private static final int NETWORK_LOSS_DISCONNECT_TIMEOUT_SECONDS = 30;
|
private static final int NETWORK_LOSS_DISCONNECT_TIMEOUT_SECONDS = 30;
|
||||||
private static final int TEARDOWN_TIMEOUT_SECONDS = 5;
|
private static final int TEARDOWN_TIMEOUT_SECONDS = 5;
|
||||||
@@ -139,7 +139,7 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
*
|
*
|
||||||
* <p>In the Connected state, this MAY indicate a mobility even occurred.
|
* <p>In the Connected state, this MAY indicate a mobility even occurred.
|
||||||
*
|
*
|
||||||
* @param arg1 The "any" token; this event is always applicable.
|
* @param arg1 The "all" token; this event is always applicable.
|
||||||
* @param obj @NonNull An EventUnderlyingNetworkChangedInfo instance with relevant data.
|
* @param obj @NonNull An EventUnderlyingNetworkChangedInfo instance with relevant data.
|
||||||
*/
|
*/
|
||||||
private static final int EVENT_UNDERLYING_NETWORK_CHANGED = 1;
|
private static final int EVENT_UNDERLYING_NETWORK_CHANGED = 1;
|
||||||
@@ -175,7 +175,7 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
* <p>Upon receipt of this signal, the state machine will transition from the Retry-timeout
|
* <p>Upon receipt of this signal, the state machine will transition from the Retry-timeout
|
||||||
* state to the Connecting state.
|
* state to the Connecting state.
|
||||||
*
|
*
|
||||||
* @param arg1 The "any" token; no sessions are active in the RetryTimeoutState.
|
* @param arg1 The "all" token; no sessions are active in the RetryTimeoutState.
|
||||||
*/
|
*/
|
||||||
private static final int EVENT_RETRY_TIMEOUT_EXPIRED = 2;
|
private static final int EVENT_RETRY_TIMEOUT_EXPIRED = 2;
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
* <p>Upon receipt of this signal, the state machine MUST tear down all active sessions, cancel
|
* <p>Upon receipt of this signal, the state machine MUST tear down all active sessions, cancel
|
||||||
* any pending work items, and move to the Disconnected state.
|
* any pending work items, and move to the Disconnected state.
|
||||||
*
|
*
|
||||||
* @param arg1 The "any" token; this signal is always honored.
|
* @param arg1 The "all" token; this signal is always honored.
|
||||||
* @param obj @NonNull An EventDisconnectRequestedInfo instance with relevant data.
|
* @param obj @NonNull An EventDisconnectRequestedInfo instance with relevant data.
|
||||||
*/
|
*/
|
||||||
private static final int EVENT_DISCONNECT_REQUESTED = 7;
|
private static final int EVENT_DISCONNECT_REQUESTED = 7;
|
||||||
@@ -504,16 +504,9 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
* <p>Once torn down, this VcnTunnel CANNOT be started again.
|
* <p>Once torn down, this VcnTunnel CANNOT be started again.
|
||||||
*/
|
*/
|
||||||
public void teardownAsynchronously() {
|
public void teardownAsynchronously() {
|
||||||
mUnderlyingNetworkTracker.teardown();
|
|
||||||
|
|
||||||
// No need to call setInterfaceDown(); the IpSecInterface is being fully torn down.
|
|
||||||
if (mTunnelIface != null) {
|
|
||||||
mTunnelIface.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessage(
|
sendMessage(
|
||||||
EVENT_DISCONNECT_REQUESTED,
|
EVENT_DISCONNECT_REQUESTED,
|
||||||
TOKEN_ANY,
|
TOKEN_ALL,
|
||||||
new EventDisconnectRequestedInfo(DISCONNECT_REASON_TEARDOWN));
|
new EventDisconnectRequestedInfo(DISCONNECT_REASON_TEARDOWN));
|
||||||
quit();
|
quit();
|
||||||
|
|
||||||
@@ -521,6 +514,16 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
// is also called asynchronously when a NetworkAgent becomes unwanted
|
// is also called asynchronously when a NetworkAgent becomes unwanted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onQuitting() {
|
||||||
|
// No need to call setInterfaceDown(); the IpSecInterface is being fully torn down.
|
||||||
|
if (mTunnelIface != null) {
|
||||||
|
mTunnelIface.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
mUnderlyingNetworkTracker.teardown();
|
||||||
|
}
|
||||||
|
|
||||||
private class VcnUnderlyingNetworkTrackerCallback implements UnderlyingNetworkTrackerCallback {
|
private class VcnUnderlyingNetworkTrackerCallback implements UnderlyingNetworkTrackerCallback {
|
||||||
@Override
|
@Override
|
||||||
public void onSelectedUnderlyingNetworkChanged(
|
public void onSelectedUnderlyingNetworkChanged(
|
||||||
@@ -530,26 +533,24 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
if (underlying == null) {
|
if (underlying == null) {
|
||||||
sendMessageDelayed(
|
sendMessageDelayed(
|
||||||
EVENT_DISCONNECT_REQUESTED,
|
EVENT_DISCONNECT_REQUESTED,
|
||||||
TOKEN_ANY,
|
TOKEN_ALL,
|
||||||
new EventDisconnectRequestedInfo(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST),
|
new EventDisconnectRequestedInfo(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST),
|
||||||
TimeUnit.SECONDS.toMillis(NETWORK_LOSS_DISCONNECT_TIMEOUT_SECONDS));
|
TimeUnit.SECONDS.toMillis(NETWORK_LOSS_DISCONNECT_TIMEOUT_SECONDS));
|
||||||
return;
|
} else if (getHandler() != null) {
|
||||||
}
|
// Cancel any existing disconnect due to loss of underlying network
|
||||||
|
// getHandler() can return null if the state machine has already quit. Since this is
|
||||||
|
// called from other classes, this condition must be verified.
|
||||||
|
|
||||||
// Cancel any existing disconnect due to loss of underlying network
|
|
||||||
// getHandler() can return null if the state machine has already quit. Since this is
|
|
||||||
// called
|
|
||||||
// from other classes, this condition must be verified.
|
|
||||||
if (getHandler() != null) {
|
|
||||||
getHandler()
|
getHandler()
|
||||||
.removeEqualMessages(
|
.removeEqualMessages(
|
||||||
EVENT_DISCONNECT_REQUESTED,
|
EVENT_DISCONNECT_REQUESTED,
|
||||||
new EventDisconnectRequestedInfo(
|
new EventDisconnectRequestedInfo(
|
||||||
DISCONNECT_REASON_UNDERLYING_NETWORK_LOST));
|
DISCONNECT_REASON_UNDERLYING_NETWORK_LOST));
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(
|
sendMessage(
|
||||||
EVENT_UNDERLYING_NETWORK_CHANGED,
|
EVENT_UNDERLYING_NETWORK_CHANGED,
|
||||||
TOKEN_ANY,
|
TOKEN_ALL,
|
||||||
new EventUnderlyingNetworkChangedInfo(underlying));
|
new EventUnderlyingNetworkChangedInfo(underlying));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -594,10 +595,101 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private abstract class BaseState extends State {
|
private abstract class BaseState extends State {
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
try {
|
||||||
|
enterState();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Slog.wtf(TAG, "Uncaught exception", e);
|
||||||
|
sendMessage(
|
||||||
|
EVENT_DISCONNECT_REQUESTED,
|
||||||
|
TOKEN_ALL,
|
||||||
|
new EventDisconnectRequestedInfo(
|
||||||
|
DISCONNECT_REASON_INTERNAL_ERROR + e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void enterState() throws Exception {}
|
protected void enterState() throws Exception {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top-level processMessage with safeguards to prevent crashing the System Server on non-eng
|
||||||
|
* builds.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean processMessage(Message msg) {
|
||||||
|
try {
|
||||||
|
processStateMsg(msg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Slog.wtf(TAG, "Uncaught exception", e);
|
||||||
|
sendMessage(
|
||||||
|
EVENT_DISCONNECT_REQUESTED,
|
||||||
|
TOKEN_ALL,
|
||||||
|
new EventDisconnectRequestedInfo(
|
||||||
|
DISCONNECT_REASON_INTERNAL_ERROR + e.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void processStateMsg(Message msg) throws Exception;
|
protected abstract void processStateMsg(Message msg) throws Exception;
|
||||||
|
|
||||||
|
protected void logUnhandledMessage(Message msg) {
|
||||||
|
// Log as unexpected all known messages, and log all else as unknown.
|
||||||
|
switch (msg.what) {
|
||||||
|
case EVENT_UNDERLYING_NETWORK_CHANGED: // Fallthrough
|
||||||
|
case EVENT_RETRY_TIMEOUT_EXPIRED: // Fallthrough
|
||||||
|
case EVENT_SESSION_LOST: // Fallthrough
|
||||||
|
case EVENT_SESSION_CLOSED: // Fallthrough
|
||||||
|
case EVENT_TRANSFORM_CREATED: // Fallthrough
|
||||||
|
case EVENT_SETUP_COMPLETED: // Fallthrough
|
||||||
|
case EVENT_DISCONNECT_REQUESTED: // Fallthrough
|
||||||
|
case EVENT_TEARDOWN_TIMEOUT_EXPIRED:
|
||||||
|
logUnexpectedEvent(msg.what);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logWtfUnknownEvent(msg.what);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void teardownNetwork() {
|
||||||
|
if (mNetworkAgent != null) {
|
||||||
|
mNetworkAgent.sendNetworkInfo(buildNetworkInfo(false /* isConnected */));
|
||||||
|
mNetworkAgent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void teardownIke() {
|
||||||
|
if (mIkeSession != null) {
|
||||||
|
mIkeSession.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleDisconnectRequested(String msg) {
|
||||||
|
Slog.v(TAG, "Tearing down. Cause: " + msg);
|
||||||
|
teardownNetwork();
|
||||||
|
teardownIke();
|
||||||
|
|
||||||
|
if (mIkeSession == null) {
|
||||||
|
// Already disconnected, go straight to DisconnectedState
|
||||||
|
transitionTo(mDisconnectedState);
|
||||||
|
} else {
|
||||||
|
// Still need to wait for full closure
|
||||||
|
transitionTo(mDisconnectingState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void logUnexpectedEvent(int what) {
|
||||||
|
Slog.d(TAG, String.format(
|
||||||
|
"Unexpected event code %d in state %s", what, this.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void logWtfUnknownEvent(int what) {
|
||||||
|
Slog.wtf(TAG, String.format(
|
||||||
|
"Unknown event code %d in state %s", what, this.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State representing the a disconnected VCN tunnel.
|
* State representing the a disconnected VCN tunnel.
|
||||||
*
|
*
|
||||||
@@ -608,7 +700,29 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
protected void processStateMsg(Message msg) {}
|
protected void processStateMsg(Message msg) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class ActiveBaseState extends BaseState {}
|
private abstract class ActiveBaseState extends BaseState {
|
||||||
|
/**
|
||||||
|
* Handles all incoming messages, discarding messages for previous networks.
|
||||||
|
*
|
||||||
|
* <p>States that handle mobility events may need to override this method to receive
|
||||||
|
* messages for all underlying networks.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean processMessage(Message msg) {
|
||||||
|
final int token = msg.arg1;
|
||||||
|
// Only process if a valid token is presented.
|
||||||
|
if (isValidToken(token)) {
|
||||||
|
return super.processMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Slog.v(TAG, "Message called with obsolete token: " + token + "; what: " + msg.what);
|
||||||
|
return HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isValidToken(int token) {
|
||||||
|
return (token == TOKEN_ALL || token == mCurrentToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitive state representing a VCN that is tearing down an IKE session.
|
* Transitive state representing a VCN that is tearing down an IKE session.
|
||||||
|
|||||||
Reference in New Issue
Block a user