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

Commit eb683dfe authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Create selectableSubscriptionInfoListFlow" into main

parents 4b2b590d ced86bf5
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)
    }