From fb0583404f10351c61b35a98e104aa152de55431 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Tue, 16 Jul 2024 17:38:17 +0800 Subject: [PATCH] Always set cross sim calling By CrossSimCallingViewModel, in SIMs and per SIM settings page. To ensure the status is always right, including the case after the onboarding set up finished. Fix: 347882381 Fix: 348529996 Flag: EXEMPT bug fix Test: manual - turn on / off "Automatic data switching" on SIMs Test: manual - turn off "Automatic data switching" during onboarding Change-Id: Icc2eacb67850fa7b3aa0fe310cd09a0e0147912b --- .../AutoDataSwitchPreferenceController.java | 9 +-- .../telephony/DataSubscriptionRepository.kt | 2 + .../telephony/MobileNetworkSettings.java | 7 +- .../wificalling/CrossSimCallingViewModel.kt | 81 +++++++++---------- .../AutomaticDataSwitchingPreference.kt | 5 +- ...utoDataSwitchPreferenceControllerTest.java | 2 +- 6 files changed, 47 insertions(+), 59 deletions(-) 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