Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ced86bf5 authored by Chaohui Wang's avatar Chaohui Wang
Browse files

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
parent 04ef86d1
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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())
}
+2 −2
Original line number Diff line number Diff line
@@ -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<SubscriptionInfo> getSelectableSubscriptionInfoList(Context context) {
        return SubscriptionRepositoryKt.getSelectableSubscriptionInfoList(context);
        return new SubscriptionRepository(context).getSelectableSubscriptionInfoList();
    }

    /**
+37 −34
Original line number Diff line number Diff line
@@ -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<List<SubscriptionInfo>> =
        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<SubscriptionInfo> =
        context.getSelectableSubscriptionInfoList()
    fun getSelectableSubscriptionInfoList(): List<SubscriptionInfo> {
        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<Boolean> {
@@ -154,38 +189,6 @@ fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo): Flow<String?> =
fun Context.subscriptionsChangedFlow(): Flow<Unit> =
    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<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)
    }
    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) {
+4 −4
Original line number Diff line number Diff line
@@ -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)
    }