Refine CrossSimCalling updating
Currently, this setting depends on whether wifi calling is supported,
since wifi calling could takes some time to provision after sim is
turned on, this state could be wrong when set cross sim calling.
Use wifiCallingReadyFlow() to retrieve the latest state, and update
setting when state changes.
Fix: 352736998
Fix: 348529996
Flag: EXEMPT bug fix
Test: manual - by turn on / off sim
Change-Id: Id4b099e0c5d7cf47b007f37e6f278d1c46e58659
diff --git a/src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt b/src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt
index c5d1200..e891204 100644
--- a/src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt
+++ b/src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt
@@ -27,6 +27,7 @@
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 @@
@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 @@
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) {
diff --git a/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt b/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt
index dda147b..cab27ca 100644
--- a/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt
+++ b/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt
@@ -21,6 +21,7 @@
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.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.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 @@
subscriptionRepository.activeSubscriptionIdListFlow(),
dataSubscriptionRepository.defaultDataSubscriptionIdFlow(),
) { activeSubIds, defaultDataSubId ->
- activeSubIds to crossSimCallNewEnabled(activeSubIds, defaultDataSubId)
+ updatableSubIdsFlow(activeSubIds) to
+ crossSimCallNewEnabledFlow(activeSubIds, defaultDataSubId)
}
- .flatMapLatest { (activeSubIds, newEnabledFlow) ->
- newEnabledFlow.map { newEnabled -> activeSubIds to newEnabled }
+ .flatMapLatest { (updatableSubIdsFlow, crossSimCallNewEnabledFlow) ->
+ combine(updatableSubIdsFlow, crossSimCallNewEnabledFlow) {
+ updatableSubIds,
+ newEnabled ->
+ updatableSubIds 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() &&
- carrierConfigRepository.getBoolean(
- subId, CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL)
+ private fun isCrossSimImsAvailable(subId: Int) =
+ carrierConfigRepository.getBoolean(
+ 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 @@
.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"
}
}
diff --git a/src/com/android/settings/network/telephony/wificalling/WifiCallingRepository.kt b/src/com/android/settings/network/telephony/wificalling/WifiCallingRepository.kt
index 6af0559..a6a47fa 100644
--- a/src/com/android/settings/network/telephony/wificalling/WifiCallingRepository.kt
+++ b/src/com/android/settings/network/telephony/wificalling/WifiCallingRepository.kt
@@ -29,9 +29,7 @@
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 @@
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,
- )
- }
}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/wificalling/WifiCallingRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/wificalling/WifiCallingRepositoryTest.kt
index f0a23eb..9b71465 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/wificalling/WifiCallingRepositoryTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/wificalling/WifiCallingRepositoryTest.kt
@@ -102,22 +102,6 @@
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 {