Merge "Prevent changes to immutable capabilities for carrier wifi" am: 9e7e3b780d

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1661227

Change-Id: Iac1b1cf962eedc5a6f5e172a508b7bf7402e48b7
This commit is contained in:
Benedict Wong
2021-04-05 18:08:23 +00:00
committed by Automerger Merge Worker
2 changed files with 123 additions and 6 deletions

View File

@@ -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;

View File

@@ -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 */);