Merge "Fix title of PRIVATE_DNS_BROKEN notification when connecting VPN"
am: 82f0c22598

Change-Id: I2df410b6ceb0f9a28ee0f171bb2ff7cadd4cdefb
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index d13e675..bc83780 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -18,6 +18,7 @@
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
 import android.app.Notification;
@@ -89,14 +90,22 @@
         mNotificationTypeMap = new SparseIntArray();
     }
 
+    @VisibleForTesting
+    protected static int approximateTransportType(NetworkAgentInfo nai) {
+        return nai.isVPN() ? TRANSPORT_VPN : getFirstTransportType(nai);
+    }
+
     // TODO: deal more gracefully with multi-transport networks.
     private static int getFirstTransportType(NetworkAgentInfo nai) {
+        // TODO: The range is wrong, the safer and correct way is to change the range from
+        // MIN_TRANSPORT to MAX_TRANSPORT.
         for (int i = 0; i < 64; i++) {
             if (nai.networkCapabilities.hasTransport(i)) return i;
         }
         return -1;
     }
 
+    // TODO: Remove @TransportType or change it to @Transport.
     private static String getTransportName(@TransportType int transportType) {
         Resources r = Resources.getSystem();
         String[] networkTypes = r.getStringArray(R.array.network_switch_type_name);
@@ -146,7 +155,7 @@
         final int transportType;
         final String name;
         if (nai != null) {
-            transportType = getFirstTransportType(nai);
+            transportType = approximateTransportType(nai);
             final String extraInfo = nai.networkInfo.getExtraInfo();
             name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSSID() : extraInfo;
             // Only notify for Internet-capable networks.
@@ -175,7 +184,7 @@
                     tag, nameOf(eventId), getTransportName(transportType), name, highPriority));
         }
 
-        Resources r = Resources.getSystem();
+        Resources r = mContext.getResources();
         final CharSequence title;
         final CharSequence details;
         int icon = getIcon(transportType, notifyType);
@@ -239,7 +248,7 @@
             details = r.getString(R.string.captive_portal_logged_in_detailed);
         } else if (notifyType == NotificationType.NETWORK_SWITCH) {
             String fromTransport = getTransportName(transportType);
-            String toTransport = getTransportName(getFirstTransportType(switchToNai));
+            String toTransport = getTransportName(approximateTransportType(switchToNai));
             title = r.getString(R.string.network_switch_metered, toTransport);
             details = r.getString(R.string.network_switch_metered_detail, toTransport,
                     fromTransport);
@@ -340,8 +349,8 @@
     }
 
     public void showToast(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
-        String fromTransport = getTransportName(getFirstTransportType(fromNai));
-        String toTransport = getTransportName(getFirstTransportType(toNai));
+        String fromTransport = getTransportName(approximateTransportType(fromNai));
+        String toTransport = getTransportName(approximateTransportType(toNai));
         String text = mContext.getResources().getString(
                 R.string.network_switch_metered_toast, fromTransport, toTransport);
         Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 9580763..d57f225 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -40,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 
 import org.junit.Before;
@@ -60,12 +62,19 @@
 
     static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
     static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
+    static final NetworkCapabilities VPN_CAPABILITIES = new NetworkCapabilities();
     static {
         CELL_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
         CELL_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
 
         WIFI_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
         WIFI_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        // Set the underyling network to wifi.
+        VPN_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+        VPN_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
+        VPN_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        VPN_CAPABILITIES.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
     }
 
     @Mock Context mCtx;
@@ -75,6 +84,7 @@
     @Mock NotificationManager mNotificationManager;
     @Mock NetworkAgentInfo mWifiNai;
     @Mock NetworkAgentInfo mCellNai;
+    @Mock NetworkAgentInfo mVpnNai;
     @Mock NetworkInfo mNetworkInfo;
     ArgumentCaptor<Notification> mCaptor;
 
@@ -88,6 +98,9 @@
         mWifiNai.networkInfo = mNetworkInfo;
         mCellNai.networkCapabilities = CELL_CAPABILITIES;
         mCellNai.networkInfo = mNetworkInfo;
+        mVpnNai.networkCapabilities = VPN_CAPABILITIES;
+        mVpnNai.networkInfo = mNetworkInfo;
+        doReturn(true).when(mVpnNai).isVPN();
         when(mCtx.getResources()).thenReturn(mResources);
         when(mCtx.getPackageManager()).thenReturn(mPm);
         when(mCtx.getApplicationInfo()).thenReturn(new ApplicationInfo());
@@ -97,6 +110,35 @@
         mManager = new NetworkNotificationManager(mCtx, mTelephonyManager, mNotificationManager);
     }
 
+    private void verifyTitleByNetwork(final int id, final NetworkAgentInfo nai, final int title) {
+        final String tag = NetworkNotificationManager.tagFor(id);
+        mManager.showNotification(id, PRIVATE_DNS_BROKEN, nai, null, null, true);
+        verify(mNotificationManager, times(1))
+                .notifyAsUser(eq(tag), eq(PRIVATE_DNS_BROKEN.eventId), any(), any());
+        final int transportType = NetworkNotificationManager.approximateTransportType(nai);
+        if (transportType == NetworkCapabilities.TRANSPORT_WIFI) {
+            verify(mResources, times(1)).getString(title, eq(any()));
+        } else {
+            verify(mResources, times(1)).getString(title);
+        }
+        verify(mResources, times(1)).getString(R.string.private_dns_broken_detailed);
+    }
+
+    @Test
+    public void testTitleOfPrivateDnsBroken() {
+        // Test the title of mobile data.
+        verifyTitleByNetwork(100, mCellNai, R.string.mobile_no_internet);
+        reset(mResources);
+
+        // Test the title of wifi.
+        verifyTitleByNetwork(101, mWifiNai, R.string.wifi_no_internet);
+        reset(mResources);
+
+        // Test the title of other networks.
+        verifyTitleByNetwork(102, mVpnNai, R.string.other_networks_no_internet);
+        reset(mResources);
+    }
+
     @Test
     public void testNotificationsShownAndCleared() {
         final int NETWORK_ID_BASE = 100;