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
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 { (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 @@ 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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user