Merge "Disable entry point of output switcher"
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index 40d26f7..82c3668 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -248,7 +248,9 @@
             final Map<String, IContentProvider> providerMap = new ArrayMap<>();
             final String titleFromUri = TileUtils.getTextFromUri(
                     mContext, uri, providerMap, META_DATA_PREFERENCE_TITLE);
-            ThreadUtils.postOnMainThread(() -> preference.setTitle(titleFromUri));
+            if (!TextUtils.equals(titleFromUri, preference.getTitle())) {
+                ThreadUtils.postOnMainThread(() -> preference.setTitle(titleFromUri));
+            }
         });
     }
 
@@ -277,7 +279,9 @@
             final Map<String, IContentProvider> providerMap = new ArrayMap<>();
             final String summaryFromUri = TileUtils.getTextFromUri(
                     mContext, uri, providerMap, META_DATA_PREFERENCE_SUMMARY);
-            ThreadUtils.postOnMainThread(() -> preference.setSummary(summaryFromUri));
+            if (!TextUtils.equals(summaryFromUri, preference.getSummary())) {
+                ThreadUtils.postOnMainThread(() -> preference.setSummary(summaryFromUri));
+            }
         });
     }
 
diff --git a/src/com/android/settings/network/MobileNetworkPreferenceController.java b/src/com/android/settings/network/MobileNetworkPreferenceController.java
index 5612d2e..b968438 100644
--- a/src/com/android/settings/network/MobileNetworkPreferenceController.java
+++ b/src/com/android/settings/network/MobileNetworkPreferenceController.java
@@ -18,6 +18,8 @@
 import static android.os.UserHandle.myUserId;
 import static android.os.UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
 
+import static androidx.lifecycle.Lifecycle.Event;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -29,6 +31,8 @@
 import android.telephony.TelephonyManager;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
@@ -39,12 +43,9 @@
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.Utils;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
 
 public class MobileNetworkPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
+        implements PreferenceControllerMixin, LifecycleObserver {
 
     @VisibleForTesting
     static final String KEY_MOBILE_NETWORK_SETTINGS = "mobile_network_settings";
@@ -96,7 +97,7 @@
         return KEY_MOBILE_NETWORK_SETTINGS;
     }
 
-    @Override
+    @OnLifecycleEvent(Event.ON_START)
     public void onStart() {
         if (isAvailable()) {
             if (mPhoneStateListener == null) {
@@ -115,7 +116,7 @@
         }
     }
 
-    @Override
+    @OnLifecycleEvent(Event.ON_STOP)
     public void onStop() {
         if (mPhoneStateListener != null) {
             mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
diff --git a/src/com/android/settings/wifi/OWNERS b/src/com/android/settings/wifi/OWNERS
index ab0af7c..5e20fd5 100644
--- a/src/com/android/settings/wifi/OWNERS
+++ b/src/com/android/settings/wifi/OWNERS
@@ -1,4 +1,5 @@
 # Default reviewers for this and subdirectories.
-govenliu@google.com
+andychou@google.com
 arcwang@google.com
-tmfang@google.com
+goldmanj@google.com
+wengsu@google.com
diff --git a/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
new file mode 100644
index 0000000..c540512
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.network;
+
+import static androidx.lifecycle.Lifecycle.Event;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.Looper;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedPreference;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class MobileNetworkPreferenceControllerTest {
+    private Context mContext;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private ConnectivityManager mConnectivityManager;
+
+    private PreferenceManager mPreferenceManager;
+    private PreferenceScreen mScreen;
+
+    @Mock
+    private LifecycleOwner mLifecycleOwner;
+    private LifecycleRegistry mLifecycleRegistry;
+    private MobileNetworkPreferenceController mController;
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mPreferenceManager = new PreferenceManager(mContext);
+        mScreen = mPreferenceManager.createPreferenceScreen(mContext);
+        mPreference = new Preference(mContext);
+        mPreference.setKey(MobileNetworkPreferenceController.KEY_MOBILE_NETWORK_SETTINGS);
+
+        mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
+        when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
+    }
+
+    @Test
+    public void secondaryUser_prefIsNotAvailable() {
+        when(mUserManager.isAdminUser()).thenReturn(false);
+        when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE))
+            .thenReturn(true);
+
+        mController = new MobileNetworkPreferenceController(mContext);
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void wifiOnly_prefIsNotAvailable() {
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE))
+            .thenReturn(false);
+
+        mController = new MobileNetworkPreferenceController(mContext);
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    @UiThreadTest
+    public void goThroughLifecycle_isAvailable_shouldListenToServiceChange() {
+        mController = spy(new MobileNetworkPreferenceController(mContext));
+        mLifecycleRegistry.addObserver(mController);
+        doReturn(true).when(mController).isAvailable();
+
+        mLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
+        verify(mController).onStart();
+        verify(mTelephonyManager).listen(mController.mPhoneStateListener,
+                PhoneStateListener.LISTEN_SERVICE_STATE);
+
+        mLifecycleRegistry.handleLifecycleEvent(Event.ON_STOP);
+        verify(mController).onStop();
+        verify(mTelephonyManager).listen(mController.mPhoneStateListener,
+                PhoneStateListener.LISTEN_NONE);
+    }
+
+    @Test
+    @UiThreadTest
+    public void serviceStateChange_shouldUpdatePrefSummary() {
+        final String testCarrierName = "test";
+
+        mController = spy(new MobileNetworkPreferenceController(mContext));
+        mLifecycleRegistry.addObserver(mController);
+        doReturn(true).when(mController).isAvailable();
+
+        mScreen.addPreference(mPreference);
+
+        // Display pref and go through lifecycle to set up listener.
+        mController.displayPreference(mScreen);
+        mLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
+        verify(mController).onStart();
+        verify(mTelephonyManager).listen(mController.mPhoneStateListener,
+                PhoneStateListener.LISTEN_SERVICE_STATE);
+
+        doReturn(testCarrierName).when(mController).getSummary();
+
+        mController.mPhoneStateListener.onServiceStateChanged(null);
+
+        // Carrier name should be set.
+        Assert.assertEquals(mPreference.getSummary(), testCarrierName);
+    }
+
+    @Test
+    public void airplaneModeTurnedOn_shouldDisablePreference() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Global.AIRPLANE_MODE_ON, 1);
+        mController = spy(new MobileNetworkPreferenceController(mContext));
+        final RestrictedPreference mPreference = new RestrictedPreference(mContext);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void airplaneModeTurnedOffAndNoUserRestriction_shouldEnablePreference() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Global.AIRPLANE_MODE_ON, 0);
+        mController = spy(new MobileNetworkPreferenceController(mContext));
+        final RestrictedPreference mPreference = new RestrictedPreference(mContext);
+        mPreference.setDisabledByAdmin(null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void airplaneModeTurnedOffAndHasUserRestriction_shouldDisablePreference() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Global.AIRPLANE_MODE_ON, 0);
+        mController = spy(new MobileNetworkPreferenceController(mContext));
+        final RestrictedPreference mPreference = new RestrictedPreference(mContext);
+        mPreference.setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
+}