diff --git a/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java b/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java index fcbfdef4a72..6d6e41f1f45 100644 --- a/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java +++ b/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java @@ -38,7 +38,6 @@ import com.android.settings.datausage.DataUsageUtils; import com.android.settings.flags.Flags; import com.android.settings.network.MobileDataContentObserver; import com.android.settings.network.SubscriptionsChangeListener; -import com.android.settings.network.telephony.wificalling.CrossSimCallingViewModel; /** * Controls whether switch mobile data to the non-default SIM if the non-default SIM has better @@ -63,8 +62,6 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc @Nullable private MobileDataContentObserver mMobileDataContentObserver; @Nullable - private CrossSimCallingViewModel mCrossSimCallingViewModel; - @Nullable private PreferenceScreen mScreen; public AutoDataSwitchPreferenceController( @@ -72,10 +69,9 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc super(context, preferenceKey); } - void init(int subId, @Nullable CrossSimCallingViewModel crossSimCallingViewModel) { + void init(int subId) { this.mSubId = subId; mManager = mContext.getSystemService(TelephonyManager.class).createForSubscriptionId(subId); - mCrossSimCallingViewModel = crossSimCallingViewModel; } @OnLifecycleEvent(ON_RESUME) @@ -122,9 +118,6 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, isChecked); } - if (mCrossSimCallingViewModel != null) { - mCrossSimCallingViewModel.updateCrossSimCalling(); - } return true; } diff --git a/src/com/android/settings/network/telephony/DataSubscriptionRepository.kt b/src/com/android/settings/network/telephony/DataSubscriptionRepository.kt index 62e7e98df3c..829c4c0f153 100644 --- a/src/com/android/settings/network/telephony/DataSubscriptionRepository.kt +++ b/src/com/android/settings/network/telephony/DataSubscriptionRepository.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart class DataSubscriptionRepository( @@ -53,6 +54,7 @@ class DataSubscriptionRepository( .onStart { emit(SubscriptionManager.getDefaultDataSubscriptionId()) } .distinctUntilChanged() .conflate() + .onEach { Log.d(TAG, "defaultDataSubscriptionIdFlow: $it") } .flowOn(Dispatchers.Default) fun activeDataSubscriptionIdFlow(): Flow = diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index d70ef25dd3a..896eac6197a 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -247,9 +247,10 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme use(CarrierSettingsVersionPreferenceController.class).init(mSubId); use(BillingCyclePreferenceController.class).init(mSubId); use(MmsMessagePreferenceController.class).init(mSubId); - final var crossSimCallingViewModel = - new ViewModelProvider(this).get(CrossSimCallingViewModel.class); - use(AutoDataSwitchPreferenceController.class).init(mSubId, crossSimCallingViewModel); + // CrossSimCallingViewModel is responsible for maintaining the correct cross sim calling + // settings (backup calling). + new ViewModelProvider(this).get(CrossSimCallingViewModel.class); + use(AutoDataSwitchPreferenceController.class).init(mSubId); use(DisabledSubscriptionController.class).init(mSubId); use(DeleteSimProfilePreferenceController.class).init(mSubId); use(DisableSimFooterPreferenceController.class).init(mSubId); diff --git a/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt b/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt index 170af548ad1..dda147b549e 100644 --- a/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt +++ b/src/com/android/settings/network/telephony/wificalling/CrossSimCallingViewModel.kt @@ -24,22 +24,22 @@ import android.telephony.TelephonyManager import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.android.settings.R +import com.android.settings.network.telephony.CarrierConfigRepository +import com.android.settings.network.telephony.DataSubscriptionRepository import com.android.settings.network.telephony.MobileDataRepository import com.android.settings.network.telephony.SubscriptionRepository import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl -import com.android.settings.network.telephony.safeGetConfig -import com.android.settings.network.telephony.telephonyManager import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.plus @OptIn(ExperimentalCoroutinesApi::class) @@ -48,24 +48,23 @@ class CrossSimCallingViewModel( ) : AndroidViewModel(application) { private val subscriptionRepository = SubscriptionRepository(application) - private val carrierConfigManager = - application.getSystemService(CarrierConfigManager::class.java)!! + private val dataSubscriptionRepository = DataSubscriptionRepository(application) + private val mobileDataRepository = MobileDataRepository(application) + private val carrierConfigRepository = CarrierConfigRepository(application) private val scope = viewModelScope + Dispatchers.Default private val metricsFeatureProvider = featureFactory.metricsFeatureProvider - private val updateChannel = Channel() - private val mobileDataRepository = MobileDataRepository(application) init { val resources = application.resources if (resources.getBoolean(R.bool.config_auto_data_switch_enables_cross_sim_calling)) { - subscriptionRepository.activeSubscriptionIdListFlow() - .flatMapLatest { activeSubIds -> - merge( - activeSubIds.anyMobileDataEnableChangedFlow(), - updateChannel.receiveAsFlow(), - ).map { - activeSubIds to crossSimCallNewEnabled(activeSubIds) - } + combine( + subscriptionRepository.activeSubscriptionIdListFlow(), + dataSubscriptionRepository.defaultDataSubscriptionIdFlow(), + ) { activeSubIds, defaultDataSubId -> + activeSubIds to crossSimCallNewEnabled(activeSubIds, defaultDataSubId) + } + .flatMapLatest { (activeSubIds, newEnabledFlow) -> + newEnabledFlow.map { newEnabled -> activeSubIds to newEnabled } } .distinctUntilChanged() .onEach { (activeSubIds, newEnabled) -> @@ -75,44 +74,36 @@ class CrossSimCallingViewModel( } } - fun updateCrossSimCalling() { - updateChannel.trySend(Unit) - } - - private fun List.anyMobileDataEnableChangedFlow() = map { subId -> - mobileDataRepository.mobileDataEnabledChangedFlow(subId = subId, sendInitialValue = false) - }.merge() - private suspend fun updateCrossSimCalling(activeSubIds: List, newEnabled: Boolean) { metricsFeatureProvider.action( application, SettingsEnums.ACTION_UPDATE_CROSS_SIM_CALLING_ON_AUTO_DATA_SWITCH_EVENT, newEnabled, ) - activeSubIds.filter { crossSimAvailable(it) }.forEach { subId -> - ImsMmTelRepositoryImpl(application, subId) - .setCrossSimCallingEnabled(newEnabled) - } + activeSubIds + .filter { subId -> crossSimAvailable(subId) } + .forEach { subId -> + ImsMmTelRepositoryImpl(application, subId).setCrossSimCallingEnabled(newEnabled) + } } private suspend fun crossSimAvailable(subId: Int): Boolean = WifiCallingRepository(application, subId).isWifiCallingSupported() && - crossSimImsAvailable(subId) + carrierConfigRepository.getBoolean( + subId, CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL) - private fun crossSimImsAvailable(subId: Int): Boolean = - carrierConfigManager.safeGetConfig( - keys = listOf(CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL), - subId = subId, - ).getBoolean(CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false) - - private fun crossSimCallNewEnabled(activeSubscriptionIdList: List): Boolean { - val defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId() - return SubscriptionManager.isValidSubscriptionId(defaultDataSubId) && - activeSubscriptionIdList.any { subId -> - subId != defaultDataSubId && - application.telephonyManager(subId).isMobileDataPolicyEnabled( - TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH - ) - } + private fun crossSimCallNewEnabled( + activeSubscriptionIdList: List, + defaultDataSubId: Int, + ): Flow { + if (!SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) return flowOf(false) + val isMobileDataPolicyEnabledFlows = + activeSubscriptionIdList + .filter { subId -> subId != defaultDataSubId } + .map { subId -> + mobileDataRepository.isMobileDataPolicyEnabledFlow( + subId, TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) + } + return combine(isMobileDataPolicyEnabledFlows) { true in it } } } diff --git a/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt b/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt index e7cc18fb101..5fbd7dc835a 100644 --- a/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt +++ b/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt @@ -34,7 +34,9 @@ fun AutomaticDataSwitchingPreference( ) { val autoDataSummary = stringResource(id = R.string.primary_sim_automatic_data_msg) val coroutineScope = rememberCoroutineScope() - val crossSimCallingViewModel = viewModel() // handles backup calling + // CrossSimCallingViewModel is responsible for maintaining the correct cross sim calling + // settings (backup calling). + viewModel() SwitchPreference( object : SwitchPreferenceModel { override val title = stringResource(id = R.string.primary_sim_automatic_data_title) @@ -43,7 +45,6 @@ fun AutomaticDataSwitchingPreference( override val onCheckedChange: (Boolean) -> Unit = { newEnabled -> coroutineScope.launch(Dispatchers.Default) { setAutoDataEnabled(newEnabled) - crossSimCallingViewModel.updateCrossSimCalling() } } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceControllerTest.java index 8db4681784e..29592cf9189 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceControllerTest.java @@ -85,7 +85,7 @@ public class AutoDataSwitchPreferenceControllerTest { return true; } }; - mController.init(SUB_ID_1, null); + mController.init(SUB_ID_1); } @Test