Merge "Refine CrossSimCalling updating" into main
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