From ced86bf56d09a91cde44287dda83bf02b26e2254 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 12 Sep 2024 11:43:05 +0800 Subject: [PATCH] Create selectableSubscriptionInfoListFlow Which can be used in MobileNetworkSummaryController in the future. Bug: 366097262 Flag: EXEMPT refactor Test: manual - check Network & internet Test: unit tests Change-Id: Ia74af993646c2e1d53817f1e9f8ac3ef0b8fa97a --- .../network/SubscriptionInfoListViewModel.kt | 9 +-- .../settings/network/SubscriptionUtil.java | 4 +- .../telephony/SubscriptionRepository.kt | 71 ++++++++++--------- .../telephony/SubscriptionRepositoryTest.kt | 8 +-- 4 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/com/android/settings/network/SubscriptionInfoListViewModel.kt b/src/com/android/settings/network/SubscriptionInfoListViewModel.kt index df3b8bad278..fe505224e30 100644 --- a/src/com/android/settings/network/SubscriptionInfoListViewModel.kt +++ b/src/com/android/settings/network/SubscriptionInfoListViewModel.kt @@ -20,7 +20,7 @@ import android.app.Application 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.SubscriptionRepository import com.android.settings.network.telephony.subscriptionsChangedFlow import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted @@ -45,7 +45,8 @@ class SubscriptionInfoListViewModel(application: Application) : AndroidViewModel * Getting the Selectable SubscriptionInfo List from the SubscriptionRepository's * getAvailableSubscriptionInfoList */ - val selectableSubscriptionInfoListFlow = application.subscriptionsChangedFlow().map { - application.getSelectableSubscriptionInfoList() - }.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList()) + val selectableSubscriptionInfoListFlow = + SubscriptionRepository(application) + .selectableSubscriptionInfoListFlow() + .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 fcf15991306..aca2fc3b2e9 100644 --- a/src/com/android/settings/network/SubscriptionUtil.java +++ b/src/com/android/settings/network/SubscriptionUtil.java @@ -52,7 +52,7 @@ import com.android.settings.network.helper.SelectableSubscriptions; 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.SubscriptionRepository; import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity; import java.util.ArrayList; @@ -508,7 +508,7 @@ public class SubscriptionUtil { * @return list of user selectable subscriptions. */ public static List getSelectableSubscriptionInfoList(Context context) { - return SubscriptionRepositoryKt.getSelectableSubscriptionInfoList(context); + return new SubscriptionRepository(context).getSelectableSubscriptionInfoList(); } /** diff --git a/src/com/android/settings/network/telephony/SubscriptionRepository.kt b/src/com/android/settings/network/telephony/SubscriptionRepository.kt index 26ea9b3fc42..6b5b4cb4d43 100644 --- a/src/com/android/settings/network/telephony/SubscriptionRepository.kt +++ b/src/com/android/settings/network/telephony/SubscriptionRepository.kt @@ -42,13 +42,48 @@ private const val TAG = "SubscriptionRepository" class SubscriptionRepository(private val context: Context) { private val subscriptionManager = context.requireSubscriptionManager() + /** A cold flow of a list of subscriptions that are available and visible to the user. */ + fun selectableSubscriptionInfoListFlow(): Flow> = + context + .subscriptionsChangedFlow() + .map { getSelectableSubscriptionInfoList() } + .conflate() + .flowOn(Dispatchers.Default) + /** * Return a list of subscriptions that are available and visible to the user. * * @return list of user selectable subscriptions. */ - fun getSelectableSubscriptionInfoList(): List = - context.getSelectableSubscriptionInfoList() + fun getSelectableSubscriptionInfoList(): List { + 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, context, subInfo) + } + return visibleList + .groupBy { it.groupUuid } + .flatMap { (groupUuid, subInfos) -> + if (groupUuid == null) { + subInfos + } else { + // Multiple subscriptions in a group should only have one representative. + // It should be the current active primary subscription if any, or the primary + // subscription with minimum subscription id. + subInfos + .filter { it.simSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX } + .ifEmpty { subInfos.sortedBy { it.subscriptionId } } + .take(1) + } + } + // Matching the sorting order in + // SubscriptionManagerService.getAvailableSubscriptionInfoList + .sortedWith(compareBy({ it.sortableSimSlotIndex }, { it.subscriptionId })) + .also { Log.d(TAG, "getSelectableSubscriptionInfoList: $it") } + } /** Flow of whether the subscription visible for the given [subId]. */ fun isSubscriptionVisibleFlow(subId: Int): Flow { @@ -154,38 +189,6 @@ fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo): Flow = fun Context.subscriptionsChangedFlow(): Flow = SubscriptionRepository(this).subscriptionsChangedFlow() -/** - * Return a list of subscriptions that are available and visible to the user. - * - * @return list of user selectable subscriptions. - */ -fun Context.getSelectableSubscriptionInfoList(): List { - 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) - } - return visibleList - .groupBy { it.groupUuid } - .flatMap { (groupUuid, subInfos) -> - if (groupUuid == null) { - subInfos - } else { - // Multiple subscriptions in a group should only have one representative. - // It should be the current active primary subscription if any, or the primary - // subscription with minimum subscription id. - subInfos.filter { it.simSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX } - .ifEmpty { subInfos.sortedBy { it.subscriptionId } } - .take(1) - } - } - // Matching the sorting order in SubscriptionManagerService.getAvailableSubscriptionInfoList - .sortedWith(compareBy({ it.sortableSimSlotIndex }, { it.subscriptionId })) - .also { Log.d(TAG, "getSelectableSubscriptionInfoList: $it") } -} - /** Subscription with invalid sim slot index has lowest sort order. */ private val SubscriptionInfo.sortableSimSlotIndex: Int get() = if (simSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { 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 5dbc5340745..5052f57c588 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 @@ -120,7 +120,7 @@ class SubscriptionRepositoryTest { ) } - val subInfos = context.getSelectableSubscriptionInfoList() + val subInfos = repository.getSelectableSubscriptionInfoList() assertThat(subInfos.map { it.simSlotIndex }) .containsExactly(SIM_SLOT_INDEX_0, SIM_SLOT_INDEX_1).inOrder() @@ -141,7 +141,7 @@ class SubscriptionRepositoryTest { ) } - val subInfos = context.getSelectableSubscriptionInfoList() + val subInfos = repository.getSelectableSubscriptionInfoList() assertThat(subInfos.map { it.simSlotIndex }) .containsExactly(SIM_SLOT_INDEX_1, SubscriptionManager.INVALID_SIM_SLOT_INDEX).inOrder() @@ -164,7 +164,7 @@ class SubscriptionRepositoryTest { ) } - val subInfos = context.getSelectableSubscriptionInfoList() + val subInfos = repository.getSelectableSubscriptionInfoList() assertThat(subInfos.map { it.subscriptionId }).containsExactly(SUB_ID_IN_SLOT_0) } @@ -184,7 +184,7 @@ class SubscriptionRepositoryTest { ) } - val subInfos = context.getSelectableSubscriptionInfoList() + val subInfos = repository.getSelectableSubscriptionInfoList() assertThat(subInfos.map { it.subscriptionId }).containsExactly(SUB_ID_3_NOT_IN_SLOT) }