Loading services/core/java/com/android/server/VcnManagementService.java +55 −11 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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} Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -583,9 +619,12 @@ 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 { // TODO(b/193687515): Support multiple VCNs active at the same time if (isActiveSubGroup(subscriptionGroup, mLastSnapshot)) { startVcnLocked(subscriptionGroup, config); startVcnLocked(subscriptionGroup, config); } } } } } /** /** * Sets a VCN config for a given subscription group. * Sets a VCN config for a given subscription group. Loading Loading @@ -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); Loading services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +51 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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() { Loading @@ -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); } } /** /** Loading Loading @@ -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)) { Loading Loading @@ -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"); Loading @@ -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() { Loading Loading @@ -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 Loading @@ -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); } } Loading @@ -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); Loading @@ -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 + " }"; + " }"; } } Loading @@ -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 { Loading @@ -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(); } } } } } tests/vcn/java/com/android/server/VcnManagementServiceTest.java +204 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +42 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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() { Loading Loading @@ -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 { Loading Loading @@ -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)); Loading @@ -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)), Loading tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading
services/core/java/com/android/server/VcnManagementService.java +55 −11 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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} Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -583,9 +619,12 @@ 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 { // TODO(b/193687515): Support multiple VCNs active at the same time if (isActiveSubGroup(subscriptionGroup, mLastSnapshot)) { startVcnLocked(subscriptionGroup, config); startVcnLocked(subscriptionGroup, config); } } } } } /** /** * Sets a VCN config for a given subscription group. * Sets a VCN config for a given subscription group. Loading Loading @@ -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); Loading
services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +51 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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() { Loading @@ -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); } } /** /** Loading Loading @@ -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)) { Loading Loading @@ -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"); Loading @@ -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() { Loading Loading @@ -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 Loading @@ -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); } } Loading @@ -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); Loading @@ -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 + " }"; + " }"; } } Loading @@ -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 { Loading @@ -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(); } } } } }
tests/vcn/java/com/android/server/VcnManagementServiceTest.java +204 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes
tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +42 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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() { Loading Loading @@ -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 { Loading Loading @@ -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)); Loading @@ -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)), Loading
tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading