Merge changes Iaeb1871b,I1687df02
* changes: Add restrictions on underlying networks with CarrierConfig Support configuring the VCN restriction policy
This commit is contained in:
@@ -104,12 +104,23 @@ public class VcnManager {
|
||||
|
||||
// TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz
|
||||
|
||||
/**
|
||||
* Key for transports that need to be marked as restricted by the VCN
|
||||
*
|
||||
* <p>Defaults to TRANSPORT_WIFI if the config does not exist
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY =
|
||||
"vcn_restricted_transports";
|
||||
|
||||
/** List of Carrier Config options to extract from Carrier Config bundles. @hide */
|
||||
@NonNull
|
||||
public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
|
||||
new String[] {
|
||||
VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
||||
VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY
|
||||
VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
||||
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY
|
||||
};
|
||||
|
||||
private static final Map<
|
||||
|
||||
@@ -18,8 +18,11 @@ package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.DUMP;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.vcn.VcnGatewayConnectionConfig.ALLOWED_CAPABILITIES;
|
||||
import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
|
||||
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;
|
||||
@@ -53,6 +56,7 @@ import android.net.vcn.VcnManager.VcnStatusCode;
|
||||
import android.net.vcn.VcnUnderlyingNetworkPolicy;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -68,6 +72,7 @@ import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.LocalLog;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -83,6 +88,7 @@ import com.android.server.vcn.Vcn;
|
||||
import com.android.server.vcn.VcnContext;
|
||||
import com.android.server.vcn.VcnNetworkProvider;
|
||||
import com.android.server.vcn.util.PersistableBundleUtils;
|
||||
import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
@@ -159,6 +165,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
private static final long DUMP_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(5);
|
||||
private static final int LOCAL_LOG_LINE_COUNT = 512;
|
||||
|
||||
private static final Set<Integer> RESTRICTED_TRANSPORTS_DEFAULT =
|
||||
Collections.singleton(TRANSPORT_WIFI);
|
||||
|
||||
// Public for use in all other VCN classes
|
||||
@NonNull public static final LocalLog LOCAL_LOG = new LocalLog(LOCAL_LOG_LINE_COUNT);
|
||||
|
||||
@@ -361,6 +370,34 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
public LocationPermissionChecker newLocationPermissionChecker(@NonNull Context context) {
|
||||
return new LocationPermissionChecker(context);
|
||||
}
|
||||
|
||||
/** Gets the transports that need to be marked as restricted by the VCN */
|
||||
public Set<Integer> getRestrictedTransports(
|
||||
ParcelUuid subGrp, TelephonySubscriptionSnapshot lastSnapshot) {
|
||||
if (!Build.IS_ENG && !Build.IS_USERDEBUG) {
|
||||
return RESTRICTED_TRANSPORTS_DEFAULT;
|
||||
}
|
||||
|
||||
final PersistableBundleWrapper carrierConfig =
|
||||
lastSnapshot.getCarrierConfigForSubGrp(subGrp);
|
||||
if (carrierConfig == null) {
|
||||
return RESTRICTED_TRANSPORTS_DEFAULT;
|
||||
}
|
||||
|
||||
final int[] defaultValue =
|
||||
RESTRICTED_TRANSPORTS_DEFAULT.stream().mapToInt(i -> i).toArray();
|
||||
final int[] restrictedTransportsArray =
|
||||
carrierConfig.getIntArray(
|
||||
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
|
||||
defaultValue);
|
||||
|
||||
// Convert to a boxed set
|
||||
final Set<Integer> restrictedTransports = new ArraySet<>();
|
||||
for (int transport : restrictedTransportsArray) {
|
||||
restrictedTransports.add(transport);
|
||||
}
|
||||
return restrictedTransports;
|
||||
}
|
||||
}
|
||||
|
||||
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
||||
@@ -517,6 +554,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
boolean needNotifyAllPolicyListeners = false;
|
||||
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
|
||||
// delay)
|
||||
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
|
||||
@@ -564,6 +602,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
} else {
|
||||
// If this VCN's status has not changed, update it with the new snapshot
|
||||
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
|
||||
needNotifyAllPolicyListeners |=
|
||||
!Objects.equals(
|
||||
oldSnapshot.getCarrierConfigForSubGrp(subGrp),
|
||||
mLastSnapshot.getCarrierConfigForSubGrp(subGrp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,6 +615,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
getSubGroupToSubIdMappings(mLastSnapshot);
|
||||
if (!currSubGrpMappings.equals(oldSubGrpMappings)) {
|
||||
garbageCollectAndWriteVcnConfigsLocked();
|
||||
needNotifyAllPolicyListeners = true;
|
||||
}
|
||||
|
||||
if (needNotifyAllPolicyListeners) {
|
||||
notifyAllPolicyListenersLocked();
|
||||
}
|
||||
}
|
||||
@@ -917,6 +963,14 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
void addVcnUnderlyingNetworkPolicyListenerForTest(
|
||||
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
||||
synchronized (mLock) {
|
||||
addVcnUnderlyingNetworkPolicyListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
|
||||
@GuardedBy("mLock")
|
||||
@Override
|
||||
@@ -1000,7 +1054,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
|
||||
final ParcelUuid subGrp = getSubGroupForNetworkCapabilities(ncCopy);
|
||||
boolean isVcnManagedNetwork = false;
|
||||
boolean isRestrictedCarrierWifi = false;
|
||||
boolean isRestricted = false;
|
||||
synchronized (mLock) {
|
||||
final Vcn vcn = mVcns.get(subGrp);
|
||||
if (vcn != null) {
|
||||
@@ -1008,9 +1062,19 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
isVcnManagedNetwork = true;
|
||||
}
|
||||
|
||||
if (ncCopy.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||
// Carrier WiFi always restricted if VCN exists (even in safe mode).
|
||||
isRestrictedCarrierWifi = true;
|
||||
final Set<Integer> restrictedTransports =
|
||||
mDeps.getRestrictedTransports(subGrp, mLastSnapshot);
|
||||
for (int restrictedTransport : restrictedTransports) {
|
||||
if (ncCopy.hasTransport(restrictedTransport)) {
|
||||
if (restrictedTransport == TRANSPORT_CELLULAR) {
|
||||
// Only make a cell network as restricted when the VCN is in
|
||||
// active mode.
|
||||
isRestricted |= (vcn.getStatus() == VCN_STATUS_CODE_ACTIVE);
|
||||
} else {
|
||||
isRestricted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1024,14 +1088,16 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
ncBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||
}
|
||||
|
||||
if (isRestrictedCarrierWifi) {
|
||||
if (isRestricted) {
|
||||
ncBuilder.removeCapability(
|
||||
NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
||||
}
|
||||
|
||||
final NetworkCapabilities result = ncBuilder.build();
|
||||
final VcnUnderlyingNetworkPolicy policy = new VcnUnderlyingNetworkPolicy(
|
||||
mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
|
||||
mTrackingNetworkCallback
|
||||
.requiresRestartForImmutableCapabilityChanges(result),
|
||||
result);
|
||||
|
||||
logVdbg("getUnderlyingNetworkPolicy() called for caps: " + networkCapabilities
|
||||
+ "; and lp: " + linkProperties + "; result = " + policy);
|
||||
@@ -1296,15 +1362,38 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
|
||||
if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubscriptionIds() == null) {
|
||||
private Set<Integer> getNonTestTransportTypes(NetworkCapabilities caps) {
|
||||
final Set<Integer> transportTypes = new ArraySet<>();
|
||||
for (int t : caps.getTransportTypes()) {
|
||||
transportTypes.add(t);
|
||||
}
|
||||
return transportTypes;
|
||||
}
|
||||
|
||||
private boolean hasSameTransportsAndCapabilities(
|
||||
NetworkCapabilities caps, NetworkCapabilities capsOther) {
|
||||
if (!Objects.equals(
|
||||
getNonTestTransportTypes(caps), getNonTestTransportTypes(capsOther))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int capability : ALLOWED_CAPABILITIES) {
|
||||
if (caps.hasCapability(capability) != capsOther.hasCapability(capability)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean requiresRestartForImmutableCapabilityChanges(NetworkCapabilities caps) {
|
||||
if (caps.getSubscriptionIds() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (mCaps) {
|
||||
for (NetworkCapabilities existing : mCaps.values()) {
|
||||
if (existing.hasTransport(TRANSPORT_WIFI)
|
||||
&& caps.getSubscriptionIds().equals(existing.getSubscriptionIds())) {
|
||||
if (caps.getSubscriptionIds().equals(existing.getSubscriptionIds())
|
||||
&& hasSameTransportsAndCapabilities(caps, existing)) {
|
||||
// Restart if any immutable capabilities have changed
|
||||
return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
!= caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
|
||||
|
||||
@@ -390,8 +390,13 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
||||
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
|
||||
Objects.requireNonNull(subIdToCarrierConfigMap, "subIdToCarrierConfigMap was null");
|
||||
|
||||
mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
|
||||
mSubIdToCarrierConfigMap = Collections.unmodifiableMap(subIdToCarrierConfigMap);
|
||||
mSubIdToInfoMap =
|
||||
Collections.unmodifiableMap(
|
||||
new HashMap<Integer, SubscriptionInfo>(subIdToInfoMap));
|
||||
mSubIdToCarrierConfigMap =
|
||||
Collections.unmodifiableMap(
|
||||
new HashMap<Integer, PersistableBundleWrapper>(
|
||||
subIdToCarrierConfigMap));
|
||||
|
||||
final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
|
||||
for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
|
||||
|
||||
@@ -544,6 +544,20 @@ public class PersistableBundleUtils {
|
||||
return mBundle.getInt(key, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key, or null if no mapping of the desired
|
||||
* type exists for the given key or a null value is explicitly associated with the key.
|
||||
*
|
||||
* @param key a String, or null
|
||||
* @param defaultValue the value to return if key does not exist
|
||||
* @return an int[] value, or null
|
||||
*/
|
||||
@Nullable
|
||||
public int[] getIntArray(@Nullable String key, @Nullable int[] defaultValue) {
|
||||
final int[] value = mBundle.getIntArray(key);
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getHashCode(mBundle);
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
package com.android.server;
|
||||
|
||||
import static android.net.ConnectivityManager.NetworkCallback;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
|
||||
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;
|
||||
import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
@@ -95,6 +97,7 @@ import com.android.server.vcn.Vcn;
|
||||
import com.android.server.vcn.VcnContext;
|
||||
import com.android.server.vcn.VcnNetworkProvider;
|
||||
import com.android.server.vcn.util.PersistableBundleUtils;
|
||||
import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -252,6 +255,10 @@ public class VcnManagementServiceTest {
|
||||
.when(mMockContext)
|
||||
.enforceCallingOrSelfPermission(
|
||||
eq(android.Manifest.permission.NETWORK_FACTORY), any());
|
||||
|
||||
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
||||
.when(mMockDeps)
|
||||
.getRestrictedTransports(any(), any());
|
||||
}
|
||||
|
||||
|
||||
@@ -1031,63 +1038,188 @@ public class VcnManagementServiceTest {
|
||||
new LinkProperties());
|
||||
}
|
||||
|
||||
private void checkGetRestrictedTransports(
|
||||
ParcelUuid subGrp,
|
||||
TelephonySubscriptionSnapshot lastSnapshot,
|
||||
Set<Integer> expectedTransports) {
|
||||
Set<Integer> result =
|
||||
new VcnManagementService.Dependencies()
|
||||
.getRestrictedTransports(subGrp, lastSnapshot);
|
||||
assertEquals(expectedTransports, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyCellular() throws Exception {
|
||||
public void testGetRestrictedTransports() {
|
||||
final Set<Integer> restrictedTransports = new ArraySet<>();
|
||||
restrictedTransports.add(TRANSPORT_CELLULAR);
|
||||
restrictedTransports.add(TRANSPORT_WIFI);
|
||||
|
||||
PersistableBundle carrierConfigBundle = new PersistableBundle();
|
||||
carrierConfigBundle.putIntArray(
|
||||
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
|
||||
restrictedTransports.stream().mapToInt(i -> i).toArray());
|
||||
final PersistableBundleWrapper carrierConfig =
|
||||
new PersistableBundleWrapper(carrierConfigBundle);
|
||||
|
||||
final TelephonySubscriptionSnapshot lastSnapshot =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||
|
||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRestrictedTransports_noRestrictPolicyConfigured() {
|
||||
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
||||
|
||||
final PersistableBundleWrapper carrierConfig =
|
||||
new PersistableBundleWrapper(new PersistableBundle());
|
||||
final TelephonySubscriptionSnapshot lastSnapshot =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||
|
||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRestrictedTransports_noCarrierConfig() {
|
||||
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
||||
|
||||
final TelephonySubscriptionSnapshot lastSnapshot =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
|
||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||
}
|
||||
|
||||
private void checkGetUnderlyingNetworkPolicy(
|
||||
int transportType,
|
||||
boolean isTransportRestricted,
|
||||
boolean isActive,
|
||||
boolean expectVcnManaged,
|
||||
boolean expectRestricted)
|
||||
throws Exception {
|
||||
|
||||
final Set<Integer> restrictedTransports = new ArraySet();
|
||||
if (isTransportRestricted) {
|
||||
restrictedTransports.add(transportType);
|
||||
}
|
||||
doReturn(restrictedTransports).when(mMockDeps).getRestrictedTransports(any(), any());
|
||||
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
startVcnAndGetPolicyForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_CELLULAR);
|
||||
TEST_SUBSCRIPTION_ID, TEST_UUID_2, isActive, transportType);
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(),
|
||||
transportType,
|
||||
expectVcnManaged,
|
||||
expectRestricted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_unrestrictCell() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_CELLULAR,
|
||||
false /* isTransportRestricted */,
|
||||
true /* isActive */,
|
||||
true /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_unrestrictCellSafeMode() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_CELLULAR,
|
||||
false /* isTransportRestricted */,
|
||||
false /* isActive */,
|
||||
false /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_restrictCell() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_CELLULAR,
|
||||
true /* isTransportRestricted */,
|
||||
true /* isActive */,
|
||||
true /* expectVcnManaged */,
|
||||
true /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_restrictCellSafeMode() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_CELLULAR,
|
||||
true /* isTransportRestricted */,
|
||||
false /* isActive */,
|
||||
false /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_unrestrictWifi() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_WIFI,
|
||||
false /* isTransportRestricted */,
|
||||
true /* isActive */,
|
||||
true /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_unrestrictWifiSafeMode() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_WIFI,
|
||||
false /* isTransportRestricted */,
|
||||
false /* isActive */,
|
||||
false /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_restrictWifi() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_WIFI,
|
||||
true /* isTransportRestricted */,
|
||||
true /* isActive */,
|
||||
true /* expectVcnManaged */,
|
||||
true /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy_restrictWifiSafeMode() throws Exception {
|
||||
checkGetUnderlyingNetworkPolicy(
|
||||
TRANSPORT_WIFI,
|
||||
true /* isTransportRestricted */,
|
||||
false /* isActive */,
|
||||
false /* expectVcnManaged */,
|
||||
true /* expectRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyCell_restrictWifi() throws Exception {
|
||||
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
||||
.when(mMockDeps)
|
||||
.getRestrictedTransports(any(), any());
|
||||
|
||||
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isVcnActive */);
|
||||
|
||||
// Get the policy for a cellular network and expect it won't be affected by the wifi
|
||||
// restriction policy
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(
|
||||
getNetworkCapabilitiesBuilderForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
|
||||
.build(),
|
||||
new LinkProperties());
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(),
|
||||
TRANSPORT_CELLULAR,
|
||||
true /* isVcnManaged */,
|
||||
false /* isRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyCellular_safeMode() throws Exception {
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
startVcnAndGetPolicyForTransport(
|
||||
TEST_SUBSCRIPTION_ID,
|
||||
TEST_UUID_2,
|
||||
false /* isActive */,
|
||||
TRANSPORT_CELLULAR);
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(),
|
||||
NetworkCapabilities.TRANSPORT_CELLULAR,
|
||||
false /* isVcnManaged */,
|
||||
false /* isRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyWifi() throws Exception {
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
startVcnAndGetPolicyForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_WIFI);
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(),
|
||||
NetworkCapabilities.TRANSPORT_WIFI,
|
||||
true /* isVcnManaged */,
|
||||
true /* isRestricted */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyVcnWifi_safeMode() throws Exception {
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
startVcnAndGetPolicyForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI);
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(),
|
||||
NetworkCapabilities.TRANSPORT_WIFI,
|
||||
false /* isVcnManaged */,
|
||||
true /* isRestricted */);
|
||||
true /* expectVcnManaged */,
|
||||
false /* expectRestricted */);
|
||||
}
|
||||
|
||||
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
|
||||
@@ -1137,6 +1269,27 @@ public class VcnManagementServiceTest {
|
||||
assertTrue(policy.isTeardownRequested());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyForRestrictedImsWhenUnrestrictingCell()
|
||||
throws Exception {
|
||||
final NetworkCapabilities existingNetworkCaps =
|
||||
getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
|
||||
.addCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.removeCapability(NET_CAPABILITY_IMS)
|
||||
.build();
|
||||
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
|
||||
|
||||
final VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(
|
||||
getNetworkCapabilitiesBuilderForTransport(
|
||||
TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
|
||||
.addCapability(NET_CAPABILITY_IMS)
|
||||
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.build(),
|
||||
new LinkProperties());
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
|
||||
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */);
|
||||
@@ -1217,6 +1370,30 @@ public class VcnManagementServiceTest {
|
||||
verify(mMockPolicyListener).onPolicyChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVcnCarrierConfigChangeUpdatesPolicyListener() throws Exception {
|
||||
setupActiveSubscription(TEST_UUID_2);
|
||||
|
||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListenerForTest(mMockPolicyListener);
|
||||
|
||||
final TelephonySubscriptionSnapshot snapshot =
|
||||
buildSubscriptionSnapshot(
|
||||
TEST_SUBSCRIPTION_ID,
|
||||
TEST_UUID_2,
|
||||
Collections.singleton(TEST_UUID_2),
|
||||
Collections.emptyMap(),
|
||||
true /* hasCarrierPrivileges */);
|
||||
|
||||
final PersistableBundleWrapper mockCarrierConfig = mock(PersistableBundleWrapper.class);
|
||||
doReturn(mockCarrierConfig).when(snapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
cb.onNewSnapshot(snapshot);
|
||||
|
||||
verify(mMockPolicyListener).onPolicyChanged();
|
||||
}
|
||||
|
||||
private void triggerVcnSafeMode(
|
||||
@NonNull ParcelUuid subGroup,
|
||||
@NonNull TelephonySubscriptionSnapshot snapshot,
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.server.vcn;
|
||||
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
|
||||
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
|
||||
import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
|
||||
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
|
||||
@@ -39,6 +42,7 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
@@ -493,6 +497,37 @@ public class TelephonySubscriptionTrackerTest {
|
||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(emptyMap(), emptyMap())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierConfigUpdatedAfterValidTriggersCallbacks() throws Exception {
|
||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
|
||||
reset(mCallback);
|
||||
|
||||
final PersistableBundle updatedConfig = new PersistableBundle();
|
||||
updatedConfig.putIntArray(
|
||||
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
|
||||
new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR});
|
||||
doReturn(updatedConfig)
|
||||
.when(mCarrierConfigManager)
|
||||
.getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
|
||||
|
||||
Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
|
||||
subIdToCarrierConfigMap.put(
|
||||
TEST_SUBSCRIPTION_ID_1, new PersistableBundleWrapper(updatedConfig));
|
||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mCallback)
|
||||
.onNewSnapshot(
|
||||
eq(
|
||||
buildExpectedSnapshot(
|
||||
0,
|
||||
TEST_SUBID_TO_INFO_MAP,
|
||||
subIdToCarrierConfigMap,
|
||||
TEST_PRIVILEGED_PACKAGES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSlotClearedAfterValidTriggersCallbacks() throws Exception {
|
||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
|
||||
|
||||
Reference in New Issue
Block a user