Limit VCNs to one running at a given time
This change ensures that there is only ever one VCN running at a given point in time, and that if the device has switched to using a subscription in a different subscription group, the VCN will immediately tear down. This ensures that when on a DSDS device, when the VCN-enabled subscription is not the default/active subscription, the other subscription's network will never be outscored by the VCN, and thus get torn down. Bug: 190761448 Test: atest FrameworksVcnTests Test: Manual testing to ensure common functionality Change-Id: I8031fab7502880d38420058451df41f47567c458
This commit is contained in:
@@ -24,6 +24,7 @@ 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_INACTIVE;
|
||||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
|
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
|
||||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
||||||
|
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
|
||||||
|
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
||||||
@@ -436,6 +437,15 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isActiveSubGroup(
|
||||||
|
@NonNull ParcelUuid subGrp, @NonNull TelephonySubscriptionSnapshot snapshot) {
|
||||||
|
if (subGrp == null || snapshot == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(subGrp, snapshot.getActiveDataSubscriptionGroup());
|
||||||
|
}
|
||||||
|
|
||||||
private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback {
|
private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback {
|
||||||
/**
|
/**
|
||||||
* Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker}
|
* Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker}
|
||||||
@@ -453,28 +463,49 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
|
|
||||||
// Start any VCN instances as necessary
|
// Start any VCN instances as necessary
|
||||||
for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
|
for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
|
||||||
|
final ParcelUuid subGrp = entry.getKey();
|
||||||
|
|
||||||
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
if (snapshot.packageHasPermissionsForSubscriptionGroup(
|
if (snapshot.packageHasPermissionsForSubscriptionGroup(
|
||||||
entry.getKey(), entry.getValue().getProvisioningPackageName())) {
|
subGrp, entry.getValue().getProvisioningPackageName())
|
||||||
if (!mVcns.containsKey(entry.getKey())) {
|
&& isActiveSubGroup(subGrp, snapshot)) {
|
||||||
startVcnLocked(entry.getKey(), entry.getValue());
|
if (!mVcns.containsKey(subGrp)) {
|
||||||
|
startVcnLocked(subGrp, entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel any scheduled teardowns for active subscriptions
|
// Cancel any scheduled teardowns for active subscriptions
|
||||||
mHandler.removeCallbacksAndMessages(mVcns.get(entry.getKey()));
|
mHandler.removeCallbacksAndMessages(mVcns.get(subGrp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
|
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
|
||||||
// delay)
|
// delay)
|
||||||
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
|
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
|
||||||
final VcnConfig config = mConfigs.get(entry.getKey());
|
final ParcelUuid subGrp = entry.getKey();
|
||||||
|
final VcnConfig config = mConfigs.get(subGrp);
|
||||||
|
|
||||||
|
final boolean isActiveSubGrp = isActiveSubGroup(subGrp, snapshot);
|
||||||
|
final boolean isValidActiveDataSubIdNotInVcnSubGrp =
|
||||||
|
isValidSubscriptionId(snapshot.getActiveDataSubscriptionId())
|
||||||
|
&& !isActiveSubGroup(subGrp, snapshot);
|
||||||
|
|
||||||
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
if (config == null
|
if (config == null
|
||||||
|| !snapshot.packageHasPermissionsForSubscriptionGroup(
|
|| !snapshot.packageHasPermissionsForSubscriptionGroup(
|
||||||
entry.getKey(), config.getProvisioningPackageName())) {
|
subGrp, config.getProvisioningPackageName())
|
||||||
final ParcelUuid uuidToTeardown = entry.getKey();
|
|| !isActiveSubGrp) {
|
||||||
|
final ParcelUuid uuidToTeardown = subGrp;
|
||||||
final Vcn instanceToTeardown = entry.getValue();
|
final Vcn instanceToTeardown = entry.getValue();
|
||||||
|
|
||||||
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
|
// If directly switching to a subscription not in the current group,
|
||||||
|
// teardown immediately to prevent other subscription's network from being
|
||||||
|
// outscored by the VCN. Otherwise, teardown after a delay to ensure that
|
||||||
|
// SIM profile switches do not trigger the VCN to cycle.
|
||||||
|
final long teardownDelayMs =
|
||||||
|
isValidActiveDataSubIdNotInVcnSubGrp
|
||||||
|
? 0
|
||||||
|
: CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS;
|
||||||
mHandler.postDelayed(() -> {
|
mHandler.postDelayed(() -> {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// Guard against case where this is run after a old instance was
|
// Guard against case where this is run after a old instance was
|
||||||
@@ -490,7 +521,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
|
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, instanceToTeardown, CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
}, instanceToTeardown, teardownDelayMs);
|
||||||
} else {
|
} else {
|
||||||
// If this VCN's status has not changed, update it with the new snapshot
|
// If this VCN's status has not changed, update it with the new snapshot
|
||||||
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
|
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
|
||||||
@@ -554,8 +585,13 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
|
private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
|
||||||
logDbg("Starting VCN config for subGrp: " + subscriptionGroup);
|
logDbg("Starting VCN config for subGrp: " + subscriptionGroup);
|
||||||
|
|
||||||
// TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
// VCN.
|
if (!mVcns.isEmpty()) {
|
||||||
|
// Only one VCN supported at a time; teardown all others before starting new one
|
||||||
|
for (ParcelUuid uuidToTeardown : mVcns.keySet()) {
|
||||||
|
stopVcnLocked(uuidToTeardown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup);
|
final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup);
|
||||||
|
|
||||||
@@ -583,7 +619,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
final Vcn vcn = mVcns.get(subscriptionGroup);
|
final Vcn vcn = mVcns.get(subscriptionGroup);
|
||||||
vcn.updateConfig(config);
|
vcn.updateConfig(config);
|
||||||
} else {
|
} else {
|
||||||
startVcnLocked(subscriptionGroup, config);
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
|
if (isActiveSubGroup(subscriptionGroup, mLastSnapshot)) {
|
||||||
|
startVcnLocked(subscriptionGroup, config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1008,6 +1047,11 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
void setLastSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
|
||||||
|
mLastSnapshot = Objects.requireNonNull(snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
private void logVdbg(String msg) {
|
private void logVdbg(String msg) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Slog.v(TAG, msg);
|
Slog.v(TAG, msg);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.telephony.CarrierConfigManager;
|
|||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||||
|
import android.telephony.TelephonyCallback;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -85,6 +86,8 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
@NonNull private final SubscriptionManager mSubscriptionManager;
|
@NonNull private final SubscriptionManager mSubscriptionManager;
|
||||||
@NonNull private final CarrierConfigManager mCarrierConfigManager;
|
@NonNull private final CarrierConfigManager mCarrierConfigManager;
|
||||||
|
|
||||||
|
@NonNull private final ActiveDataSubscriptionIdListener mActiveDataSubIdListener;
|
||||||
|
|
||||||
// TODO (Android T+): Add ability to handle multiple subIds per slot.
|
// TODO (Android T+): Add ability to handle multiple subIds per slot.
|
||||||
@NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
|
@NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
|
||||||
@NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
|
@NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
|
||||||
@@ -112,6 +115,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
|
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||||
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
||||||
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
|
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
|
||||||
|
mActiveDataSubIdListener = new ActiveDataSubscriptionIdListener();
|
||||||
|
|
||||||
mSubscriptionChangedListener =
|
mSubscriptionChangedListener =
|
||||||
new OnSubscriptionsChangedListener() {
|
new OnSubscriptionsChangedListener() {
|
||||||
@@ -124,16 +128,20 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
/** Registers the receivers, and starts tracking subscriptions. */
|
/** Registers the receivers, and starts tracking subscriptions. */
|
||||||
public void register() {
|
public void register() {
|
||||||
|
final HandlerExecutor executor = new HandlerExecutor(mHandler);
|
||||||
|
|
||||||
mContext.registerReceiver(
|
mContext.registerReceiver(
|
||||||
this, new IntentFilter(ACTION_CARRIER_CONFIG_CHANGED), null, mHandler);
|
this, new IntentFilter(ACTION_CARRIER_CONFIG_CHANGED), null, mHandler);
|
||||||
mSubscriptionManager.addOnSubscriptionsChangedListener(
|
mSubscriptionManager.addOnSubscriptionsChangedListener(
|
||||||
new HandlerExecutor(mHandler), mSubscriptionChangedListener);
|
executor, mSubscriptionChangedListener);
|
||||||
|
mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unregisters the receivers, and stops tracking subscriptions. */
|
/** Unregisters the receivers, and stops tracking subscriptions. */
|
||||||
public void unregister() {
|
public void unregister() {
|
||||||
mContext.unregisterReceiver(this);
|
mContext.unregisterReceiver(this);
|
||||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
|
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
|
||||||
|
mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,7 +193,8 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final TelephonySubscriptionSnapshot newSnapshot =
|
final TelephonySubscriptionSnapshot newSnapshot =
|
||||||
new TelephonySubscriptionSnapshot(newSubIdToInfoMap, privilegedPackages);
|
new TelephonySubscriptionSnapshot(
|
||||||
|
mDeps.getActiveDataSubscriptionId(), newSubIdToInfoMap, privilegedPackages);
|
||||||
|
|
||||||
// If snapshot was meaningfully updated, fire the callback
|
// If snapshot was meaningfully updated, fire the callback
|
||||||
if (!newSnapshot.equals(mCurrentSnapshot)) {
|
if (!newSnapshot.equals(mCurrentSnapshot)) {
|
||||||
@@ -242,16 +251,20 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
/** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
|
/** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
|
||||||
public static class TelephonySubscriptionSnapshot {
|
public static class TelephonySubscriptionSnapshot {
|
||||||
|
private final int mActiveDataSubId;
|
||||||
private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
|
private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
|
||||||
private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;
|
private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;
|
||||||
|
|
||||||
public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
|
public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
|
||||||
new TelephonySubscriptionSnapshot(Collections.emptyMap(), Collections.emptyMap());
|
new TelephonySubscriptionSnapshot(
|
||||||
|
INVALID_SUBSCRIPTION_ID, Collections.emptyMap(), Collections.emptyMap());
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
TelephonySubscriptionSnapshot(
|
TelephonySubscriptionSnapshot(
|
||||||
|
int activeDataSubId,
|
||||||
@NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
@NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
@NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
|
@NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
|
mActiveDataSubId = activeDataSubId;
|
||||||
Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
|
Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
|
||||||
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
|
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
|
||||||
|
|
||||||
@@ -265,6 +278,22 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
mPrivilegedPackages = Collections.unmodifiableMap(unmodifiableInnerSets);
|
mPrivilegedPackages = Collections.unmodifiableMap(unmodifiableInnerSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the active subscription ID. May be INVALID_SUBSCRIPTION_ID */
|
||||||
|
public int getActiveDataSubscriptionId() {
|
||||||
|
return mActiveDataSubId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the active subscription group */
|
||||||
|
@Nullable
|
||||||
|
public ParcelUuid getActiveDataSubscriptionGroup() {
|
||||||
|
final SubscriptionInfo info = mSubIdToInfoMap.get(getActiveDataSubscriptionId());
|
||||||
|
if (info == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.getGroupUuid();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the active subscription groups */
|
/** Returns the active subscription groups */
|
||||||
@NonNull
|
@NonNull
|
||||||
public Set<ParcelUuid> getActiveSubscriptionGroups() {
|
public Set<ParcelUuid> getActiveSubscriptionGroups() {
|
||||||
@@ -313,7 +342,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mSubIdToInfoMap, mPrivilegedPackages);
|
return Objects.hash(mActiveDataSubId, mSubIdToInfoMap, mPrivilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -324,7 +353,8 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
final TelephonySubscriptionSnapshot other = (TelephonySubscriptionSnapshot) obj;
|
final TelephonySubscriptionSnapshot other = (TelephonySubscriptionSnapshot) obj;
|
||||||
|
|
||||||
return mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
|
return mActiveDataSubId == other.mActiveDataSubId
|
||||||
|
&& mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
|
||||||
&& mPrivilegedPackages.equals(other.mPrivilegedPackages);
|
&& mPrivilegedPackages.equals(other.mPrivilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +363,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
pw.println("TelephonySubscriptionSnapshot:");
|
pw.println("TelephonySubscriptionSnapshot:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
|
|
||||||
|
pw.println("mActiveDataSubId: " + mActiveDataSubId);
|
||||||
pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
|
pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
|
||||||
pw.println("mPrivilegedPackages: " + mPrivilegedPackages);
|
pw.println("mPrivilegedPackages: " + mPrivilegedPackages);
|
||||||
|
|
||||||
@@ -342,7 +373,8 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TelephonySubscriptionSnapshot{ "
|
return "TelephonySubscriptionSnapshot{ "
|
||||||
+ "mSubIdToInfoMap=" + mSubIdToInfoMap
|
+ "mActiveDataSubId=" + mActiveDataSubId
|
||||||
|
+ ", mSubIdToInfoMap=" + mSubIdToInfoMap
|
||||||
+ ", mPrivilegedPackages=" + mPrivilegedPackages
|
+ ", mPrivilegedPackages=" + mPrivilegedPackages
|
||||||
+ " }";
|
+ " }";
|
||||||
}
|
}
|
||||||
@@ -362,6 +394,14 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
void onNewSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot);
|
void onNewSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ActiveDataSubscriptionIdListener extends TelephonyCallback
|
||||||
|
implements TelephonyCallback.ActiveDataSubscriptionIdListener {
|
||||||
|
@Override
|
||||||
|
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||||
|
handleSubscriptionsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** External static dependencies for test injection */
|
/** External static dependencies for test injection */
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
public static class Dependencies {
|
public static class Dependencies {
|
||||||
@@ -369,5 +409,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
public boolean isConfigForIdentifiedCarrier(PersistableBundle bundle) {
|
public boolean isConfigForIdentifiedCarrier(PersistableBundle bundle) {
|
||||||
return CarrierConfigManager.isConfigForIdentifiedCarrier(bundle);
|
return CarrierConfigManager.isConfigForIdentifiedCarrier(bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the active Subscription ID */
|
||||||
|
public int getActiveDataSubscriptionId() {
|
||||||
|
return SubscriptionManager.getActiveDataSubscriptionId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
|||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
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_ACTIVE;
|
||||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
||||||
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
||||||
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
|
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ import static org.mockito.Mockito.doThrow;
|
|||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -99,6 +101,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -227,6 +230,7 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
setupMockedCarrierPrivilege(true);
|
setupMockedCarrierPrivilege(true);
|
||||||
mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps);
|
mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps);
|
||||||
|
setupActiveSubscription(TEST_UUID_1);
|
||||||
|
|
||||||
doReturn(mMockIBinder).when(mMockPolicyListener).asBinder();
|
doReturn(mMockIBinder).when(mMockPolicyListener).asBinder();
|
||||||
doReturn(mMockIBinder).when(mMockStatusCallback).asBinder();
|
doReturn(mMockIBinder).when(mMockStatusCallback).asBinder();
|
||||||
@@ -300,23 +304,65 @@ public class VcnManagementServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
Set<ParcelUuid> activeSubscriptionGroups) {
|
ParcelUuid activeDataSubGrp, Set<ParcelUuid> activeSubscriptionGroups) {
|
||||||
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
activeSubscriptionGroups, Collections.emptyMap());
|
activeDataSubGrp, activeSubscriptionGroups, Collections.emptyMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
Set<ParcelUuid> activeSubscriptionGroups, Map<Integer, ParcelUuid> subIdToGroupMap) {
|
ParcelUuid activeDataSubGrp,
|
||||||
|
Set<ParcelUuid> activeSubscriptionGroups,
|
||||||
|
Map<Integer, ParcelUuid> subIdToGroupMap) {
|
||||||
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
activeSubscriptionGroups, subIdToGroupMap, true /* hasCarrierPrivileges */);
|
activeDataSubGrp,
|
||||||
|
activeSubscriptionGroups,
|
||||||
|
subIdToGroupMap,
|
||||||
|
true /* hasCarrierPrivileges */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
ParcelUuid activeDataSubGrp,
|
||||||
|
Set<ParcelUuid> activeSubscriptionGroups,
|
||||||
|
Map<Integer, ParcelUuid> subIdToGroupMap,
|
||||||
|
boolean hasCarrierPrivileges) {
|
||||||
|
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID,
|
||||||
|
activeDataSubGrp,
|
||||||
|
activeSubscriptionGroups,
|
||||||
|
subIdToGroupMap,
|
||||||
|
hasCarrierPrivileges);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
int activeDataSubId,
|
||||||
|
ParcelUuid activeDataSubGrp,
|
||||||
|
Set<ParcelUuid> activeSubscriptionGroups,
|
||||||
|
Map<Integer, ParcelUuid> subIdToGroupMap,
|
||||||
|
boolean hasCarrierPrivileges) {
|
||||||
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
|
buildSubscriptionSnapshot(
|
||||||
|
activeDataSubId,
|
||||||
|
activeDataSubGrp,
|
||||||
|
activeSubscriptionGroups,
|
||||||
|
subIdToGroupMap,
|
||||||
|
hasCarrierPrivileges);
|
||||||
|
|
||||||
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
|
cb.onNewSnapshot(snapshot);
|
||||||
|
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TelephonySubscriptionSnapshot buildSubscriptionSnapshot(
|
||||||
|
int activeDataSubId,
|
||||||
|
ParcelUuid activeDataSubGrp,
|
||||||
Set<ParcelUuid> activeSubscriptionGroups,
|
Set<ParcelUuid> activeSubscriptionGroups,
|
||||||
Map<Integer, ParcelUuid> subIdToGroupMap,
|
Map<Integer, ParcelUuid> subIdToGroupMap,
|
||||||
boolean hasCarrierPrivileges) {
|
boolean hasCarrierPrivileges) {
|
||||||
final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class);
|
final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class);
|
||||||
doReturn(activeSubscriptionGroups).when(snapshot).getActiveSubscriptionGroups();
|
doReturn(activeSubscriptionGroups).when(snapshot).getActiveSubscriptionGroups();
|
||||||
|
doReturn(activeDataSubGrp).when(snapshot).getActiveDataSubscriptionGroup();
|
||||||
|
doReturn(activeDataSubId).when(snapshot).getActiveDataSubscriptionId();
|
||||||
|
|
||||||
final Set<String> privilegedPackages =
|
final Set<String> privilegedPackages =
|
||||||
(activeSubscriptionGroups == null || activeSubscriptionGroups.isEmpty())
|
(activeSubscriptionGroups == null || activeSubscriptionGroups.isEmpty())
|
||||||
@@ -343,12 +389,19 @@ public class VcnManagementServiceTest {
|
|||||||
return subIds;
|
return subIds;
|
||||||
}).when(snapshot).getAllSubIdsInGroup(any());
|
}).when(snapshot).getAllSubIdsInGroup(any());
|
||||||
|
|
||||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
|
||||||
cb.onNewSnapshot(snapshot);
|
|
||||||
|
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupActiveSubscription(ParcelUuid activeDataSubGrp) {
|
||||||
|
mVcnMgmtSvc.setLastSnapshot(
|
||||||
|
buildSubscriptionSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID,
|
||||||
|
activeDataSubGrp,
|
||||||
|
Collections.emptySet(),
|
||||||
|
Collections.emptyMap(),
|
||||||
|
true /* hasCarrierPrivileges */));
|
||||||
|
}
|
||||||
|
|
||||||
private TelephonySubscriptionTrackerCallback getTelephonySubscriptionTrackerCallback() {
|
private TelephonySubscriptionTrackerCallback getTelephonySubscriptionTrackerCallback() {
|
||||||
final ArgumentCaptor<TelephonySubscriptionTrackerCallback> captor =
|
final ArgumentCaptor<TelephonySubscriptionTrackerCallback> captor =
|
||||||
ArgumentCaptor.forClass(TelephonySubscriptionTrackerCallback.class);
|
ArgumentCaptor.forClass(TelephonySubscriptionTrackerCallback.class);
|
||||||
@@ -372,25 +425,56 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTelephonyNetworkTrackerCallbackStartsInstances() throws Exception {
|
public void testTelephonyNetworkTrackerCallbackStartsInstances() throws Exception {
|
||||||
|
// Add a record for a non-active SIM
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
|
|
||||||
TelephonySubscriptionSnapshot snapshot =
|
TelephonySubscriptionSnapshot snapshot =
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_1, new ArraySet<>(Arrays.asList(TEST_UUID_1, TEST_UUID_2)));
|
||||||
verify(mMockDeps)
|
verify(mMockDeps)
|
||||||
.newVcnContext(
|
.newVcnContext(
|
||||||
eq(mMockContext),
|
eq(mMockContext),
|
||||||
eq(mTestLooper.getLooper()),
|
eq(mTestLooper.getLooper()),
|
||||||
any(VcnNetworkProvider.class),
|
any(VcnNetworkProvider.class),
|
||||||
anyBoolean());
|
anyBoolean());
|
||||||
|
|
||||||
|
// Verify that only the VCN for the active data SIM was started.
|
||||||
verify(mMockDeps)
|
verify(mMockDeps)
|
||||||
.newVcn(eq(mVcnContext), eq(TEST_UUID_1), eq(TEST_VCN_CONFIG), eq(snapshot), any());
|
.newVcn(eq(mVcnContext), eq(TEST_UUID_1), eq(TEST_VCN_CONFIG), eq(snapshot), any());
|
||||||
|
verify(mMockDeps, never())
|
||||||
|
.newVcn(eq(mVcnContext), eq(TEST_UUID_2), eq(TEST_VCN_CONFIG), eq(snapshot), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTelephonyNetworkTrackerCallbackSwitchingActiveDataStartsAndStopsInstances()
|
||||||
|
throws Exception {
|
||||||
|
// Add a record for a non-active SIM
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_1);
|
||||||
|
|
||||||
|
TelephonySubscriptionSnapshot snapshot =
|
||||||
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_2, new ArraySet<>(Arrays.asList(TEST_UUID_1, TEST_UUID_2)));
|
||||||
|
|
||||||
|
// Verify that a new VCN for UUID_2 was started, and the old instance was torn down
|
||||||
|
// immediately
|
||||||
|
verify(mMockDeps)
|
||||||
|
.newVcn(eq(mVcnContext), eq(TEST_UUID_2), eq(TEST_VCN_CONFIG), eq(snapshot), any());
|
||||||
|
verify(vcn).teardownAsynchronously();
|
||||||
|
assertEquals(1, mVcnMgmtSvc.getAllVcns().size());
|
||||||
|
assertFalse(mVcnMgmtSvc.getAllVcns().containsKey(TEST_UUID_1));
|
||||||
|
assertTrue(mVcnMgmtSvc.getAllVcns().containsKey(TEST_UUID_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTelephonyNetworkTrackerCallbackStopsInstances() throws Exception {
|
public void testTelephonyNetworkTrackerCallbackStopsInstances() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
|
||||||
|
|
||||||
// Verify teardown after delay
|
// Verify teardown after delay
|
||||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||||
@@ -399,20 +483,77 @@ public class VcnManagementServiceTest {
|
|||||||
verify(mMockPolicyListener).onPolicyChanged();
|
verify(mMockPolicyListener).onPolicyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTelephonyNetworkTrackerCallbackSwitchToNewSubscriptionImmediatelyTearsDown()
|
||||||
|
throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
|
|
||||||
|
// Simulate switch to different default data subscription that does not have a VCN.
|
||||||
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID,
|
||||||
|
null /* activeDataSubscriptionGroup */,
|
||||||
|
Collections.emptySet(),
|
||||||
|
Collections.emptyMap(),
|
||||||
|
false /* hasCarrierPrivileges */);
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
verify(vcn).teardownAsynchronously();
|
||||||
|
assertEquals(0, mVcnMgmtSvc.getAllVcns().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests an intermediate state where carrier privileges are marked as lost before active data
|
||||||
|
* subId changes during a SIM ejection.
|
||||||
|
*
|
||||||
|
* <p>The expected outcome is that the VCN is torn down after a delay, as opposed to
|
||||||
|
* immediately.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testTelephonyNetworkTrackerCallbackLostCarrierPrivilegesBeforeActiveDataSubChanges()
|
||||||
|
throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
|
|
||||||
|
// Simulate privileges lost
|
||||||
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID,
|
||||||
|
TEST_UUID_2,
|
||||||
|
Collections.emptySet(),
|
||||||
|
Collections.emptyMap(),
|
||||||
|
false /* hasCarrierPrivileges */);
|
||||||
|
|
||||||
|
// Verify teardown after delay
|
||||||
|
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
verify(vcn).teardownAsynchronously();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTelephonyNetworkTrackerCallbackSimSwitchesDoNotKillVcnInstances()
|
public void testTelephonyNetworkTrackerCallbackSimSwitchesDoNotKillVcnInstances()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
|
|
||||||
// Simulate SIM unloaded
|
// Simulate SIM unloaded
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
INVALID_SUBSCRIPTION_ID,
|
||||||
|
null /* activeDataSubscriptionGroup */,
|
||||||
|
Collections.emptySet(),
|
||||||
|
Collections.emptyMap(),
|
||||||
|
false /* hasCarrierPrivileges */);
|
||||||
|
|
||||||
// Simulate new SIM loaded right during teardown delay.
|
// Simulate new SIM loaded right during teardown delay.
|
||||||
mTestLooper.moveTimeForward(
|
mTestLooper.moveTimeForward(
|
||||||
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
|
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||||
|
|
||||||
// Verify that even after the full timeout duration, the VCN instance is not torn down
|
// Verify that even after the full timeout duration, the VCN instance is not torn down
|
||||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||||
@@ -422,11 +563,13 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTelephonyNetworkTrackerCallbackDoesNotKillNewVcnInstances() throws Exception {
|
public void testTelephonyNetworkTrackerCallbackDoesNotKillNewVcnInstances() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||||
final Vcn oldInstance = startAndGetVcnInstance(TEST_UUID_2);
|
final Vcn oldInstance = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
|
|
||||||
// Simulate SIM unloaded
|
// Simulate SIM unloaded
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
|
||||||
|
|
||||||
// Config cleared, SIM reloaded & config re-added right before teardown delay, staring new
|
// Config cleared, SIM reloaded & config re-added right before teardown delay, staring new
|
||||||
// vcnInstance.
|
// vcnInstance.
|
||||||
@@ -434,6 +577,7 @@ public class VcnManagementServiceTest {
|
|||||||
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
|
||||||
|
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||||
final Vcn newInstance = startAndGetVcnInstance(TEST_UUID_2);
|
final Vcn newInstance = startAndGetVcnInstance(TEST_UUID_2);
|
||||||
|
|
||||||
// Verify that new instance was different, and the old one was torn down
|
// Verify that new instance was different, and the old one was torn down
|
||||||
@@ -537,6 +681,31 @@ public class VcnManagementServiceTest {
|
|||||||
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
|
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetVcnConfigNonActiveSimDoesNotStartVcn() throws Exception {
|
||||||
|
// Use a different UUID to simulate a new VCN config.
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
|
assertEquals(TEST_VCN_CONFIG, mVcnMgmtSvc.getConfigs().get(TEST_UUID_2));
|
||||||
|
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
|
||||||
|
|
||||||
|
verify(mMockDeps, never()).newVcn(any(), any(), any(), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetVcnConfigActiveSimTearsDownExistingVcnsImmediately() throws Exception {
|
||||||
|
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_1);
|
||||||
|
|
||||||
|
// Use a different UUID to simulate a new VCN config.
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
|
|
||||||
|
verify(mMockDeps, times(2)).newVcn(any(), any(), any(), any(), any());
|
||||||
|
verify(vcn).teardownAsynchronously();
|
||||||
|
assertEquals(1, mVcnMgmtSvc.getAllVcns().size());
|
||||||
|
assertFalse(mVcnMgmtSvc.getAllVcns().containsKey(TEST_UUID_1));
|
||||||
|
assertTrue(mVcnMgmtSvc.getAllVcns().containsKey(TEST_UUID_2));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetVcnConfigTestModeRequiresPermission() throws Exception {
|
public void testSetVcnConfigTestModeRequiresPermission() throws Exception {
|
||||||
doThrow(new SecurityException("Requires MANAGE_TEST_NETWORKS"))
|
doThrow(new SecurityException("Requires MANAGE_TEST_NETWORKS"))
|
||||||
@@ -561,7 +730,7 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
|
public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
|
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||||
|
|
||||||
mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
|
||||||
verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
|
verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
|
||||||
@@ -635,7 +804,9 @@ public class VcnManagementServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetVcnConfigClearVcnConfigStartsUpdatesAndTeardsDownVcns() throws Exception {
|
public void testSetVcnConfigClearVcnConfigStartsUpdatesAndTearsDownVcns() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
// Use a different UUID to simulate a new VCN config.
|
// Use a different UUID to simulate a new VCN config.
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
final Map<ParcelUuid, Vcn> vcnInstances = mVcnMgmtSvc.getAllVcns();
|
final Map<ParcelUuid, Vcn> vcnInstances = mVcnMgmtSvc.getAllVcns();
|
||||||
@@ -646,12 +817,7 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
// Verify Vcn is started
|
// Verify Vcn is started
|
||||||
verify(mMockDeps)
|
verify(mMockDeps)
|
||||||
.newVcn(
|
.newVcn(eq(mVcnContext), eq(TEST_UUID_2), eq(TEST_VCN_CONFIG), any(), any());
|
||||||
eq(mVcnContext),
|
|
||||||
eq(TEST_UUID_2),
|
|
||||||
eq(TEST_VCN_CONFIG),
|
|
||||||
eq(TelephonySubscriptionSnapshot.EMPTY_SNAPSHOT),
|
|
||||||
any());
|
|
||||||
|
|
||||||
// Verify Vcn is updated if it was previously started
|
// Verify Vcn is updated if it was previously started
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
@@ -693,7 +859,7 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
// Assert that if both UUID 1 and 2 are provisioned, the caller only gets ones that they are
|
// Assert that if both UUID 1 and 2 are provisioned, the caller only gets ones that they are
|
||||||
// privileged for.
|
// privileged for.
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
|
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_1, Collections.singleton(TEST_UUID_1));
|
||||||
final List<ParcelUuid> subGrps =
|
final List<ParcelUuid> subGrps =
|
||||||
mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
|
||||||
assertEquals(Collections.singletonList(TEST_UUID_1), subGrps);
|
assertEquals(Collections.singletonList(TEST_UUID_1), subGrps);
|
||||||
@@ -760,6 +926,7 @@ public class VcnManagementServiceTest {
|
|||||||
int subId, ParcelUuid subGrp, boolean isVcnActive, boolean hasCarrierPrivileges) {
|
int subId, ParcelUuid subGrp, boolean isVcnActive, boolean hasCarrierPrivileges) {
|
||||||
mVcnMgmtSvc.systemReady();
|
mVcnMgmtSvc.systemReady();
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
subGrp,
|
||||||
Collections.singleton(subGrp),
|
Collections.singleton(subGrp),
|
||||||
Collections.singletonMap(subId, subGrp),
|
Collections.singletonMap(subId, subGrp),
|
||||||
hasCarrierPrivileges);
|
hasCarrierPrivileges);
|
||||||
@@ -927,18 +1094,23 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSubscriptionSnapshotUpdateNotifiesVcn() {
|
public void testSubscriptionSnapshotUpdateNotifiesVcn() {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
final Map<ParcelUuid, Vcn> vcnInstances = mVcnMgmtSvc.getAllVcns();
|
final Map<ParcelUuid, Vcn> vcnInstances = mVcnMgmtSvc.getAllVcns();
|
||||||
final Vcn vcnInstance = vcnInstances.get(TEST_UUID_2);
|
final Vcn vcnInstance = vcnInstances.get(TEST_UUID_2);
|
||||||
|
|
||||||
TelephonySubscriptionSnapshot snapshot =
|
TelephonySubscriptionSnapshot snapshot =
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||||
|
|
||||||
verify(vcnInstance).updateSubscriptionSnapshot(eq(snapshot));
|
verify(vcnInstance).updateSubscriptionSnapshot(eq(snapshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddNewVcnUpdatesPolicyListener() throws Exception {
|
public void testAddNewVcnUpdatesPolicyListener() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
@@ -948,6 +1120,8 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveVcnUpdatesPolicyListener() throws Exception {
|
public void testRemoveVcnUpdatesPolicyListener() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
@@ -958,10 +1132,13 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVcnSubIdChangeUpdatesPolicyListener() throws Exception {
|
public void testVcnSubIdChangeUpdatesPolicyListener() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
startAndGetVcnInstance(TEST_UUID_2);
|
startAndGetVcnInstance(TEST_UUID_2);
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_2,
|
||||||
Collections.singleton(TEST_UUID_2),
|
Collections.singleton(TEST_UUID_2),
|
||||||
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_2));
|
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_2));
|
||||||
|
|
||||||
@@ -988,7 +1165,8 @@ public class VcnManagementServiceTest {
|
|||||||
private void verifyVcnSafeModeChangesNotifiesPolicyListeners(boolean enterSafeMode)
|
private void verifyVcnSafeModeChangesNotifiesPolicyListeners(boolean enterSafeMode)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
TelephonySubscriptionSnapshot snapshot =
|
TelephonySubscriptionSnapshot snapshot =
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_1, Collections.singleton(TEST_UUID_1));
|
||||||
|
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
@@ -1014,7 +1192,8 @@ public class VcnManagementServiceTest {
|
|||||||
boolean hasPermissionsforSubGroup)
|
boolean hasPermissionsforSubGroup)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
TelephonySubscriptionSnapshot snapshot =
|
TelephonySubscriptionSnapshot snapshot =
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(subGroup));
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
subGroup, Collections.singleton(subGroup));
|
||||||
|
|
||||||
setupSubscriptionAndStartVcn(
|
setupSubscriptionAndStartVcn(
|
||||||
TEST_SUBSCRIPTION_ID, subGroup, true /* isActive */, hasPermissionsforSubGroup);
|
TEST_SUBSCRIPTION_ID, subGroup, true /* isActive */, hasPermissionsforSubGroup);
|
||||||
@@ -1089,6 +1268,7 @@ public class VcnManagementServiceTest {
|
|||||||
// timeout so the VCN goes inactive.
|
// timeout so the VCN goes inactive.
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||||
|
TEST_UUID_1,
|
||||||
Collections.singleton(TEST_UUID_1),
|
Collections.singleton(TEST_UUID_1),
|
||||||
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_1),
|
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_1),
|
||||||
false /* hasCarrierPrivileges */);
|
false /* hasCarrierPrivileges */);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
|
|||||||
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
|
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
|
||||||
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||||
|
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
||||||
@@ -54,6 +55,7 @@ import android.telephony.CarrierConfigManager;
|
|||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||||
|
import android.telephony.TelephonyCallback;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
@@ -178,6 +180,14 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
return captor.getValue();
|
return captor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ActiveDataSubscriptionIdListener getActiveDataSubscriptionIdListener() {
|
||||||
|
final ArgumentCaptor<TelephonyCallback> captor =
|
||||||
|
ArgumentCaptor.forClass(TelephonyCallback.class);
|
||||||
|
verify(mTelephonyManager).registerTelephonyCallback(any(), captor.capture());
|
||||||
|
|
||||||
|
return (ActiveDataSubscriptionIdListener) captor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
private Intent buildTestBroadcastIntent(boolean hasValidSubscription) {
|
private Intent buildTestBroadcastIntent(boolean hasValidSubscription) {
|
||||||
Intent intent = new Intent(ACTION_CARRIER_CONFIG_CHANGED);
|
Intent intent = new Intent(ACTION_CARRIER_CONFIG_CHANGED);
|
||||||
intent.putExtra(EXTRA_SLOT_INDEX, TEST_SIM_SLOT_INDEX);
|
intent.putExtra(EXTRA_SLOT_INDEX, TEST_SIM_SLOT_INDEX);
|
||||||
@@ -196,7 +206,14 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
||||||
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
return new TelephonySubscriptionSnapshot(subIdToInfoMap, privilegedPackages);
|
return new TelephonySubscriptionSnapshot(0, subIdToInfoMap, privilegedPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
||||||
|
int activeSubId,
|
||||||
|
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
|
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
|
return new TelephonySubscriptionSnapshot(activeSubId, subIdToInfoMap, privilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNoActiveSubscriptions() {
|
private void verifyNoActiveSubscriptions() {
|
||||||
@@ -249,6 +266,26 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
verifyNoActiveSubscriptions();
|
verifyNoActiveSubscriptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnSubscriptionsChangedFired_onActiveSubIdsChanged() throws Exception {
|
||||||
|
setupReadySubIds();
|
||||||
|
setPrivilegedPackagesForMock(Collections.emptyList());
|
||||||
|
|
||||||
|
doReturn(TEST_SUBSCRIPTION_ID_2).when(mDeps).getActiveDataSubscriptionId();
|
||||||
|
final ActiveDataSubscriptionIdListener listener = getActiveDataSubscriptionIdListener();
|
||||||
|
listener.onActiveDataSubscriptionIdChanged(TEST_SUBSCRIPTION_ID_2);
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
ArgumentCaptor<TelephonySubscriptionSnapshot> snapshotCaptor =
|
||||||
|
ArgumentCaptor.forClass(TelephonySubscriptionSnapshot.class);
|
||||||
|
verify(mCallback).onNewSnapshot(snapshotCaptor.capture());
|
||||||
|
|
||||||
|
TelephonySubscriptionSnapshot snapshot = snapshotCaptor.getValue();
|
||||||
|
assertNotNull(snapshot);
|
||||||
|
assertEquals(TEST_SUBSCRIPTION_ID_2, snapshot.getActiveDataSubscriptionId());
|
||||||
|
assertEquals(TEST_PARCEL_UUID, snapshot.getActiveDataSubscriptionGroup());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnSubscriptionsChangedFired_WithReadySubidsNoPrivilegedPackages()
|
public void testOnSubscriptionsChangedFired_WithReadySubidsNoPrivilegedPackages()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -371,7 +408,8 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTelephonySubscriptionSnapshotGetGroupForSubId() throws Exception {
|
public void testTelephonySubscriptionSnapshotGetGroupForSubId() throws Exception {
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
new TelephonySubscriptionSnapshot(TEST_SUBID_TO_INFO_MAP, emptyMap());
|
new TelephonySubscriptionSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
|
||||||
|
|
||||||
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_1));
|
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_1));
|
||||||
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_2));
|
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_2));
|
||||||
@@ -380,7 +418,8 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTelephonySubscriptionSnapshotGetAllSubIdsInGroup() throws Exception {
|
public void testTelephonySubscriptionSnapshotGetAllSubIdsInGroup() throws Exception {
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
new TelephonySubscriptionSnapshot(TEST_SUBID_TO_INFO_MAP, emptyMap());
|
new TelephonySubscriptionSnapshot(
|
||||||
|
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
|
new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
|
||||||
|
|||||||
@@ -127,7 +127,9 @@ public class VcnGatewayConnectionTestBase {
|
|||||||
|
|
||||||
protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT =
|
protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT =
|
||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO), Collections.EMPTY_MAP);
|
TEST_SUB_ID,
|
||||||
|
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO),
|
||||||
|
Collections.EMPTY_MAP);
|
||||||
|
|
||||||
@NonNull protected final Context mContext;
|
@NonNull protected final Context mContext;
|
||||||
@NonNull protected final TestLooper mTestLooper;
|
@NonNull protected final TestLooper mTestLooper;
|
||||||
|
|||||||
Reference in New Issue
Block a user