Merge "Convert VcnNetworkProvider to use NetworkOffers"
This commit is contained in:
@@ -83,7 +83,12 @@ public final class VcnGatewayConnectionConfig {
|
|||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
static final int MIN_MTU_V6 = 1280;
|
static final int MIN_MTU_V6 = 1280;
|
||||||
|
|
||||||
private static final Set<Integer> ALLOWED_CAPABILITIES;
|
/**
|
||||||
|
* The set of allowed capabilities for exposed capabilities.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final Set<Integer> ALLOWED_CAPABILITIES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<Integer> allowedCaps = new ArraySet<>();
|
Set<Integer> allowedCaps = new ArraySet<>();
|
||||||
|
|||||||
@@ -372,8 +372,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
|
|
||||||
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
||||||
public void systemReady() {
|
public void systemReady() {
|
||||||
mContext.getSystemService(ConnectivityManager.class)
|
mNetworkProvider.register();
|
||||||
.registerNetworkProvider(mNetworkProvider);
|
|
||||||
mContext.getSystemService(ConnectivityManager.class)
|
mContext.getSystemService(ConnectivityManager.class)
|
||||||
.registerNetworkCallback(
|
.registerNetworkCallback(
|
||||||
new NetworkRequest.Builder().clearCapabilities().build(),
|
new NetworkRequest.Builder().clearCapabilities().build(),
|
||||||
|
|||||||
@@ -16,12 +16,24 @@
|
|||||||
|
|
||||||
package com.android.server.vcn;
|
package com.android.server.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
|
||||||
import static com.android.server.VcnManagementService.VDBG;
|
import static com.android.server.VcnManagementService.VDBG;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkProvider;
|
import android.net.NetworkProvider;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
|
import android.net.NetworkScore;
|
||||||
|
import android.net.vcn.VcnGatewayConnectionConfig;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerExecutor;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -30,7 +42,9 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VCN Network Provider routes NetworkRequests to listeners to bring up tunnels as needed.
|
* VCN Network Provider routes NetworkRequests to listeners to bring up tunnels as needed.
|
||||||
@@ -45,6 +59,10 @@ public class VcnNetworkProvider extends NetworkProvider {
|
|||||||
|
|
||||||
private final Set<NetworkRequestListener> mListeners = new ArraySet<>();
|
private final Set<NetworkRequestListener> mListeners = new ArraySet<>();
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final Dependencies mDeps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache of NetworkRequest(s).
|
* Cache of NetworkRequest(s).
|
||||||
*
|
*
|
||||||
@@ -52,8 +70,59 @@ public class VcnNetworkProvider extends NetworkProvider {
|
|||||||
*/
|
*/
|
||||||
private final Set<NetworkRequest> mRequests = new ArraySet<>();
|
private final Set<NetworkRequest> mRequests = new ArraySet<>();
|
||||||
|
|
||||||
public VcnNetworkProvider(Context context, Looper looper) {
|
public VcnNetworkProvider(@NonNull Context context, @NonNull Looper looper) {
|
||||||
super(context, looper, VcnNetworkProvider.class.getSimpleName());
|
this(context, looper, new Dependencies());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
public VcnNetworkProvider(
|
||||||
|
@NonNull Context context, @NonNull Looper looper, @NonNull Dependencies dependencies) {
|
||||||
|
super(
|
||||||
|
Objects.requireNonNull(context, "Missing context"),
|
||||||
|
Objects.requireNonNull(looper, "Missing looper"),
|
||||||
|
TAG);
|
||||||
|
|
||||||
|
mContext = context;
|
||||||
|
mHandler = new Handler(looper);
|
||||||
|
mDeps = Objects.requireNonNull(dependencies, "Missing dependencies");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Registers this VcnNetworkProvider and a generic network offer with ConnectivityService. */
|
||||||
|
public void register() {
|
||||||
|
mContext.getSystemService(ConnectivityManager.class).registerNetworkProvider(this);
|
||||||
|
mDeps.registerNetworkOffer(
|
||||||
|
this,
|
||||||
|
Vcn.getNetworkScore(), // score filter
|
||||||
|
buildCapabilityFilter(),
|
||||||
|
new HandlerExecutor(mHandler),
|
||||||
|
new NetworkOfferCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNetworkNeeded(@NonNull NetworkRequest request) {
|
||||||
|
handleNetworkRequested(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkUnneeded(@NonNull NetworkRequest request) {
|
||||||
|
handleNetworkRequestWithdrawn(request);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Builds the filter for NetworkRequests that can be served by the VcnNetworkProvider. */
|
||||||
|
private NetworkCapabilities buildCapabilityFilter() {
|
||||||
|
final NetworkCapabilities.Builder builder =
|
||||||
|
new NetworkCapabilities.Builder()
|
||||||
|
.addTransportType(TRANSPORT_CELLULAR)
|
||||||
|
.addCapability(NET_CAPABILITY_TRUSTED)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_VPN)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||||
|
|
||||||
|
for (int cap : VcnGatewayConnectionConfig.ALLOWED_CAPABILITIES) {
|
||||||
|
builder.addCapability(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,8 +157,7 @@ public class VcnNetworkProvider extends NetworkProvider {
|
|||||||
listener.onNetworkRequested(request);
|
listener.onNetworkRequested(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void handleNetworkRequested(@NonNull NetworkRequest request) {
|
||||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {
|
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Slog.v(TAG, "Network requested: Request = " + request);
|
Slog.v(TAG, "Network requested: Request = " + request);
|
||||||
}
|
}
|
||||||
@@ -103,8 +171,7 @@ public class VcnNetworkProvider extends NetworkProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void handleNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
|
||||||
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
|
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Slog.v(TAG, "Network request withdrawn: Request = " + request);
|
Slog.v(TAG, "Network request withdrawn: Request = " + request);
|
||||||
}
|
}
|
||||||
@@ -144,4 +211,18 @@ public class VcnNetworkProvider extends NetworkProvider {
|
|||||||
|
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Proxy class for dependencies used for testing. */
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
public static class Dependencies {
|
||||||
|
/** Registers a given network offer for the given provider. */
|
||||||
|
public void registerNetworkOffer(
|
||||||
|
@NonNull VcnNetworkProvider provider,
|
||||||
|
@NonNull NetworkScore score,
|
||||||
|
@NonNull NetworkCapabilities capabilitiesFilter,
|
||||||
|
@NonNull Executor executor,
|
||||||
|
@NonNull NetworkOfferCallback callback) {
|
||||||
|
provider.registerNetworkOffer(score, capabilitiesFilter, executor, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,18 @@
|
|||||||
|
|
||||||
package com.android.server.vcn;
|
package com.android.server.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkProvider.NetworkOfferCallback;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.argThat;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
|
|
||||||
@@ -33,6 +39,7 @@ import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -47,6 +54,8 @@ public class VcnNetworkProviderTest {
|
|||||||
@NonNull private final Context mContext;
|
@NonNull private final Context mContext;
|
||||||
@NonNull private final TestLooper mTestLooper;
|
@NonNull private final TestLooper mTestLooper;
|
||||||
|
|
||||||
|
@NonNull private VcnNetworkProvider.Dependencies mDeps;
|
||||||
|
@NonNull private ConnectivityManager mConnMgr;
|
||||||
@NonNull private VcnNetworkProvider mVcnNetworkProvider;
|
@NonNull private VcnNetworkProvider mVcnNetworkProvider;
|
||||||
@NonNull private NetworkRequestListener mListener;
|
@NonNull private NetworkRequestListener mListener;
|
||||||
|
|
||||||
@@ -57,16 +66,47 @@ public class VcnNetworkProviderTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mVcnNetworkProvider = new VcnNetworkProvider(mContext, mTestLooper.getLooper());
|
mDeps = mock(VcnNetworkProvider.Dependencies.class);
|
||||||
|
mConnMgr = mock(ConnectivityManager.class);
|
||||||
|
VcnTestUtils.setupSystemService(
|
||||||
|
mContext, mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class);
|
||||||
|
|
||||||
|
mVcnNetworkProvider = new VcnNetworkProvider(mContext, mTestLooper.getLooper(), mDeps);
|
||||||
mListener = mock(NetworkRequestListener.class);
|
mListener = mock(NetworkRequestListener.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetworkOfferCallback verifyRegisterAndGetOfferCallback() throws Exception {
|
||||||
|
mVcnNetworkProvider.register();
|
||||||
|
|
||||||
|
final ArgumentCaptor<NetworkOfferCallback> cbCaptor =
|
||||||
|
ArgumentCaptor.forClass(NetworkOfferCallback.class);
|
||||||
|
|
||||||
|
verify(mConnMgr).registerNetworkProvider(eq(mVcnNetworkProvider));
|
||||||
|
verify(mDeps)
|
||||||
|
.registerNetworkOffer(
|
||||||
|
eq(mVcnNetworkProvider),
|
||||||
|
argThat(
|
||||||
|
score ->
|
||||||
|
score.getLegacyInt()
|
||||||
|
== Vcn.getNetworkScore().getLegacyInt()),
|
||||||
|
any(),
|
||||||
|
any(),
|
||||||
|
cbCaptor.capture());
|
||||||
|
|
||||||
|
return cbCaptor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegister() throws Exception {
|
||||||
|
verifyRegisterAndGetOfferCallback();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestsPassedToRegisteredListeners() throws Exception {
|
public void testRequestsPassedToRegisteredListeners() throws Exception {
|
||||||
mVcnNetworkProvider.registerListener(mListener);
|
mVcnNetworkProvider.registerListener(mListener);
|
||||||
|
|
||||||
final NetworkRequest request = mock(NetworkRequest.class);
|
final NetworkRequest request = mock(NetworkRequest.class);
|
||||||
mVcnNetworkProvider.onNetworkRequested(request, TEST_SCORE_UNSATISFIED, TEST_PROVIDER_ID);
|
verifyRegisterAndGetOfferCallback().onNetworkNeeded(request);
|
||||||
verify(mListener).onNetworkRequested(request);
|
verify(mListener).onNetworkRequested(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,13 +116,14 @@ public class VcnNetworkProviderTest {
|
|||||||
mVcnNetworkProvider.unregisterListener(mListener);
|
mVcnNetworkProvider.unregisterListener(mListener);
|
||||||
|
|
||||||
final NetworkRequest request = mock(NetworkRequest.class);
|
final NetworkRequest request = mock(NetworkRequest.class);
|
||||||
mVcnNetworkProvider.onNetworkRequested(request, TEST_SCORE_UNSATISFIED, TEST_PROVIDER_ID);
|
verifyRegisterAndGetOfferCallback().onNetworkNeeded(request);
|
||||||
verifyNoMoreInteractions(mListener);
|
verifyNoMoreInteractions(mListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCachedRequestsPassedOnRegister() throws Exception {
|
public void testCachedRequestsPassedOnRegister() throws Exception {
|
||||||
final List<NetworkRequest> requests = new ArrayList<>();
|
final List<NetworkRequest> requests = new ArrayList<>();
|
||||||
|
final NetworkOfferCallback offerCb = verifyRegisterAndGetOfferCallback();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
// Build unique network requests; in this case, iterate down the capabilities as a way
|
// Build unique network requests; in this case, iterate down the capabilities as a way
|
||||||
@@ -91,12 +132,12 @@ public class VcnNetworkProviderTest {
|
|||||||
new NetworkRequest.Builder().clearCapabilities().addCapability(i).build();
|
new NetworkRequest.Builder().clearCapabilities().addCapability(i).build();
|
||||||
|
|
||||||
requests.add(request);
|
requests.add(request);
|
||||||
mVcnNetworkProvider.onNetworkRequested(request, i, i + 1);
|
offerCb.onNetworkNeeded(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove one, and verify that it is never sent to the listeners.
|
// Remove one, and verify that it is never sent to the listeners.
|
||||||
final NetworkRequest removed = requests.remove(0);
|
final NetworkRequest removed = requests.remove(0);
|
||||||
mVcnNetworkProvider.onNetworkRequestWithdrawn(removed);
|
offerCb.onNetworkUnneeded(removed);
|
||||||
|
|
||||||
mVcnNetworkProvider.registerListener(mListener);
|
mVcnNetworkProvider.registerListener(mListener);
|
||||||
for (NetworkRequest request : requests) {
|
for (NetworkRequest request : requests) {
|
||||||
|
|||||||
Reference in New Issue
Block a user