Refesh mobile network details page on carrier config changes

In general the mobile network details page has several preference
controllers that don't listen to carrier config changes, so instead of
having each one add a listener, we instead just have one listener and
refresh the entire page when we see the broadcast.

Fixes: 135587885
Test: make RunSettingsRoboTests
Change-Id: Iff5b28dbfe12d94c901b442b23cece8e68218983
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index e20032f..9912b4e 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -23,6 +23,7 @@
 import android.content.IntentFilter;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.view.Menu;
@@ -93,13 +94,18 @@
             setContentView(R.layout.mobile_network_settings_container);
         }
         setActionBar(findViewById(R.id.mobile_action_bar));
-        mPhoneChangeReceiver = new PhoneChangeReceiver(this, () -> {
-            if (mCurSubscriptionId != SUB_ID_NULL) {
-                // When the radio changes (ex: CDMA->GSM), refresh the fragment.
-                // This is very rare.
+        mPhoneChangeReceiver = new PhoneChangeReceiver(this, new PhoneChangeReceiver.Client() {
+            @Override
+            public void onPhoneChange() {
+                // When the radio or carrier config changes (ex: CDMA->GSM), refresh the fragment.
                 switchFragment(new MobileNetworkSettings(), mCurSubscriptionId,
                         true /* forceUpdate */);
             }
+
+            @Override
+            public int getSubscriptionId() {
+                return mCurSubscriptionId;
+            }
         });
         mSubscriptionManager = getSystemService(SubscriptionManager.class);
         mSubscriptionInfos = mSubscriptionManager.getActiveSubscriptionInfoList(true);
@@ -250,14 +256,12 @@
 
     @VisibleForTesting
     static class PhoneChangeReceiver extends BroadcastReceiver {
-        private static final IntentFilter RADIO_TECHNOLOGY_CHANGED_FILTER = new IntentFilter(
-                TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
-
         private Context mContext;
         private Client mClient;
 
         interface Client {
             void onPhoneChange();
+            int getSubscriptionId();
         }
 
         public PhoneChangeReceiver(Context context, Client client) {
@@ -266,7 +270,10 @@
         }
 
         public void register() {
-            mContext.registerReceiver(this, RADIO_TECHNOLOGY_CHANGED_FILTER);
+            final IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+            intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+            mContext.registerReceiver(this, intentFilter);
         }
 
         public void unregister() {
@@ -275,9 +282,17 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (!isInitialStickyBroadcast()) {
-                mClient.onPhoneChange();
+            if (isInitialStickyBroadcast()) {
+                return;
             }
+            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+                if (!intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX) ||
+                        intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1)
+                                != mClient.getSubscriptionId()) {
+                    return;
+                }
+            }
+            mClient.onPhoneChange();
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
index e43655b..43897d5 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
@@ -22,7 +22,10 @@
 
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -31,6 +34,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -161,19 +165,56 @@
     @Test
     public void phoneChangeReceiver_ignoresStickyBroadcastFromBeforeRegistering() {
         Activity activity = Robolectric.setupActivity(Activity.class);
-        final int[] onChangeCallbackCount = {0};
+        MobileNetworkActivity.PhoneChangeReceiver.Client client = mock(
+                MobileNetworkActivity.PhoneChangeReceiver.Client.class);
         MobileNetworkActivity.PhoneChangeReceiver receiver =
-                new MobileNetworkActivity.PhoneChangeReceiver(activity, () -> {
-                    onChangeCallbackCount[0]++;
-                });
+                new MobileNetworkActivity.PhoneChangeReceiver(activity, client);
         Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
         activity.sendStickyBroadcast(intent);
 
         receiver.register();
-        assertThat(onChangeCallbackCount[0]).isEqualTo(0);
+        verify(client, never()).onPhoneChange();
 
         activity.sendStickyBroadcast(intent);
-        assertThat(onChangeCallbackCount[0]).isEqualTo(1);
+        verify(client, times(1)).onPhoneChange();
+    }
+
+    @Test
+    public void phoneChangeReceiver_ignoresCarrierConfigChangeForWrongSubscriptionId() {
+        Activity activity = Robolectric.setupActivity(Activity.class);
+
+        MobileNetworkActivity.PhoneChangeReceiver.Client client = mock(
+                MobileNetworkActivity.PhoneChangeReceiver.Client.class);
+        doReturn(2).when(client).getSubscriptionId();
+
+        MobileNetworkActivity.PhoneChangeReceiver receiver =
+                new MobileNetworkActivity.PhoneChangeReceiver(activity, client);
+
+        receiver.register();
+
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, 3);
+        activity.sendBroadcast(intent);
+        verify(client, never()).onPhoneChange();
+    }
+
+    @Test
+    public void phoneChangeReceiver_dispatchesCarrierConfigChangeForCorrectSubscriptionId() {
+        Activity activity = Robolectric.setupActivity(Activity.class);
+
+        MobileNetworkActivity.PhoneChangeReceiver.Client client = mock(
+                MobileNetworkActivity.PhoneChangeReceiver.Client.class);
+        doReturn(2).when(client).getSubscriptionId();
+
+        MobileNetworkActivity.PhoneChangeReceiver receiver =
+                new MobileNetworkActivity.PhoneChangeReceiver(activity, client);
+
+        receiver.register();
+
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, 2);
+        activity.sendBroadcast(intent);
+        verify(client).onPhoneChange();
     }