Use old getSelectableSubscriptionInfoList
24D1-dev was using the
SubscriptionUtil.getSelectableSubscriptionInfoList().
Change I215b5a4615a3b3da6fc160f76c85c814210cc3ef cherry-pick the new
getSelectableSubscriptionInfoList from main, but not the latest version,
could produce an unexpected subscription order.
Main branch already fixed by I06b6c61304f9e6c9515b5f989294417ac3f82a60
and If7150bd2fa5c1b7d42fe34ef2e814ba540454ed8.
Fix: 341037896
Test: manual - on Mobile Settings
Merged-In: I06b6c61304f9e6c9515b5f989294417ac3f82a60
Change-Id: I5cb16b60a7bf5df5b048e539f89bfedc43aa1582
diff --git a/src/com/android/settings/network/SubscriptionInfoListViewModel.kt b/src/com/android/settings/network/SubscriptionInfoListViewModel.kt
index df3b8ba..1a83874 100644
--- a/src/com/android/settings/network/SubscriptionInfoListViewModel.kt
+++ b/src/com/android/settings/network/SubscriptionInfoListViewModel.kt
@@ -20,7 +20,6 @@
import android.telephony.SubscriptionManager
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
-import com.android.settings.network.telephony.getSelectableSubscriptionInfoList
import com.android.settings.network.telephony.subscriptionsChangedFlow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
@@ -46,6 +45,6 @@
* getAvailableSubscriptionInfoList
*/
val selectableSubscriptionInfoListFlow = application.subscriptionsChangedFlow().map {
- application.getSelectableSubscriptionInfoList()
+ SubscriptionUtil.getSelectableSubscriptionInfoList(application)
}.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList())
}
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index a379856..a9c4ac5 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -50,12 +50,12 @@
import com.android.settings.network.helper.SubscriptionAnnotation;
import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity;
import com.android.settings.network.telephony.EuiccRacConnectivityDialogActivity;
-import com.android.settings.network.telephony.SubscriptionRepositoryKt;
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -507,7 +507,40 @@
* @return list of user selectable subscriptions.
*/
public static List<SubscriptionInfo> getSelectableSubscriptionInfoList(Context context) {
- return SubscriptionRepositoryKt.getSelectableSubscriptionInfoList(context);
+ SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
+ List<SubscriptionInfo> availableList = subManager.getAvailableSubscriptionInfoList();
+ if (availableList == null) {
+ return null;
+ } else {
+ // Multiple subscriptions in a group should only have one representative.
+ // It should be the current active primary subscription if any, or any
+ // primary subscription.
+ List<SubscriptionInfo> selectableList = new ArrayList<>();
+ Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
+
+ for (SubscriptionInfo info : availableList) {
+ // Opportunistic subscriptions are considered invisible
+ // to users so they should never be returned.
+ if (!isSubscriptionVisible(subManager, context, info)) continue;
+
+ ParcelUuid groupUuid = info.getGroupUuid();
+ if (groupUuid == null) {
+ // Doesn't belong to any group. Add in the list.
+ selectableList.add(info);
+ } else if (!groupMap.containsKey(groupUuid)
+ || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
+ && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
+ // If it belongs to a group that has never been recorded or it's the current
+ // active subscription, add it in the list.
+ selectableList.remove(groupMap.get(groupUuid));
+ selectableList.add(info);
+ groupMap.put(groupUuid, info);
+ }
+
+ }
+ Log.d(TAG, "getSelectableSubscriptionInfoList: " + selectableList);
+ return selectableList;
+ }
}
/**
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt
index f89a0db..4c13d98 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt
@@ -67,7 +67,7 @@
}
private fun Context.isVisible(): Boolean {
- val subInfo = subscriptionRepository.getSelectableSubscriptionInfoList()
+ val subInfo = SubscriptionUtil.getAvailableSubscriptions(this)
.firstOrNull { it.subscriptionId == subId }
?: return false
// For eSIM, we always want the toggle. If telephony stack support disabling a pSIM
diff --git a/src/com/android/settings/network/telephony/SubscriptionRepository.kt b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
index 8aee297..db5216a 100644
--- a/src/com/android/settings/network/telephony/SubscriptionRepository.kt
+++ b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
@@ -20,9 +20,7 @@
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.util.Log
-import androidx.lifecycle.LifecycleOwner
import com.android.settings.network.SubscriptionUtil
-import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
@@ -36,14 +34,6 @@
private const val TAG = "SubscriptionRepository"
class SubscriptionRepository(private val context: Context) {
- /**
- * Return a list of subscriptions that are available and visible to the user.
- *
- * @return list of user selectable subscriptions.
- */
- fun getSelectableSubscriptionInfoList(): List<SubscriptionInfo> =
- context.getSelectableSubscriptionInfoList()
-
fun isSubscriptionEnabledFlow(subId: Int) = context.isSubscriptionEnabledFlow(subId)
}
@@ -77,36 +67,3 @@
awaitClose { subscriptionManager.removeOnSubscriptionsChangedListener(listener) }
}.conflate().onEach { Log.d(TAG, "subscriptions changed") }.flowOn(Dispatchers.Default)
-
-/**
- * Return a list of subscriptions that are available and visible to the user.
- *
- * @return list of user selectable subscriptions.
- */
-fun Context.getSelectableSubscriptionInfoList(): List<SubscriptionInfo> {
- val subscriptionManager = requireSubscriptionManager()
- val availableList = subscriptionManager.getAvailableSubscriptionInfoList() ?: return emptyList()
- val visibleList = availableList.filter { subInfo ->
- // Opportunistic subscriptions are considered invisible
- // to users so they should never be returned.
- SubscriptionUtil.isSubscriptionVisible(subscriptionManager, this, subInfo)
- }
- // Multiple subscriptions in a group should only have one representative.
- // It should be the current active primary subscription if any, or any primary subscription.
- val groupUuidToSelectedIdMap = visibleList
- .groupBy { it.groupUuid }
- .mapValues { (_, subInfos) ->
- subInfos.filter { it.simSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX }
- .ifEmpty { subInfos }
- .minOf { it.subscriptionId }
- }
-
- return visibleList
- .filter { subInfo ->
- val groupUuid = subInfo.groupUuid ?: return@filter true
- groupUuidToSelectedIdMap[groupUuid] == subInfo.subscriptionId
- }
- .sortedBy { it.subscriptionId }
- .also { Log.d(TAG, "getSelectableSubscriptionInfoList: $it") }
-}
-
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.kt
index e731333..77724e8 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.kt
@@ -30,8 +30,11 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
+import com.android.settings.network.SubscriptionUtil
import com.android.settingslib.spa.testutils.waitUntilExists
import kotlinx.coroutines.flow.flowOf
+import org.junit.After
+import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -58,7 +61,6 @@
}
private val mockSubscriptionRepository = mock<SubscriptionRepository> {
- on { getSelectableSubscriptionInfoList() } doReturn listOf(SubInfo)
on { isSubscriptionEnabledFlow(SUB_ID) } doReturn flowOf(false)
}
@@ -68,6 +70,16 @@
subscriptionRepository = mockSubscriptionRepository,
).apply { init(SUB_ID) }
+ @Before
+ fun setUp() {
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(listOf(SubInfo))
+ }
+
+ @After
+ fun tearDown() {
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(null)
+ }
+
@Test
fun isVisible_pSimAndCanDisablePhysicalSubscription_returnTrue() {
val pSimSubInfo = SubscriptionInfo.Builder().apply {
@@ -77,9 +89,7 @@
mockSubscriptionManager.stub {
on { canDisablePhysicalSubscription() } doReturn true
}
- mockSubscriptionRepository.stub {
- on { getSelectableSubscriptionInfoList() } doReturn listOf(pSimSubInfo)
- }
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(listOf(pSimSubInfo))
setContent()
@@ -96,9 +106,7 @@
mockSubscriptionManager.stub {
on { canDisablePhysicalSubscription() } doReturn false
}
- mockSubscriptionRepository.stub {
- on { getSelectableSubscriptionInfoList() } doReturn listOf(pSimSubInfo)
- }
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(listOf(pSimSubInfo))
setContent()
@@ -112,9 +120,7 @@
setId(SUB_ID)
setEmbedded(true)
}.build()
- mockSubscriptionRepository.stub {
- on { getSelectableSubscriptionInfoList() } doReturn listOf(eSimSubInfo)
- }
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(listOf(eSimSubInfo))
setContent()
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt
index 3f69155..15ca2f0 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt
@@ -24,7 +24,6 @@
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spa.testutils.toListWithTimeout
import com.google.common.truth.Truth.assertThat
-import java.util.UUID
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
@@ -83,65 +82,6 @@
}
@Test
- fun getSelectableSubscriptionInfoList_sortedBySubId() {
- mockSubscriptionManager.stub {
- on { getAvailableSubscriptionInfoList() } doReturn listOf(
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_2)
- }.build(),
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_1)
- }.build(),
- )
- }
-
- val subInfos = context.getSelectableSubscriptionInfoList()
-
- assertThat(subInfos.map { it.subscriptionId }).containsExactly(SUB_ID_1, SUB_ID_2).inOrder()
- }
-
- @Test
- fun getSelectableSubscriptionInfoList_sameGroupAndOneHasSlot_returnTheOneWithSimSlotIndex() {
- mockSubscriptionManager.stub {
- on { getAvailableSubscriptionInfoList() } doReturn listOf(
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_1)
- setGroupUuid(GROUP_UUID)
- }.build(),
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_2)
- setGroupUuid(GROUP_UUID)
- setSimSlotIndex(SIM_SLOT_INDEX)
- }.build(),
- )
- }
-
- val subInfos = context.getSelectableSubscriptionInfoList()
-
- assertThat(subInfos.map { it.subscriptionId }).containsExactly(SUB_ID_2)
- }
-
- @Test
- fun getSelectableSubscriptionInfoList_sameGroupAndNonHasSlot_returnTheOneWithMinimumSubId() {
- mockSubscriptionManager.stub {
- on { getAvailableSubscriptionInfoList() } doReturn listOf(
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_2)
- setGroupUuid(GROUP_UUID)
- }.build(),
- SubscriptionInfo.Builder().apply {
- setId(SUB_ID_1)
- setGroupUuid(GROUP_UUID)
- }.build(),
- )
- }
-
- val subInfos = context.getSelectableSubscriptionInfoList()
-
- assertThat(subInfos.map { it.subscriptionId }).containsExactly(SUB_ID_1)
- }
-
- @Test
fun phoneNumberFlow() = runBlocking {
mockSubscriptionManager.stub {
on { getPhoneNumber(SUB_ID_1) } doReturn NUMBER_1
@@ -158,9 +98,6 @@
private companion object {
const val SUB_ID_1 = 1
- const val SUB_ID_2 = 2
- val GROUP_UUID = UUID.randomUUID().toString()
- const val SIM_SLOT_INDEX = 1
const val NUMBER_1 = "000000001"
const val MCC = "310"
}