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

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

Merge "Refine CrossSimCalling updating" into main

parents b210f35a 355ee0a1
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.telephony.ims.ImsStateCallback
import android.telephony.ims.RegistrationManager
import android.telephony.ims.feature.MmTelFeature
import android.util.Log
import androidx.annotation.VisibleForTesting
import kotlin.coroutines.resume
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
@@ -53,11 +54,6 @@ interface ImsMmTelRepository {
        @AccessNetworkConstants.TransportType transportType: Int,
    ): Flow<Boolean>

    suspend fun isSupported(
        @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int,
        @AccessNetworkConstants.TransportType transportType: Int,
    ): Boolean

    suspend fun setCrossSimCallingEnabled(enabled: Boolean)
}

@@ -143,7 +139,8 @@ class ImsMmTelRepositoryImpl(
    override fun isSupportedFlow(capability: Int, transportType: Int): Flow<Boolean> =
        imsReadyFlow().map { imsReady -> imsReady && isSupported(capability, transportType) }

    override suspend fun isSupported(
    @VisibleForTesting
    suspend fun isSupported(
        @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int,
        @AccessNetworkConstants.TransportType transportType: Int,
    ): Boolean = withContext(Dispatchers.Default) {
+51 −24
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.settings.SettingsEnums
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.android.settings.R
@@ -34,6 +35,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
@@ -43,9 +45,8 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.plus

@OptIn(ExperimentalCoroutinesApi::class)
class CrossSimCallingViewModel(
    private val application: Application,
) : AndroidViewModel(application) {
class CrossSimCallingViewModel(private val application: Application) :
    AndroidViewModel(application) {

    private val subscriptionRepository = SubscriptionRepository(application)
    private val dataSubscriptionRepository = DataSubscriptionRepository(application)
@@ -61,38 +62,45 @@ class CrossSimCallingViewModel(
                    subscriptionRepository.activeSubscriptionIdListFlow(),
                    dataSubscriptionRepository.defaultDataSubscriptionIdFlow(),
                ) { activeSubIds, defaultDataSubId ->
                    activeSubIds to crossSimCallNewEnabled(activeSubIds, defaultDataSubId)
                    updatableSubIdsFlow(activeSubIds) to
                        crossSimCallNewEnabledFlow(activeSubIds, defaultDataSubId)
                }
                .flatMapLatest { (updatableSubIdsFlow, crossSimCallNewEnabledFlow) ->
                    combine(updatableSubIdsFlow, crossSimCallNewEnabledFlow) {
                        updatableSubIds,
                        newEnabled ->
                        updatableSubIds to newEnabled
                    }
                .flatMapLatest { (activeSubIds, newEnabledFlow) ->
                    newEnabledFlow.map { newEnabled -> activeSubIds to newEnabled }
                }
                .distinctUntilChanged()
                .onEach { (activeSubIds, newEnabled) ->
                    updateCrossSimCalling(activeSubIds, newEnabled)
                .conflate()
                .onEach { (updatableSubIds, newEnabled) ->
                    Log.d(TAG, "updatableSubIds: $updatableSubIds newEnabled: $newEnabled")
                    updateCrossSimCalling(updatableSubIds, newEnabled)
                }
                .launchIn(scope)
        }
    }

    private suspend fun updateCrossSimCalling(activeSubIds: List<Int>, newEnabled: Boolean) {
        metricsFeatureProvider.action(
            application,
            SettingsEnums.ACTION_UPDATE_CROSS_SIM_CALLING_ON_AUTO_DATA_SWITCH_EVENT,
            newEnabled,
        )
        activeSubIds
            .filter { subId -> crossSimAvailable(subId) }
            .forEach { subId ->
                ImsMmTelRepositoryImpl(application, subId).setCrossSimCallingEnabled(newEnabled)
    private fun updatableSubIdsFlow(activeSubIds: List<Int>): Flow<List<Int>> {
        val updatableSubIdFlows =
            activeSubIds.map { subId ->
                WifiCallingRepository(application, subId).wifiCallingReadyFlow().map { isReady ->
                    subId.takeIf { isReady && isCrossSimImsAvailable(subId) }
                }
            }
        return combine(updatableSubIdFlows) { subIds -> subIds.filterNotNull() }
            .distinctUntilChanged()
            .conflate()
    }

    private suspend fun crossSimAvailable(subId: Int): Boolean =
        WifiCallingRepository(application, subId).isWifiCallingSupported() &&
    private fun isCrossSimImsAvailable(subId: Int) =
        carrierConfigRepository.getBoolean(
                subId, CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL)
            subId,
            CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL,
        )

    private fun crossSimCallNewEnabled(
    private fun crossSimCallNewEnabledFlow(
        activeSubscriptionIdList: List<Int>,
        defaultDataSubId: Int,
    ): Flow<Boolean> {
@@ -102,8 +110,27 @@ class CrossSimCallingViewModel(
                .filter { subId -> subId != defaultDataSubId }
                .map { subId ->
                    mobileDataRepository.isMobileDataPolicyEnabledFlow(
                        subId, TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
                        subId,
                        TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH,
                    )
                }
        return combine(isMobileDataPolicyEnabledFlows) { true in it }
            .distinctUntilChanged()
            .conflate()
    }

    private suspend fun updateCrossSimCalling(subIds: List<Int>, newEnabled: Boolean) {
        metricsFeatureProvider.action(
            application,
            SettingsEnums.ACTION_UPDATE_CROSS_SIM_CALLING_ON_AUTO_DATA_SWITCH_EVENT,
            newEnabled,
        )
        for (subId in subIds) {
            ImsMmTelRepositoryImpl(application, subId).setCrossSimCallingEnabled(newEnabled)
        }
    }

    companion object {
        private const val TAG = "CrossSimCallingVM"
    }
}
+0 −9
Original line number Diff line number Diff line
@@ -29,9 +29,7 @@ import com.android.settings.network.telephony.ims.ImsMmTelRepository
import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl
import com.android.settings.network.telephony.telephonyManager
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext

interface IWifiCallingRepository {
    /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
@@ -75,11 +73,4 @@ constructor(
            tech = ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
            transportType = AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
        )

    suspend fun isWifiCallingSupported(): Boolean = withContext(Dispatchers.Default) {
        imsMmTelRepository.isSupported(
            capability = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
            transportType = AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
        )
    }
}
+0 −16
Original line number Diff line number Diff line
@@ -102,22 +102,6 @@ class WifiCallingRepositoryTest {
        assertThat(wiFiCallingMode).isEqualTo(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
    }

    @Test
    fun isWifiCallingSupported() = runBlocking {
        mockImsMmTelRepository.stub {
            onBlocking {
                isSupported(
                    capability = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
                    transportType = AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                )
            } doReturn true
        }

        val isSupported = repository.isWifiCallingSupported()

        assertThat(isSupported).isTrue()
    }

    private fun mockUseWfcHomeModeForRoaming(config: Boolean) {
        mockCarrierConfigManager.stub {
            on {