Merge changes Ib439bde4,I5bc0fe94,I72abf1e2,Id1813bcb am: a3fab46d7b am: 46b1ae0666
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1611230 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I12c2ee626cfb607b54c9d7237b250ad150e549da
This commit is contained in:
@@ -65,7 +65,7 @@ public class UnderlyingNetworkTracker {
|
||||
@NonNull private final NetworkCallback mRouteSelectionCallback = new RouteSelectionCallback();
|
||||
|
||||
@NonNull private TelephonySubscriptionSnapshot mLastSnapshot;
|
||||
private boolean mIsRunning = true;
|
||||
private boolean mIsQuitting = false;
|
||||
|
||||
@Nullable private UnderlyingNetworkRecord mCurrentRecord;
|
||||
@Nullable private UnderlyingNetworkRecord.Builder mRecordInProgress;
|
||||
@@ -151,7 +151,7 @@ public class UnderlyingNetworkTracker {
|
||||
mVcnContext.ensureRunningOnLooperThread();
|
||||
|
||||
// Don't bother re-filing NetworkRequests if this Tracker has been torn down.
|
||||
if (!mIsRunning) {
|
||||
if (mIsQuitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class UnderlyingNetworkTracker {
|
||||
}
|
||||
mCellBringupCallbacks.clear();
|
||||
|
||||
mIsRunning = false;
|
||||
mIsQuitting = true;
|
||||
}
|
||||
|
||||
/** Returns whether the currently selected Network matches the given network. */
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.vcn;
|
||||
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
|
||||
|
||||
import static com.android.server.VcnManagementService.VDBG;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -84,6 +86,13 @@ public class Vcn extends Handler {
|
||||
*/
|
||||
private static final int MSG_EVENT_SUBSCRIPTIONS_CHANGED = MSG_EVENT_BASE + 2;
|
||||
|
||||
/**
|
||||
* A GatewayConnection owned by this VCN quit.
|
||||
*
|
||||
* @param obj VcnGatewayConnectionConfig
|
||||
*/
|
||||
private static final int MSG_EVENT_GATEWAY_CONNECTION_QUIT = MSG_EVENT_BASE + 3;
|
||||
|
||||
/** Triggers an immediate teardown of the entire Vcn, including GatewayConnections. */
|
||||
private static final int MSG_CMD_TEARDOWN = MSG_CMD_BASE;
|
||||
|
||||
@@ -208,6 +217,9 @@ public class Vcn extends Handler {
|
||||
case MSG_EVENT_SUBSCRIPTIONS_CHANGED:
|
||||
handleSubscriptionsChanged((TelephonySubscriptionSnapshot) msg.obj);
|
||||
break;
|
||||
case MSG_EVENT_GATEWAY_CONNECTION_QUIT:
|
||||
handleGatewayConnectionQuit((VcnGatewayConnectionConfig) msg.obj);
|
||||
break;
|
||||
case MSG_CMD_TEARDOWN:
|
||||
handleTeardown();
|
||||
break;
|
||||
@@ -263,7 +275,7 @@ public class Vcn extends Handler {
|
||||
|
||||
// If preexisting VcnGatewayConnection(s) satisfy request, return
|
||||
for (VcnGatewayConnectionConfig gatewayConnectionConfig : mVcnGatewayConnections.keySet()) {
|
||||
if (requestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
|
||||
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
|
||||
if (VDBG) {
|
||||
Slog.v(
|
||||
getLogTag(),
|
||||
@@ -278,7 +290,7 @@ public class Vcn extends Handler {
|
||||
// up
|
||||
for (VcnGatewayConnectionConfig gatewayConnectionConfig :
|
||||
mConfig.getGatewayConnectionConfigs()) {
|
||||
if (requestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
|
||||
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
|
||||
Slog.v(
|
||||
getLogTag(),
|
||||
"Bringing up new VcnGatewayConnection for request " + request.requestId);
|
||||
@@ -289,12 +301,21 @@ public class Vcn extends Handler {
|
||||
mSubscriptionGroup,
|
||||
mLastSnapshot,
|
||||
gatewayConnectionConfig,
|
||||
new VcnGatewayStatusCallbackImpl());
|
||||
new VcnGatewayStatusCallbackImpl(gatewayConnectionConfig));
|
||||
mVcnGatewayConnections.put(gatewayConnectionConfig, vcnGatewayConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGatewayConnectionQuit(VcnGatewayConnectionConfig config) {
|
||||
Slog.v(getLogTag(), "VcnGatewayConnection quit: " + config);
|
||||
mVcnGatewayConnections.remove(config);
|
||||
|
||||
// Trigger a re-evaluation of all NetworkRequests (to make sure any that can be satisfied
|
||||
// start a new GatewayConnection)
|
||||
mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
|
||||
}
|
||||
|
||||
private void handleSubscriptionsChanged(@NonNull TelephonySubscriptionSnapshot snapshot) {
|
||||
mLastSnapshot = snapshot;
|
||||
|
||||
@@ -305,9 +326,10 @@ public class Vcn extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requestSatisfiedByGatewayConnectionConfig(
|
||||
private boolean isRequestSatisfiedByGatewayConnectionConfig(
|
||||
@NonNull NetworkRequest request, @NonNull VcnGatewayConnectionConfig config) {
|
||||
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
|
||||
builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||
for (int cap : config.getAllExposedCapabilities()) {
|
||||
builder.addCapability(cap);
|
||||
}
|
||||
@@ -339,9 +361,23 @@ public class Vcn extends Handler {
|
||||
@VcnErrorCode int errorCode,
|
||||
@Nullable String exceptionClass,
|
||||
@Nullable String exceptionMessage);
|
||||
|
||||
/** Called by a VcnGatewayConnection to indicate that it has fully torn down. */
|
||||
void onQuit();
|
||||
}
|
||||
|
||||
private class VcnGatewayStatusCallbackImpl implements VcnGatewayStatusCallback {
|
||||
public final VcnGatewayConnectionConfig mGatewayConnectionConfig;
|
||||
|
||||
VcnGatewayStatusCallbackImpl(VcnGatewayConnectionConfig gatewayConnectionConfig) {
|
||||
mGatewayConnectionConfig = gatewayConnectionConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuit() {
|
||||
sendMessage(obtainMessage(MSG_EVENT_GATEWAY_CONNECTION_QUIT, mGatewayConnectionConfig));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnteredSafeMode() {
|
||||
sendMessage(obtainMessage(MSG_CMD_ENTER_SAFE_MODE));
|
||||
|
||||
@@ -168,6 +168,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
private static final String DISCONNECT_REASON_INTERNAL_ERROR = "Uncaught exception: ";
|
||||
private static final String DISCONNECT_REASON_UNDERLYING_NETWORK_LOST =
|
||||
"Underlying Network lost";
|
||||
private static final String DISCONNECT_REASON_NETWORK_AGENT_UNWANTED =
|
||||
"NetworkAgent was unwanted";
|
||||
private static final String DISCONNECT_REASON_TEARDOWN = "teardown() called on VcnTunnel";
|
||||
private static final int TOKEN_ALL = Integer.MIN_VALUE;
|
||||
|
||||
@@ -379,13 +381,16 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
/** The reason why the disconnect was requested. */
|
||||
@NonNull public final String reason;
|
||||
|
||||
EventDisconnectRequestedInfo(@NonNull String reason) {
|
||||
public final boolean shouldQuit;
|
||||
|
||||
EventDisconnectRequestedInfo(@NonNull String reason, boolean shouldQuit) {
|
||||
this.reason = Objects.requireNonNull(reason);
|
||||
this.shouldQuit = shouldQuit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(reason);
|
||||
return Objects.hash(reason, shouldQuit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -395,7 +400,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
}
|
||||
|
||||
final EventDisconnectRequestedInfo rhs = (EventDisconnectRequestedInfo) other;
|
||||
return reason.equals(rhs.reason);
|
||||
return reason.equals(rhs.reason) && shouldQuit == rhs.shouldQuit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,8 +493,14 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
*/
|
||||
@NonNull private final VcnWakeLock mWakeLock;
|
||||
|
||||
/** Running state of this VcnGatewayConnection. */
|
||||
private boolean mIsRunning = true;
|
||||
/**
|
||||
* Whether the VcnGatewayConnection is in the process of irreversibly quitting.
|
||||
*
|
||||
* <p>This variable is false for the lifecycle of the VcnGatewayConnection, until a command to
|
||||
* teardown has been received. This may be flipped due to events such as the Network becoming
|
||||
* unwanted, the owning VCN entering safe mode, or an irrecoverable internal failure.
|
||||
*/
|
||||
private boolean mIsQuitting = false;
|
||||
|
||||
/**
|
||||
* The token used by the primary/current/active session.
|
||||
@@ -622,10 +633,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
* <p>Once torn down, this VcnTunnel CANNOT be started again.
|
||||
*/
|
||||
public void teardownAsynchronously() {
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
TOKEN_ALL,
|
||||
new EventDisconnectRequestedInfo(DISCONNECT_REASON_TEARDOWN));
|
||||
sendDisconnectRequestedAndAcquireWakelock(
|
||||
DISCONNECT_REASON_TEARDOWN, true /* shouldQuit */);
|
||||
|
||||
// TODO: Notify VcnInstance (via callbacks) of permanent teardown of this tunnel, since this
|
||||
// is also called asynchronously when a NetworkAgent becomes unwanted
|
||||
@@ -646,6 +655,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
cancelSafeModeAlarm();
|
||||
|
||||
mUnderlyingNetworkTracker.teardown();
|
||||
|
||||
mGatewayStatusCallback.onQuit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,7 +704,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
private void acquireWakeLock() {
|
||||
mVcnContext.ensureRunningOnLooperThread();
|
||||
|
||||
if (mIsRunning) {
|
||||
if (!mIsQuitting) {
|
||||
mWakeLock.acquire();
|
||||
}
|
||||
}
|
||||
@@ -892,7 +903,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
TOKEN_ALL,
|
||||
0 /* arg2 */,
|
||||
new EventDisconnectRequestedInfo(
|
||||
DISCONNECT_REASON_UNDERLYING_NETWORK_LOST));
|
||||
DISCONNECT_REASON_UNDERLYING_NETWORK_LOST, false /* shouldQuit */));
|
||||
mDisconnectRequestAlarm =
|
||||
createScheduledAlarm(
|
||||
DISCONNECT_REQUEST_ALARM,
|
||||
@@ -909,7 +920,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
// Cancel any existing disconnect due to previous loss of underlying network
|
||||
removeEqualMessages(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
new EventDisconnectRequestedInfo(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST));
|
||||
new EventDisconnectRequestedInfo(
|
||||
DISCONNECT_REASON_UNDERLYING_NETWORK_LOST, false /* shouldQuit */));
|
||||
}
|
||||
|
||||
private void setRetryTimeoutAlarm(long delay) {
|
||||
@@ -1041,11 +1053,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
enterState();
|
||||
} catch (Exception e) {
|
||||
Slog.wtf(TAG, "Uncaught exception", e);
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
TOKEN_ALL,
|
||||
new EventDisconnectRequestedInfo(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString()));
|
||||
sendDisconnectRequestedAndAcquireWakelock(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,11 +1092,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
processStateMsg(msg);
|
||||
} catch (Exception e) {
|
||||
Slog.wtf(TAG, "Uncaught exception", e);
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
TOKEN_ALL,
|
||||
new EventDisconnectRequestedInfo(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString()));
|
||||
sendDisconnectRequestedAndAcquireWakelock(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
|
||||
}
|
||||
|
||||
// Attempt to release the WakeLock - only possible if the Handler queue is empty
|
||||
@@ -1104,11 +1110,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
exitState();
|
||||
} catch (Exception e) {
|
||||
Slog.wtf(TAG, "Uncaught exception", e);
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
TOKEN_ALL,
|
||||
new EventDisconnectRequestedInfo(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString()));
|
||||
sendDisconnectRequestedAndAcquireWakelock(
|
||||
DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1141,11 +1144,11 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleDisconnectRequested(String msg) {
|
||||
protected void handleDisconnectRequested(EventDisconnectRequestedInfo info) {
|
||||
// TODO(b/180526152): notify VcnStatusCallback for Network loss
|
||||
|
||||
Slog.v(TAG, "Tearing down. Cause: " + msg);
|
||||
mIsRunning = false;
|
||||
Slog.v(TAG, "Tearing down. Cause: " + info.reason);
|
||||
mIsQuitting = info.shouldQuit;
|
||||
|
||||
teardownNetwork();
|
||||
|
||||
@@ -1177,7 +1180,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
private class DisconnectedState extends BaseState {
|
||||
@Override
|
||||
protected void enterState() {
|
||||
if (!mIsRunning) {
|
||||
if (mIsQuitting) {
|
||||
quitNow(); // Ignore all queued events; cleanup is complete.
|
||||
}
|
||||
|
||||
@@ -1200,9 +1203,11 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
}
|
||||
break;
|
||||
case EVENT_DISCONNECT_REQUESTED:
|
||||
mIsRunning = false;
|
||||
if (((EventDisconnectRequestedInfo) msg.obj).shouldQuit) {
|
||||
mIsQuitting = true;
|
||||
|
||||
quitNow();
|
||||
quitNow();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logUnhandledMessage(msg);
|
||||
@@ -1284,10 +1289,11 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
|
||||
break;
|
||||
case EVENT_DISCONNECT_REQUESTED:
|
||||
EventDisconnectRequestedInfo info = ((EventDisconnectRequestedInfo) msg.obj);
|
||||
mIsQuitting = info.shouldQuit;
|
||||
teardownNetwork();
|
||||
|
||||
String reason = ((EventDisconnectRequestedInfo) msg.obj).reason;
|
||||
if (reason.equals(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST)) {
|
||||
if (info.reason.equals(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST)) {
|
||||
// TODO(b/180526152): notify VcnStatusCallback for Network loss
|
||||
|
||||
// Will trigger EVENT_SESSION_CLOSED immediately.
|
||||
@@ -1300,7 +1306,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
case EVENT_SESSION_CLOSED:
|
||||
mIkeSession = null;
|
||||
|
||||
if (mIsRunning && mUnderlying != null) {
|
||||
if (!mIsQuitting && mUnderlying != null) {
|
||||
transitionTo(mSkipRetryTimeout ? mConnectingState : mRetryTimeoutState);
|
||||
} else {
|
||||
teardownNetwork();
|
||||
@@ -1391,7 +1397,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
transitionTo(mConnectedState);
|
||||
break;
|
||||
case EVENT_DISCONNECT_REQUESTED:
|
||||
handleDisconnectRequested(((EventDisconnectRequestedInfo) msg.obj).reason);
|
||||
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
|
||||
break;
|
||||
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
|
||||
mGatewayStatusCallback.onEnteredSafeMode();
|
||||
@@ -1438,6 +1444,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
mVcnContext.getVcnNetworkProvider()) {
|
||||
@Override
|
||||
public void unwanted() {
|
||||
Slog.d(TAG, "NetworkAgent was unwanted");
|
||||
teardownAsynchronously();
|
||||
}
|
||||
|
||||
@@ -1471,7 +1478,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
@NonNull IpSecTransform transform,
|
||||
int direction) {
|
||||
try {
|
||||
// TODO(b/180163196): Set underlying network of tunnel interface
|
||||
tunnelIface.setUnderlyingNetwork(underlyingNetwork);
|
||||
|
||||
// Transforms do not need to be persisted; the IkeSession will keep them alive
|
||||
mIpSecManager.applyTunnelModeTransform(tunnelIface, direction, transform);
|
||||
@@ -1577,7 +1584,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig);
|
||||
break;
|
||||
case EVENT_DISCONNECT_REQUESTED:
|
||||
handleDisconnectRequested(((EventDisconnectRequestedInfo) msg.obj).reason);
|
||||
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
|
||||
break;
|
||||
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
|
||||
mGatewayStatusCallback.onEnteredSafeMode();
|
||||
@@ -1682,7 +1689,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
transitionTo(mConnectingState);
|
||||
break;
|
||||
case EVENT_DISCONNECT_REQUESTED:
|
||||
handleDisconnectRequested(((EventDisconnectRequestedInfo) msg.obj).reason);
|
||||
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
|
||||
break;
|
||||
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
|
||||
mGatewayStatusCallback.onEnteredSafeMode();
|
||||
@@ -1905,13 +1912,13 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
boolean isRunning() {
|
||||
return mIsRunning;
|
||||
boolean isQuitting() {
|
||||
return mIsQuitting;
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
void setIsRunning(boolean isRunning) {
|
||||
mIsRunning = isRunning;
|
||||
void setIsQuitting(boolean isQuitting) {
|
||||
mIsQuitting = isQuitting;
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
@@ -1924,6 +1931,14 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
mIkeSession = session;
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
void sendDisconnectRequestedAndAcquireWakelock(String reason, boolean shouldQuit) {
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_DISCONNECT_REQUESTED,
|
||||
TOKEN_ALL,
|
||||
new EventDisconnectRequestedInfo(reason, shouldQuit));
|
||||
}
|
||||
|
||||
private IkeSessionParams buildIkeParams() {
|
||||
// TODO: Implement this once IkeSessionParams is persisted
|
||||
return null;
|
||||
|
||||
@@ -67,9 +67,7 @@ public class VcnNetworkProvider extends NetworkProvider {
|
||||
mListeners.add(listener);
|
||||
|
||||
// Send listener all cached requests
|
||||
for (NetworkRequestEntry entry : mRequests.values()) {
|
||||
notifyListenerForEvent(listener, entry);
|
||||
}
|
||||
resendAllRequests(listener);
|
||||
}
|
||||
|
||||
/** Unregisters the specified listener from receiving future NetworkRequests. */
|
||||
@@ -78,6 +76,14 @@ public class VcnNetworkProvider extends NetworkProvider {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
/** Sends all cached NetworkRequest(s) to the specified listener. */
|
||||
@VisibleForTesting(visibility = Visibility.PACKAGE)
|
||||
public void resendAllRequests(@NonNull NetworkRequestListener listener) {
|
||||
for (NetworkRequestEntry entry : mRequests.values()) {
|
||||
notifyListenerForEvent(listener, entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenerForEvent(
|
||||
@NonNull NetworkRequestListener listener, @NonNull NetworkRequestEntry entry) {
|
||||
listener.onNetworkRequested(entry.mRequest, entry.mScore, entry.mProviderId);
|
||||
|
||||
@@ -36,6 +36,7 @@ import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
@@ -143,11 +144,18 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
||||
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mIpSecSvc, times(2))
|
||||
.setNetworkForTunnelInterface(
|
||||
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID),
|
||||
eq(TEST_UNDERLYING_NETWORK_RECORD_1.network),
|
||||
any());
|
||||
|
||||
for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
|
||||
verify(mIpSecSvc)
|
||||
.applyTunnelModeTransform(
|
||||
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
|
||||
}
|
||||
|
||||
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
|
||||
}
|
||||
|
||||
@@ -290,4 +298,22 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
||||
verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback(
|
||||
new TemporaryFailureException("vcn test"), VCN_ERROR_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTeardown() throws Exception {
|
||||
mGatewayConnection.teardownAsynchronously();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
assertTrue(mGatewayConnection.isQuitting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
assertFalse(mGatewayConnection.isQuitting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.server.vcn;
|
||||
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -111,4 +113,22 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
|
||||
public void testSafeModeTimeoutNotifiesCallback() {
|
||||
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mConnectingState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTeardown() throws Exception {
|
||||
mGatewayConnection.teardownAsynchronously();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
assertTrue(mGatewayConnection.isQuitting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
assertFalse(mGatewayConnection.isQuitting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,12 @@ import static android.net.IpSecManager.IpSecTunnelInterface;
|
||||
import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.net.IpSecManager;
|
||||
@@ -54,7 +57,7 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnterWhileNotRunningTriggersQuit() throws Exception {
|
||||
public void testEnterWhileQuittingTriggersQuit() throws Exception {
|
||||
final VcnGatewayConnection vgc =
|
||||
new VcnGatewayConnection(
|
||||
mVcnContext,
|
||||
@@ -64,7 +67,7 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
|
||||
mGatewayStatusCallback,
|
||||
mDeps);
|
||||
|
||||
vgc.setIsRunning(false);
|
||||
vgc.setIsQuitting(true);
|
||||
vgc.transitionTo(vgc.mDisconnectedState);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
@@ -101,5 +104,18 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
|
||||
assertNull(mGatewayConnection.getCurrentState());
|
||||
verify(mIpSecSvc).deleteTunnelInterface(eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), any());
|
||||
verifySafeModeTimeoutAlarmAndGetCallback(true /* expectCanceled */);
|
||||
assertTrue(mGatewayConnection.isQuitting());
|
||||
verify(mGatewayStatusCallback).onQuit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState());
|
||||
assertFalse(mGatewayConnection.isQuitting());
|
||||
verify(mGatewayStatusCallback, never()).onQuit();
|
||||
// No safe mode timer changes expected.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.server.vcn;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -79,10 +81,20 @@ public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnec
|
||||
// Should do nothing; already tearing down.
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
verifyTeardownTimeoutAlarmAndGetCallback(false /* expectCanceled */);
|
||||
assertTrue(mGatewayConnection.isQuitting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSafeModeTimeoutNotifiesCallback() {
|
||||
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mDisconnectingState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||
assertFalse(mGatewayConnection.isQuitting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.android.server.vcn;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -96,4 +99,22 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect
|
||||
public void testSafeModeTimeoutNotifiesCallback() {
|
||||
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mRetryTimeoutState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.teardownAsynchronously();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertNull(mGatewayConnection.getCurrentState());
|
||||
assertTrue(mGatewayConnection.isQuitting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTeardownDisconnectRequest() throws Exception {
|
||||
mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState());
|
||||
assertFalse(mGatewayConnection.isQuitting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.server.vcn;
|
||||
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.Matchers.any;
|
||||
@@ -33,6 +37,7 @@ import android.net.vcn.VcnGatewayConnectionConfig;
|
||||
import android.net.vcn.VcnGatewayConnectionConfigTest;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.test.TestLooper;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.server.VcnManagementService.VcnCallback;
|
||||
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
@@ -51,6 +56,11 @@ public class VcnTest {
|
||||
private static final ParcelUuid TEST_SUB_GROUP = new ParcelUuid(new UUID(0, 0));
|
||||
private static final int NETWORK_SCORE = 0;
|
||||
private static final int PROVIDER_ID = 5;
|
||||
private static final int[][] TEST_CAPS =
|
||||
new int[][] {
|
||||
new int[] {NET_CAPABILITY_INTERNET, NET_CAPABILITY_MMS},
|
||||
new int[] {NET_CAPABILITY_DUN}
|
||||
};
|
||||
|
||||
private Context mContext;
|
||||
private VcnContext mVcnContext;
|
||||
@@ -91,13 +101,12 @@ public class VcnTest {
|
||||
mGatewayStatusCallbackCaptor = ArgumentCaptor.forClass(VcnGatewayStatusCallback.class);
|
||||
|
||||
final VcnConfig.Builder configBuilder = new VcnConfig.Builder(mContext);
|
||||
for (final int capability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
|
||||
for (final int[] caps : TEST_CAPS) {
|
||||
configBuilder.addGatewayConnectionConfig(
|
||||
VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(capability));
|
||||
VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(caps));
|
||||
}
|
||||
configBuilder.addGatewayConnectionConfig(VcnGatewayConnectionConfigTest.buildTestConfig());
|
||||
mConfig = configBuilder.build();
|
||||
|
||||
mConfig = configBuilder.build();
|
||||
mVcn =
|
||||
new Vcn(
|
||||
mVcnContext,
|
||||
@@ -130,8 +139,7 @@ public class VcnTest {
|
||||
@Test
|
||||
public void testSubscriptionSnapshotUpdatesVcnGatewayConnections() {
|
||||
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
|
||||
startVcnGatewayWithCapabilities(
|
||||
requestListener, VcnGatewayConnectionConfigTest.EXPOSED_CAPS);
|
||||
startVcnGatewayWithCapabilities(requestListener, TEST_CAPS[0]);
|
||||
|
||||
final Set<VcnGatewayConnection> gatewayConnections = mVcn.getVcnGatewayConnections();
|
||||
assertFalse(gatewayConnections.isEmpty());
|
||||
@@ -153,10 +161,19 @@ public class VcnTest {
|
||||
for (final int capability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
|
||||
startVcnGatewayWithCapabilities(requestListener, capability);
|
||||
}
|
||||
}
|
||||
|
||||
// Each Capability in EXPOSED_CAPS was split into a separate VcnGatewayConnection in #setUp.
|
||||
// Expect one VcnGatewayConnection per capability.
|
||||
final int numExpectedGateways = VcnGatewayConnectionConfigTest.EXPOSED_CAPS.length;
|
||||
private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
|
||||
for (final int[] caps : TEST_CAPS) {
|
||||
startVcnGatewayWithCapabilities(requestListener, caps);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<VcnGatewayConnection> startGatewaysAndGetGatewayConnections(
|
||||
NetworkRequestListener requestListener) {
|
||||
triggerVcnRequestListeners(requestListener);
|
||||
|
||||
final int numExpectedGateways = TEST_CAPS.length;
|
||||
|
||||
final Set<VcnGatewayConnection> gatewayConnections = mVcn.getVcnGatewayConnections();
|
||||
assertEquals(numExpectedGateways, gatewayConnections.size());
|
||||
@@ -168,7 +185,16 @@ public class VcnTest {
|
||||
any(),
|
||||
mGatewayStatusCallbackCaptor.capture());
|
||||
|
||||
// Doesn't matter which callback this gets - any Gateway entering safe mode should shut down
|
||||
return gatewayConnections;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayEnteringSafemodeNotifiesVcn() {
|
||||
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
|
||||
final Set<VcnGatewayConnection> gatewayConnections =
|
||||
startGatewaysAndGetGatewayConnections(requestListener);
|
||||
|
||||
// Doesn't matter which callback this gets - any Gateway entering Safemode should shut down
|
||||
// all Gateways
|
||||
final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
|
||||
statusCallback.onEnteredSafeMode();
|
||||
@@ -181,4 +207,31 @@ public class VcnTest {
|
||||
verify(mVcnNetworkProvider).unregisterListener(requestListener);
|
||||
verify(mVcnCallback).onEnteredSafeMode();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayQuit() {
|
||||
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
|
||||
final Set<VcnGatewayConnection> gatewayConnections =
|
||||
new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
|
||||
|
||||
final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
|
||||
statusCallback.onQuit();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// Verify that the VCN requests the networkRequests be resent
|
||||
assertEquals(1, mVcn.getVcnGatewayConnections().size());
|
||||
verify(mVcnNetworkProvider).resendAllRequests(requestListener);
|
||||
|
||||
// Verify that the VcnGatewayConnection is restarted
|
||||
triggerVcnRequestListeners(requestListener);
|
||||
mTestLooper.dispatchAll();
|
||||
assertEquals(2, mVcn.getVcnGatewayConnections().size());
|
||||
verify(mDeps, times(gatewayConnections.size() + 1))
|
||||
.newVcnGatewayConnection(
|
||||
eq(mVcnContext),
|
||||
eq(TEST_SUB_GROUP),
|
||||
eq(mSubscriptionSnapshot),
|
||||
any(),
|
||||
mGatewayStatusCallbackCaptor.capture());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user