Snap for 7478028 from 4f55df4e98d7d0cc18bc3fb67f44396005bb157a to mainline-adbd-release

Change-Id: If85733a9157569dadfef5af6867aa816299173be
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0b0c191..8843813 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -49,6 +49,7 @@
             android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
             android:theme="@style/AppTheme"
+            android:exported="true"
             android:configChanges="keyboardHidden|orientation|screenSize" >
             <intent-filter>
                 <action android:name="android.net.conn.CAPTIVE_PORTAL"/>
diff --git a/TEST_MAPPING b/TEST_MAPPING
index ebea16d..c2cd949 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,5 +3,10 @@
     {
       "name": "CaptivePortalLoginTests"
     }
+  ],
+  "mainline-postsubmit": [
+    {
+      "name": "CaptivePortalLoginTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+    }
   ]
 }
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index e18c876..f65d3d9 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -20,7 +20,7 @@
     <string name="ssl_security_warning_title" msgid="7912335118289529802">"Коопсуздук эскертүүсү"</string>
     <string name="ssl_error_view_certificate" msgid="3447891108083278449">"Тастыктаманы көрүү"</string>
     <string name="custom_scheme_warning" msgid="1809266150423969087">"Кошулууга аракет кылып жаткан тармагыңыз башка колдонмону ачууну өтүнүүдө"</string>
-    <string name="custom_scheme_example" msgid="7126568152528588592">"Мисалы, аккаунтка кирүү баракчасы аныктыгын текшерүү үчүн, белгилүү бир колдонмону талап кылышы мүмкүн"</string>
+    <string name="custom_scheme_example" msgid="7126568152528588592">"Мисалы, аккаунтка кирүү баракчасы аныктыгын текшерүү үчүн белгилүү бир колдонмону талап кылышы мүмкүн"</string>
     <string name="ok" msgid="6584612582120777209">"ЖАРАЙТ"</string>
     <string name="page_info_address" msgid="1290683284404217554">"Дарек:"</string>
     <string name="page_info" msgid="46593086046896385">"Барак жөнүндө маалымат"</string>
diff --git a/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 7701fe8..53803ba 100755
--- a/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -912,7 +912,7 @@
 
     private String getHeaderTitle() {
         NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        final CharSequence networkName = getNetworkName();
+        final CharSequence networkName = getNetworkName(nc);
         if (TextUtils.isEmpty(networkName)
                 || nc == null || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
             return getString(R.string.action_bar_label);
@@ -920,18 +920,25 @@
         return getString(R.string.action_bar_title, networkName);
     }
 
-    private CharSequence getNetworkName() {
+    private CharSequence getNetworkName(NetworkCapabilities nc) {
         // Use the venue friendly name if available
         if (!TextUtils.isEmpty(mVenueFriendlyName)) {
             return mVenueFriendlyName;
         }
 
-        // TODO: remove once SSID is obtained from NetworkCapabilities
-        if (mWifiManager == null) {
+        // SSID is only available in NetworkCapabilities from R
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            if (mWifiManager == null) {
+                return null;
+            }
+            final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+            return removeDoubleQuotes(wifiInfo.getSSID());
+        }
+
+        if (nc == null) {
             return null;
         }
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        return removeDoubleQuotes(wifiInfo.getSSID());
+        return removeDoubleQuotes(nc.getSsid());
     }
 
     private static String removeDoubleQuotes(String string) {
diff --git a/src/com/android/captiveportallogin/DownloadService.java b/src/com/android/captiveportallogin/DownloadService.java
index e748bbd..da8eb2c 100644
--- a/src/com/android/captiveportallogin/DownloadService.java
+++ b/src/com/android/captiveportallogin/DownloadService.java
@@ -122,7 +122,7 @@
                     .setIdentifier(String.valueOf(mId));
 
             final PendingIntent pendingIntent = PendingIntent.getService(context,
-                    0 /* requestCode */, cancelIntent, 0 /* flags */);
+                    0 /* requestCode */, cancelIntent, PendingIntent.FLAG_IMMUTABLE);
             final Notification.Action cancelAction = new Notification.Action.Builder(
                     Icon.createWithResource(context, R.drawable.ic_close),
                     res.getString(android.R.string.cancel),
diff --git a/tests/Android.bp b/tests/Android.bp
index 78b10c3..17efed4 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -20,6 +20,7 @@
 
 android_test {
     name: "CaptivePortalLoginTests",
+    defaults: ["framework-connectivity-test-defaults"],
     srcs: ["src/**/*.java", "src/**/*.kt"],
     platform_apis: true,
     min_sdk_version: "29",
diff --git a/tests/src/com/android/captiveportallogin/CaptivePortalLoginActivityTest.java b/tests/src/com/android/captiveportallogin/CaptivePortalLoginActivityTest.java
index 79044a2..3cd349a 100644
--- a/tests/src/com/android/captiveportallogin/CaptivePortalLoginActivityTest.java
+++ b/tests/src/com/android/captiveportallogin/CaptivePortalLoginActivityTest.java
@@ -67,6 +67,8 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.Uri;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ConditionVariable;
@@ -96,6 +98,7 @@
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.ServerSocket;
+import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -110,6 +113,8 @@
 public class CaptivePortalLoginActivityTest {
     private static final String TEST_URL = "http://android.test.com";
     private static final int TEST_NETID = 1234;
+    private static final String TEST_NC_SSID = "Test NetworkCapabilities SSID";
+    private static final String TEST_WIFIINFO_SSID = "Test Other SSID";
     private static final String TEST_URL_QUERY = "testquery";
     private static final long TEST_TIMEOUT_MS = 10_000L;
     private static final LinkAddress TEST_LINKADDR = new LinkAddress(
@@ -122,6 +127,7 @@
     private TestNetworkTracker mTestNetworkTracker;
 
     private static ConnectivityManager sConnectivityManager;
+    private static WifiManager sMockWifiManager;
     private static DevicePolicyManager sMockDevicePolicyManager;
 
     public static class InstrumentedCaptivePortalLoginActivity extends CaptivePortalLoginActivity {
@@ -129,9 +135,16 @@
         private final CompletableFuture<Intent> mForegroundServiceStart = new CompletableFuture<>();
         @Override
         public Object getSystemService(String name) {
-            if (Context.CONNECTIVITY_SERVICE.equals(name)) return sConnectivityManager;
-            if (Context.DEVICE_POLICY_SERVICE.equals(name)) return sMockDevicePolicyManager;
-            return super.getSystemService(name);
+            switch (name) {
+                case Context.CONNECTIVITY_SERVICE:
+                    return sConnectivityManager;
+                case Context.DEVICE_POLICY_SERVICE:
+                    return sMockDevicePolicyManager;
+                case Context.WIFI_SERVICE:
+                    return sMockWifiManager;
+                default:
+                    return super.getSystemService(name);
+            }
         }
 
         @Override
@@ -213,6 +226,7 @@
     public void setUp() throws Exception {
         final Context context = getInstrumentation().getContext();
         sConnectivityManager = spy(context.getSystemService(ConnectivityManager.class));
+        sMockWifiManager = mock(WifiManager.class);
         sMockDevicePolicyManager = mock(DevicePolicyManager.class);
         MockitoAnnotations.initMocks(this);
         mSession = mockitoSession()
@@ -233,15 +247,34 @@
             automation.dropShellPermissionIdentity();
         }
         mNetwork = mTestNetworkTracker.getNetwork();
+
+        final WifiInfo testInfo = makeWifiInfo();
+        doReturn(testInfo).when(sMockWifiManager).getConnectionInfo();
+    }
+
+    private static WifiInfo makeWifiInfo() throws Exception {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            return new WifiInfo.Builder()
+                    .setSsid(TEST_WIFIINFO_SSID.getBytes(StandardCharsets.US_ASCII))
+                    .build();
+        }
+
+        // WifiInfo did not have a builder before R. Use non-public APIs on Q to set SSID.
+        final WifiInfo info = WifiInfo.class.getConstructor().newInstance();
+        final Class<?> wifiSsidClass = Class.forName("android.net.wifi.WifiSsid");
+        final Object wifiSsid = wifiSsidClass.getMethod("createFromAsciiEncoded",
+                String.class).invoke(null, TEST_WIFIINFO_SSID);
+        WifiInfo.class.getMethod("setSSID", wifiSsidClass).invoke(info, wifiSsid);
+        return info;
     }
 
     @After
     public void tearDown() throws Exception {
         mActivityRule.finishActivity();
-        mActivity.waitForDestroy(TEST_TIMEOUT_MS);
+        if (mActivity != null) mActivity.waitForDestroy(TEST_TIMEOUT_MS);
         getInstrumentation().getContext().getSystemService(ConnectivityManager.class)
                 .bindProcessToNetwork(null);
-        mTestNetworkTracker.teardown();
+        if (mTestNetworkTracker != null) mTestNetworkTracker.teardown();
         // finish mocking after the activity has terminated to avoid races on teardown.
         mSession.finishMocking();
     }
@@ -287,8 +320,17 @@
     private void configNonVpnNetwork() {
         final Network[] networks = new Network[] {new Network(mNetwork)};
         doReturn(networks).when(sConnectivityManager).getAllNetworks();
-        final NetworkCapabilities nonVpnCapabilities = new NetworkCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+        final NetworkCapabilities nonVpnCapabilities;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            // SSID and NetworkCapabilities builder was added in R
+            nonVpnCapabilities = new NetworkCapabilities.Builder()
+                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                    .setSsid(TEST_NC_SSID)
+                    .build();
+        } else {
+            nonVpnCapabilities = new NetworkCapabilities()
+                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+        }
         doReturn(nonVpnCapabilities).when(sConnectivityManager).getNetworkCapabilities(
                 mNetwork);
     }
@@ -559,21 +601,39 @@
         final Method setVenueFriendlyNameMethod;
 
         setVenueFriendlyNameMethod = captivePortalDataBuilderClass.getDeclaredMethod(
-                "setVenueFriendlyNameMethod", String.class);
+                "setVenueFriendlyName", CharSequence.class);
 
         captivePortalDataBuilder = (CaptivePortalData.Builder)
-                setVenueFriendlyNameMethod.invoke(captivePortalDataBuilder,
-                        TEST_FRIENDLY_NAME);
+                setVenueFriendlyNameMethod.invoke(captivePortalDataBuilder, TEST_FRIENDLY_NAME);
 
         final CaptivePortalData captivePortalData = captivePortalDataBuilder.build();
         linkProperties.setCaptivePortalData(captivePortalData);
+
         when(sConnectivityManager.getLinkProperties(mNetwork)).thenReturn(linkProperties);
+        configNonVpnNetwork();
         initActivity("https://tc.example.com/");
 
         // Verify that the correct venue friendly name is used
+        assertEquals(getInstrumentation().getContext().getString(R.string.action_bar_title,
+                TEST_FRIENDLY_NAME), mActivity.getActionBar().getTitle());
+    }
+
+    @Test @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.Q)
+    public void testWifiSsid_Q() throws Exception {
+        configNonVpnNetwork();
+        initActivity("https://portal.example.com/");
         assertEquals(mActivity.getActionBar().getTitle(),
                 getInstrumentation().getContext().getString(R.string.action_bar_title,
-                        TEST_FRIENDLY_NAME));
+                        TEST_WIFIINFO_SSID));
+    }
+
+    @Test @SdkSuppress(minSdkVersion = Build.VERSION_CODES.R)
+    public void testWifiSsid() throws Exception {
+        configNonVpnNetwork();
+        initActivity("https://portal.example.com/");
+        assertEquals(mActivity.getActionBar().getTitle(),
+                getInstrumentation().getContext().getString(R.string.action_bar_title,
+                        TEST_NC_SSID));
     }
 
     /**