Merge "Always set cross sim calling" into main
diff --git a/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java b/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java
index fcbfdef..6d6e41f 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.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 @@
     @Nullable
     private MobileDataContentObserver mMobileDataContentObserver;
     @Nullable
-    private CrossSimCallingViewModel mCrossSimCallingViewModel;
-    @Nullable
     private PreferenceScreen mScreen;
 
     public AutoDataSwitchPreferenceController(
@@ -72,10 +69,9 @@
         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 @@
                     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 62e7e98..829c4c0 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.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 @@
             .onStart { emit(SubscriptionManager.getDefaultDataSubscriptionId()) }
             .distinctUntilChanged()
             .conflate()
+            .onEach { Log.d(TAG, "defaultDataSubscriptionIdFlow: $it") }
             .flowOn(Dispatchers.Default)
 
     fun activeDataSubscriptionIdFlow(): Flow<Int> =
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index d70ef25..896eac6 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -247,9 +247,10 @@
         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 170af54..dda147b 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 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 @@
 ) : 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<Unit>()
-    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 @@
         }
     }
 
-    fun updateCrossSimCalling() {
-        updateChannel.trySend(Unit)
-    }
-
-    private fun List<Int>.anyMobileDataEnableChangedFlow() = map { subId ->
-        mobileDataRepository.mobileDataEnabledChangedFlow(subId = subId, sendInitialValue = false)
-    }.merge()
-
     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 { 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<Int>): 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<Int>,
+        defaultDataSubId: Int,
+    ): Flow<Boolean> {
+        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 e7cc18f..5fbd7dc 100644
--- a/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt
+++ b/src/com/android/settings/spa/network/AutomaticDataSwitchingPreference.kt
@@ -34,7 +34,9 @@
 ) {
     val autoDataSummary = stringResource(id = R.string.primary_sim_automatic_data_msg)
     val coroutineScope = rememberCoroutineScope()
-    val crossSimCallingViewModel = viewModel<CrossSimCallingViewModel>() // handles backup calling
+    // CrossSimCallingViewModel is responsible for maintaining the correct cross sim calling
+    // settings (backup calling).
+    viewModel<CrossSimCallingViewModel>()
     SwitchPreference(
         object : SwitchPreferenceModel {
             override val title = stringResource(id = R.string.primary_sim_automatic_data_title)
@@ -43,7 +45,6 @@
             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 8db4681..29592cf 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 @@
                 return true;
             }
         };
-        mController.init(SUB_ID_1, null);
+        mController.init(SUB_ID_1);
     }
 
     @Test