Show "Connected / No internet access" for expected internet networks

Networks that are expected to have internet access (i.e. the user hasn't
accepted to stay connected via the "No internet" dialog) should show
"Connected / No internet access" instead of "Connected to device. Can't
provide internet."

Bug: 230794429
Test: atest WifiTrackerLibTests, manually verify string when connected
to a no-internet network

Change-Id: I073df8b59b5069b750cc8b669055f35b60e0ee97
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
index fde1781..fab77bb 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
@@ -258,7 +258,8 @@
 
         // For displaying network capability info, such as captive portal or no internet
         String networkCapabilitiesInformation = getCurrentNetworkCapabilitiesInformation(
-                context,  networkCapabilities, connectivityReport);
+                context,  networkCapabilities, connectivityReport,
+                wifiConfiguration != null && wifiConfiguration.isNoInternetAccessExpected());
         if (!TextUtils.isEmpty(networkCapabilitiesInformation)) {
             sj.add(networkCapabilitiesInformation);
         }
@@ -518,7 +519,8 @@
 
     static String getCurrentNetworkCapabilitiesInformation(@Nullable Context context,
             @Nullable NetworkCapabilities networkCapabilities,
-            @Nullable ConnectivityDiagnosticsManager.ConnectivityReport connectivityReport) {
+            @Nullable ConnectivityDiagnosticsManager.ConnectivityReport connectivityReport,
+            boolean noInternetExpected) {
         if (context == null || networkCapabilities == null) {
             return "";
         }
@@ -534,14 +536,23 @@
         }
 
         if (!networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
-            if (connectivityReport == null) {
+            if (connectivityReport == null && !noInternetExpected) {
                 return context.getString(R.string.wifitrackerlib_checking_for_internet_access);
             }
             if (networkCapabilities.isPrivateDnsBroken()) {
                 return context.getString(R.string.wifitrackerlib_private_dns_broken);
             }
-            return context.getString(
-                R.string.wifitrackerlib_wifi_connected_cannot_provide_internet);
+            if (noInternetExpected) {
+                return context.getString(
+                        R.string.wifitrackerlib_wifi_connected_cannot_provide_internet);
+            }
+            // Connected / No internet access
+            final StringJoiner sj = new StringJoiner(context.getString(
+                    R.string.wifitrackerlib_summary_separator));
+            sj.add(context.getResources().getStringArray(R.array.wifitrackerlib_wifi_status)
+                    [DetailedState.CONNECTED.ordinal()]);
+            sj.add(context.getString(R.string.wifitrackerlib_wifi_no_internet));
+            return sj.toString();
         }
         return "";
     }
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
index 3cdd811..d421e6b 100644
--- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
@@ -725,6 +725,70 @@
         assertThat(wifiPickerTracker.getConnectedWifiEntry().getSummary()).isEqualTo("Connected");
     }
 
+    /**
+     * Tests that a connected WifiEntry that is expected to have no internet will display
+     * "Connected to device. Can't provide internet" if the network is not validated.
+     */
+    @Test
+    public void testGetConnectedEntry_wifiNotValidated_showsConnectedToDevice() {
+        final String summarySeparator = " / ";
+        final String connectedToDevice = "Connected to device. Can't provide internet";
+        final String[] wifiStatusArray = new String[]{"", "Scanning", "Connecting",
+                "Authenticating", "Obtaining IP address", "Connected"};
+        when(mMockContext.getString(R.string.wifitrackerlib_summary_separator))
+                .thenReturn(summarySeparator);
+        when(mMockContext.getString(R.string.wifitrackerlib_wifi_connected_cannot_provide_internet))
+                .thenReturn(connectedToDevice);
+        when(mMockResources.getStringArray(R.array.wifitrackerlib_wifi_status))
+                .thenReturn(wifiStatusArray);
+        WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+        when(primaryWifiInfo.isPrimary()).thenReturn(true);
+        when(primaryWifiInfo.makeCopy(anyLong())).thenReturn(primaryWifiInfo);
+        NetworkCapabilities primaryCap = new NetworkCapabilities.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .setTransportInfo(primaryWifiInfo)
+                .build();
+        when(mMockConnectivityManager.getNetworkCapabilities(any())).thenReturn(primaryCap);
+
+        final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
+        final WifiConfiguration config = spy(new WifiConfiguration());
+        config.SSID = "\"ssid\"";
+        config.networkId = 1;
+        when(config.isNoInternetAccessExpected()).thenReturn(true);
+        when(mMockWifiManager.getPrivilegedConfiguredNetworks())
+                .thenReturn(Collections.singletonList(config));
+        when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
+                buildScanResult("ssid", "bssid", START_MILLIS)));
+        when(mMockWifiInfo.getNetworkId()).thenReturn(1);
+        when(mMockWifiInfo.getRssi()).thenReturn(-50);
+        when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
+        when(mMockConnectivityManager.getNetworkInfo(any())).thenReturn(mMockNetworkInfo);
+        ArgumentCaptor<ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback>
+                diagnosticsCallbackCaptor = ArgumentCaptor.forClass(
+                ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback.class);
+        wifiPickerTracker.onStart();
+        mTestLooper.dispatchAll();
+        verify(mMockConnectivityManager)
+                .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
+        verify(mMockConnectivityDiagnosticsManager).registerConnectivityDiagnosticsCallback(
+                any(), any(), diagnosticsCallbackCaptor.capture());
+
+        assertThat(wifiPickerTracker.getConnectedWifiEntry().getSummary())
+                .isEqualTo(connectedToDevice);
+
+        // Trigger a no-validation callback and connectivity report for the primary Wifi network.
+        primaryCap = new NetworkCapabilities.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .setTransportInfo(primaryWifiInfo)
+                .build();
+        mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork, primaryCap);
+        ConnectivityDiagnosticsManager.ConnectivityReport report = mock(
+                ConnectivityDiagnosticsManager.ConnectivityReport.class);
+        diagnosticsCallbackCaptor.getValue().onConnectivityReportAvailable(report);
+
+        assertThat(wifiPickerTracker.getConnectedWifiEntry().getSummary())
+                .isEqualTo(connectedToDevice);
+    }
 
     /**
      * Tests that a PasspointWifiEntry is returned when Passpoint scans are visible.