Make EnabledNetworkModePreferenceController listen to setting changes

The controller for the "Preferred network type" preference on the SIM
details page wasn't listening for changes to the underlying global
setting, so changes to the setting would be reflected in SysUI but not
on this page if it happened to be showing.

Bug: 135667565
Test: make RunSettingsRoboTests
Change-Id: I5dfe4843a681c613f49caf4584e9dbebc54e708a
Merged-In: I5dfe4843a681c613f49caf4584e9dbebc54e708a
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 94b1761..79cdc2e 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -16,7 +16,13 @@
 
 package com.android.settings.network.telephony;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
@@ -25,8 +31,12 @@
 import android.telephony.TelephonyManager;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.ListPreference;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
@@ -37,17 +47,27 @@
  */
 public class EnabledNetworkModePreferenceController extends
         TelephonyBasePreferenceController implements
-        ListPreference.OnPreferenceChangeListener {
+        ListPreference.OnPreferenceChangeListener, LifecycleObserver {
 
     private CarrierConfigManager mCarrierConfigManager;
+    private ContentObserver mPreferredNetworkModeObserver;
     private TelephonyManager mTelephonyManager;
     private boolean mIsGlobalCdma;
     @VisibleForTesting
     boolean mShow4GForLTE;
+    private Preference mPreference;
 
     public EnabledNetworkModePreferenceController(Context context, String key) {
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+        mPreferredNetworkModeObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange) {
+                if (mPreference != null) {
+                    updateState(mPreference);
+                }
+            }
+        };
     }
 
     @Override
@@ -78,6 +98,24 @@
         return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
+    @OnLifecycleEvent(ON_START)
+    public void onStart() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + mSubId), true,
+                mPreferredNetworkModeObserver);
+    }
+
+    @OnLifecycleEvent(ON_STOP)
+    public void onStop() {
+        mContext.getContentResolver().unregisterContentObserver(mPreferredNetworkModeObserver);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
@@ -102,7 +140,7 @@
         return false;
     }
 
-    public void init(int subId) {
+    public void init(Lifecycle lifecycle, int subId) {
         mSubId = subId;
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
@@ -115,6 +153,7 @@
                 ? carrierConfig.getBoolean(
                 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL)
                 : false;
+        lifecycle.addObserver(this);
     }
 
     private int getPreferredNetworkMode() {
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index c8e2247..8d83ef2 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -150,7 +150,7 @@
         use(CarrierPreferenceController.class).init(mSubId);
         use(DataUsagePreferenceController.class).init(mSubId);
         use(PreferredNetworkModePreferenceController.class).init(mSubId);
-        use(EnabledNetworkModePreferenceController.class).init(mSubId);
+        use(EnabledNetworkModePreferenceController.class).init(getLifecycle(), mSubId);
         use(DataServiceSetupPreferenceController.class).init(mSubId);
         if (!FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
             use(EuiccPreferenceController.class).init(mSubId);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
index ba8be90..6a12afd 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.network.telephony;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
 
@@ -23,19 +25,25 @@
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.content.Context;
+import android.net.Uri;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
+import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.ListPreference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +56,7 @@
 @RunWith(RobolectricTestRunner.class)
 public class EnabledNetworkModePreferenceControllerTest {
     private static final int SUB_ID = 2;
+    public static final String KEY = "enabled_network";
 
     @Mock
     private TelephonyManager mTelephonyManager;
@@ -60,11 +69,14 @@
     private EnabledNetworkModePreferenceController mController;
     private ListPreference mPreference;
     private Context mContext;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
         doReturn(mTelephonyManager).when(mContext).getSystemService(TelephonyManager.class);
@@ -79,8 +91,8 @@
         mPreference = new ListPreference(mContext);
         mPreference.setEntries(R.array.enabled_networks_choices);
         mPreference.setEntryValues(R.array.enabled_networks_values);
-        mController = new EnabledNetworkModePreferenceController(mContext, "enabled_network");
-        mController.init(SUB_ID);
+        mController = new EnabledNetworkModePreferenceController(mContext, KEY);
+        mController.init(mLifecycle, SUB_ID);
         mPreference.setKey(mController.getPreferenceKey());
     }
 
@@ -106,7 +118,7 @@
         mPersistableBundle.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
                 true);
 
-        mController.init(SUB_ID);
+        mController.init(mLifecycle, SUB_ID);
 
         assertThat(mController.mShow4GForLTE).isTrue();
     }
@@ -161,4 +173,31 @@
                 Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID, 0)).isNotEqualTo(
                 TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
     }
+
+    @Test
+    public void preferredNetworkModeNotification_preferenceUpdates() {
+        PreferenceScreen screen = mock(PreferenceScreen.class);
+        doReturn(mPreference).when(screen).findPreference(KEY);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
+                TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
+        mController.displayPreference(screen);
+        mController.updateState(mPreference);
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(Integer.parseInt(mPreference.getValue())).isEqualTo(
+                TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
+        assertThat(mPreference.getSummary()).isEqualTo("3G");
+
+
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
+                TelephonyManager.NETWORK_MODE_GSM_ONLY);
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID);
+        mContext.getContentResolver().notifyChange(uri, null);
+
+        assertThat(Integer.parseInt(mPreference.getValue())).isEqualTo(
+                TelephonyManager.NETWORK_MODE_GSM_ONLY);
+        assertThat(mPreference.getSummary()).isEqualTo("2G");
+    }
 }