Prevent changes to immutable capabilities for carrier wifi
This change prevents carrier wifi from having changes to the RESTRICTED network capability, which is an immutable capability. Bug: 184101137 Test: atest FrameworksVcnTests Change-Id: I802d36a754d961c9928a2e642e25f1b25b8be12d
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
|
||||
@@ -35,7 +37,9 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.vcn.IVcnManagementService;
|
||||
import android.net.vcn.IVcnStatusCallback;
|
||||
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
|
||||
@@ -161,6 +165,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
@NonNull private final VcnContext mVcnContext;
|
||||
@NonNull private final BroadcastReceiver mPkgChangeReceiver;
|
||||
|
||||
@NonNull
|
||||
private final TrackingNetworkCallback mTrackingNetworkCallback = new TrackingNetworkCallback();
|
||||
|
||||
/** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */
|
||||
@Nullable private LocationPermissionChecker mLocationPermissionChecker;
|
||||
|
||||
@@ -357,6 +364,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
public void systemReady() {
|
||||
mContext.getSystemService(ConnectivityManager.class)
|
||||
.registerNetworkProvider(mNetworkProvider);
|
||||
mContext.getSystemService(ConnectivityManager.class)
|
||||
.registerNetworkCallback(
|
||||
new NetworkRequest.Builder().clearCapabilities().build(),
|
||||
mTrackingNetworkCallback);
|
||||
mTelephonySubscriptionTracker.register();
|
||||
mLocationPermissionChecker = mDeps.newLocationPermissionChecker(mVcnContext.getContext());
|
||||
}
|
||||
@@ -792,8 +803,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
||||
}
|
||||
|
||||
final NetworkCapabilities result = ncBuilder.build();
|
||||
return new VcnUnderlyingNetworkPolicy(
|
||||
false /* isTearDownRequested */, ncBuilder.build());
|
||||
mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -940,6 +952,49 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
@Nullable String exceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* TrackingNetworkCallback tracks all active networks
|
||||
*
|
||||
* <p>This is used to ensure that no underlying networks have immutable capabilities changed
|
||||
* without requiring a Network restart.
|
||||
*/
|
||||
private class TrackingNetworkCallback extends ConnectivityManager.NetworkCallback {
|
||||
private final Map<Network, NetworkCapabilities> mCaps = new ArrayMap<>();
|
||||
|
||||
@Override
|
||||
public void onCapabilitiesChanged(Network network, NetworkCapabilities caps) {
|
||||
synchronized (mCaps) {
|
||||
mCaps.put(network, caps);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLost(Network network) {
|
||||
synchronized (mCaps) {
|
||||
mCaps.remove(network);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
|
||||
if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubIds() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (mCaps) {
|
||||
for (NetworkCapabilities existing : mCaps.values()) {
|
||||
if (existing.hasTransport(TRANSPORT_WIFI)
|
||||
&& caps.getSubIds().equals(existing.getSubIds())) {
|
||||
// Restart if any immutable capabilities have changed
|
||||
return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
!= caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** VcnCallbackImpl for Vcn signals sent up to VcnManagementService. */
|
||||
private class VcnCallbackImpl implements VcnCallback {
|
||||
@NonNull private final ParcelUuid mSubGroup;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.net.ConnectivityManager.NetworkCallback;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
@@ -55,8 +57,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkCapabilities.Transport;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.vcn.IVcnStatusCallback;
|
||||
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
|
||||
@@ -258,6 +262,10 @@ public class VcnManagementServiceTest {
|
||||
|
||||
verify(mConnMgr).registerNetworkProvider(any(VcnNetworkProvider.class));
|
||||
verify(mSubscriptionTracker).register();
|
||||
verify(mConnMgr)
|
||||
.registerNetworkCallback(
|
||||
eq(new NetworkRequest.Builder().clearCapabilities().build()),
|
||||
any(NetworkCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -706,10 +714,8 @@ public class VcnManagementServiceTest {
|
||||
.checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
|
||||
}
|
||||
|
||||
private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
|
||||
int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
|
||||
setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);
|
||||
|
||||
private NetworkCapabilities.Builder getNetworkCapabilitiesBuilderForTransport(
|
||||
int subId, int transport) {
|
||||
final NetworkCapabilities.Builder ncBuilder =
|
||||
new NetworkCapabilities.Builder()
|
||||
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||
@@ -718,7 +724,16 @@ public class VcnManagementServiceTest {
|
||||
ncBuilder.setSubIds(Collections.singleton(subId));
|
||||
}
|
||||
|
||||
return mVcnMgmtSvc.getUnderlyingNetworkPolicy(ncBuilder.build(), new LinkProperties());
|
||||
return ncBuilder;
|
||||
}
|
||||
|
||||
private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
|
||||
int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
|
||||
setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);
|
||||
|
||||
return mVcnMgmtSvc.getUnderlyingNetworkPolicy(
|
||||
getNetworkCapabilitiesBuilderForTransport(subId, transport).build(),
|
||||
new LinkProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -780,6 +795,53 @@ public class VcnManagementServiceTest {
|
||||
true /* isRestricted */);
|
||||
}
|
||||
|
||||
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
|
||||
mVcnMgmtSvc.systemReady();
|
||||
|
||||
final ArgumentCaptor<NetworkCallback> captor =
|
||||
ArgumentCaptor.forClass(NetworkCallback.class);
|
||||
verify(mConnMgr)
|
||||
.registerNetworkCallback(
|
||||
eq(new NetworkRequest.Builder().clearCapabilities().build()),
|
||||
captor.capture());
|
||||
captor.getValue().onCapabilitiesChanged(new Network(0), caps);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyVcnWifi_unrestrictingExistingNetworkRequiresRestart()
|
||||
throws Exception {
|
||||
final NetworkCapabilities existingNetworkCaps =
|
||||
getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
|
||||
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.build();
|
||||
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
|
||||
|
||||
// Trigger test without VCN instance alive; expect restart due to change of NOT_RESTRICTED
|
||||
// immutable capability
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(
|
||||
getNetworkCapabilitiesBuilderForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
|
||||
.build(),
|
||||
new LinkProperties());
|
||||
assertTrue(policy.isTeardownRequested());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyVcnWifi_restrictingExistingNetworkRequiresRestart()
|
||||
throws Exception {
|
||||
final NetworkCapabilities existingNetworkCaps =
|
||||
getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
|
||||
.build();
|
||||
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
|
||||
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
startVcnAndGetPolicyForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI);
|
||||
|
||||
assertTrue(policy.isTeardownRequested());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
|
||||
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */);
|
||||
|
||||
Reference in New Issue
Block a user