Merge "[Provider Model] Move down the Internet unavailable Wi-Fi" into sc-dev
diff --git a/res/xml/network_provider_settings.xml b/res/xml/network_provider_settings.xml
index 30fe6fe..b29755b 100644
--- a/res/xml/network_provider_settings.xml
+++ b/res/xml/network_provider_settings.xml
@@ -53,6 +53,10 @@
         settings:controller="com.android.settings.network.NetworkMobileProviderController"/>
 
     <PreferenceCategory
+        android:key="first_access_points"
+        android:layout="@layout/preference_category_no_label"/>
+
+    <PreferenceCategory
         android:key="access_points"
         android:layout="@layout/preference_category_no_label"/>
 
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index 1d8ee7a..c368fa3 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -50,6 +50,7 @@
 
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
@@ -80,6 +81,7 @@
 import com.android.settingslib.connectivity.ConnectivitySubsystemsRecoveryManager;
 import com.android.settingslib.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.utils.ThreadUtils;
 import com.android.settingslib.widget.LayoutPreference;
 import com.android.settingslib.wifi.LongPressWifiEntryPreference;
 import com.android.settingslib.wifi.WifiSavedConfigUtils;
@@ -100,7 +102,7 @@
         implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback,
         WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener,
         ConnectivitySubsystemsRecoveryManager.RecoveryStatusCallback,
-        AirplaneModeEnabler.OnAirplaneModeChangedListener {
+        AirplaneModeEnabler.OnAirplaneModeChangedListener, InternetUpdater.InternetChangeListener {
 
     public static final String ACTION_NETWORK_PROVIDER_SETTINGS =
             "android.settings.NETWORK_PROVIDER_SETTINGS";
@@ -123,7 +125,10 @@
     private static final String PREF_KEY_AIRPLANE_MODE_MSG = "airplane_mode_message";
     private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list";
     // TODO(b/70983952): Rename these to use WifiEntry instead of AccessPoint.
-    private static final String PREF_KEY_CONNECTED_ACCESS_POINTS = "connected_access_point";
+    @VisibleForTesting
+    static final String PREF_KEY_CONNECTED_ACCESS_POINTS = "connected_access_point";
+    @VisibleForTesting
+    static final String PREF_KEY_FIRST_ACCESS_POINTS = "first_access_points";
     private static final String PREF_KEY_ACCESS_POINTS = "access_points";
     private static final String PREF_KEY_CONFIGURE_WIFI_SETTINGS = "configure_wifi_settings";
     private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks";
@@ -192,12 +197,17 @@
     @VisibleForTesting
     WifiPickerTracker mWifiPickerTracker;
     private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+    @VisibleForTesting
+    InternetUpdater mInternetUpdater;
 
     private WifiDialog2 mDialog;
 
     private View mProgressHeader;
 
-    private PreferenceCategory mConnectedWifiEntryPreferenceCategory;
+    @VisibleForTesting
+    PreferenceCategory mConnectedWifiEntryPreferenceCategory;
+    @VisibleForTesting
+    PreferenceCategory mFirstWifiEntryPreferenceCategory;
     private PreferenceCategory mWifiEntryPreferenceCategory;
     @VisibleForTesting
     AddWifiNetworkPreference mAddWifiNetworkPreference;
@@ -262,6 +272,7 @@
         mAirplaneModeMsgPreference = findPreference(PREF_KEY_AIRPLANE_MODE_MSG);
         updateAirplaneModeMsgPreference(mAirplaneModeEnabler.isAirplaneModeOn() /* visible */);
         mConnectedWifiEntryPreferenceCategory = findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS);
+        mFirstWifiEntryPreferenceCategory = findPreference(PREF_KEY_FIRST_ACCESS_POINTS);
         mWifiEntryPreferenceCategory = findPreference(PREF_KEY_ACCESS_POINTS);
         mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS);
         mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS);
@@ -318,6 +329,7 @@
         mWifiPickerTrackerHelper =
                 new WifiPickerTrackerHelper(getSettingsLifecycle(), getContext(), this);
         mWifiPickerTracker = mWifiPickerTrackerHelper.getWifiPickerTracker();
+        mInternetUpdater = new InternetUpdater(getContext(), getSettingsLifecycle(), this);
 
         final Activity activity = getActivity();
 
@@ -635,6 +647,13 @@
         }
     }
 
+    @Override
+    public void onInternetTypeChanged(@InternetUpdater.InternetType int internetType) {
+        ThreadUtils.postOnMainThread(() -> {
+            onWifiStateChanged();
+        });
+    }
+
     /** Called when the state of Wifi has changed. */
     @Override
     public void onWifiStateChanged() {
@@ -738,17 +757,18 @@
         mWifiEntryPreferenceCategory.setVisible(true);
 
         final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry();
-        mConnectedWifiEntryPreferenceCategory.setVisible(connectedEntry != null);
+        PreferenceCategory connectedWifiPreferenceCategory = getConnectedWifiPreferenceCategory();
+        connectedWifiPreferenceCategory.setVisible(connectedEntry != null);
         if (connectedEntry != null) {
             final LongPressWifiEntryPreference connectedPref =
-                    mConnectedWifiEntryPreferenceCategory.findPreference(connectedEntry.getKey());
+                    connectedWifiPreferenceCategory.findPreference(connectedEntry.getKey());
             if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
-                mConnectedWifiEntryPreferenceCategory.removeAll();
+                connectedWifiPreferenceCategory.removeAll();
                 final ConnectedWifiEntryPreference pref =
-                        new ConnectedWifiEntryPreference(getPrefContext(), connectedEntry, this);
+                        createConnectedWifiEntryPreference(connectedEntry);
                 pref.setKey(connectedEntry.getKey());
                 pref.refresh();
-                mConnectedWifiEntryPreferenceCategory.addPreference(pref);
+                connectedWifiPreferenceCategory.addPreference(pref);
                 pref.setOnPreferenceClickListener(preference -> {
                     if (connectedEntry.canSignIn()) {
                         connectedEntry.signIn(null /* callback */);
@@ -763,11 +783,11 @@
 
                 if (mClickedConnect) {
                     mClickedConnect = false;
-                    scrollToPreference(mConnectedWifiEntryPreferenceCategory);
+                    scrollToPreference(connectedWifiPreferenceCategory);
                 }
             }
         } else {
-            mConnectedWifiEntryPreferenceCategory.removeAll();
+            connectedWifiPreferenceCategory.removeAll();
         }
 
         int index = 0;
@@ -821,6 +841,27 @@
         setAdditionalSettingsSummaries();
     }
 
+    @VisibleForTesting
+    PreferenceCategory getConnectedWifiPreferenceCategory() {
+        if (mInternetUpdater.getInternetType() == InternetUpdater.INTERNET_WIFI) {
+            mFirstWifiEntryPreferenceCategory.setVisible(false);
+            mFirstWifiEntryPreferenceCategory.removeAll();
+            return mConnectedWifiEntryPreferenceCategory;
+        }
+
+        mConnectedWifiEntryPreferenceCategory.setVisible(false);
+        mConnectedWifiEntryPreferenceCategory.removeAll();
+        return mFirstWifiEntryPreferenceCategory;
+    }
+
+    @VisibleForTesting
+    ConnectedWifiEntryPreference createConnectedWifiEntryPreference(WifiEntry wifiEntry) {
+        if (mInternetUpdater.getInternetType() == InternetUpdater.INTERNET_WIFI) {
+            return new ConnectedWifiEntryPreference(getPrefContext(), wifiEntry, this);
+        }
+        return new FirstWifiEntryPreference(getPrefContext(), wifiEntry, this);
+    }
+
     private void launchNetworkDetailsFragment(LongPressWifiEntryPreference pref) {
         final WifiEntry wifiEntry = pref.getWifiEntry();
         final Context context = getContext();
@@ -1217,4 +1258,22 @@
     public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
         updateAirplaneModeMsgPreference(isAirplaneModeOn /* visible */);
     }
+
+    /**
+     * A Wi-Fi preference for the connected Wi-Fi network without internet access.
+     *
+     * Override the icon color attribute by {@link ConnectedWifiEntryPreference#getIconColorAttr()}
+     * and show the icon color to android.R.attr.colorControlNormal for the preference.
+     */
+    public class FirstWifiEntryPreference extends ConnectedWifiEntryPreference {
+        public FirstWifiEntryPreference(Context context, WifiEntry wifiEntry,
+                Fragment fragment) {
+            super(context, wifiEntry, fragment);
+        }
+
+        @Override
+        protected int getIconColorAttr() {
+            return android.R.attr.colorControlNormal;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
index c1377ff..f02a806 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
@@ -51,6 +51,7 @@
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
 import androidx.recyclerview.widget.RecyclerView;
@@ -61,6 +62,7 @@
 import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
 import com.android.settings.testutils.shadow.ShadowFragment;
 import com.android.settings.wifi.AddWifiNetworkPreference;
+import com.android.settings.wifi.ConnectedWifiEntryPreference;
 import com.android.settings.wifi.WifiConfigController2;
 import com.android.settings.wifi.WifiDialog2;
 import com.android.settingslib.connectivity.ConnectivitySubsystemsRecoveryManager;
@@ -109,6 +111,12 @@
     private LayoutPreference mResetInternetPreference;
     @Mock
     private MenuItem mMenuItem;
+    @Mock
+    InternetUpdater mInternetUpdater;
+    @Mock
+    PreferenceCategory mConnectedWifiEntryPreferenceCategory;
+    @Mock
+    PreferenceCategory mFirstWifiEntryPreferenceCategory;
 
     @Before
     public void setUp() {
@@ -132,6 +140,15 @@
         mNetworkProviderSettings.mResetInternetPreference = mResetInternetPreference;
         mNetworkProviderSettings.mAirplaneModeMsgPreference = mAirplaneModeMsgPreference;
         mNetworkProviderSettings.mAirplaneModeEnabler = mAirplaneModeEnabler;
+        mNetworkProviderSettings.mInternetUpdater = mInternetUpdater;
+        doReturn(NetworkProviderSettings.PREF_KEY_CONNECTED_ACCESS_POINTS)
+                .when(mConnectedWifiEntryPreferenceCategory).getKey();
+        mNetworkProviderSettings.mConnectedWifiEntryPreferenceCategory =
+                mConnectedWifiEntryPreferenceCategory;
+        doReturn(NetworkProviderSettings.PREF_KEY_FIRST_ACCESS_POINTS)
+                .when(mFirstWifiEntryPreferenceCategory).getKey();
+        mNetworkProviderSettings.mFirstWifiEntryPreferenceCategory =
+                mFirstWifiEntryPreferenceCategory;
         FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL, false);
     }
 
@@ -452,11 +469,48 @@
         verify(mAirplaneModeMsgPreference).setVisible(true);
     }
 
-
     @Test
     public void onAirplaneModeChanged_apmIsOff_hideApmMsg() {
         mNetworkProviderSettings.onAirplaneModeChanged(false);
 
         verify(mAirplaneModeMsgPreference).setVisible(false);
     }
+
+    @Test
+    public void getConnectedWifiPreferenceCategory_internetWiFi_getConnectedAccessPoints() {
+        doReturn(InternetUpdater.INTERNET_WIFI).when(mInternetUpdater).getInternetType();
+
+        final PreferenceCategory pc = mNetworkProviderSettings.getConnectedWifiPreferenceCategory();
+
+        assertThat(pc.getKey()).isEqualTo(NetworkProviderSettings.PREF_KEY_CONNECTED_ACCESS_POINTS);
+    }
+
+    @Test
+    public void getConnectedWifiPreferenceCategory_internetCellular_getFirstAccessPoints() {
+        doReturn(InternetUpdater.INTERNET_CELLULAR).when(mInternetUpdater).getInternetType();
+
+        final PreferenceCategory pc = mNetworkProviderSettings.getConnectedWifiPreferenceCategory();
+
+        assertThat(pc.getKey()).isEqualTo(NetworkProviderSettings.PREF_KEY_FIRST_ACCESS_POINTS);
+    }
+
+    @Test
+    public void createConnectedWifiEntryPreference_internetWiFi_createConnectedPreference() {
+        final WifiEntry wifiEntry = mock(WifiEntry.class);
+        doReturn(InternetUpdater.INTERNET_WIFI).when(mInternetUpdater).getInternetType();
+
+        final Preference p = mNetworkProviderSettings.createConnectedWifiEntryPreference(wifiEntry);
+
+        assertThat(p instanceof ConnectedWifiEntryPreference).isTrue();
+    }
+
+    @Test
+    public void createConnectedWifiEntryPreference_internetCellular_createFirstWifiPreference() {
+        final WifiEntry wifiEntry = mock(WifiEntry.class);
+        doReturn(InternetUpdater.INTERNET_CELLULAR).when(mInternetUpdater).getInternetType();
+
+        final Preference p = mNetworkProviderSettings.createConnectedWifiEntryPreference(wifiEntry);
+
+        assertThat(p instanceof NetworkProviderSettings.FirstWifiEntryPreference).isTrue();
+    }
 }