Add tests to verify response authentication behavior.

testFillResponseAuthBothFields()
A basic response authentication test.

testFillResponseAuth_requestAutofillOnAuthenticationActivity()
A test that verifies Ib06edd823fa4478f34362164f3f7dd3544e51705. When
user requests autofill on Authentication Activity then back, it will
show dropdown suggestion.

Bug: 158877106
Test: atest CtsAutoFillServiceTestCases:InlineAuthenticationTest
Test: atest CtsAutoFillServiceTestCases:AuthenticationTest
Test: atest CtsAutoFillServiceTestCases:PartitionedActivityTest
Test: atest CtsAutoFillServiceTestCases:FillEventHistoryTest
Test: atest CtsAutoFillServiceTestCases:InlineFillEventHistoryTest
Test: atest CtsAutoFillServiceTestCases:DatasetFilteringDropdownTest
Test: atest CtsAutoFillServiceTestCases:DatasetFilteringInlineTest

Change-Id: Ie1d9055b0eabfcaa00861869467be8dcee25833e
diff --git a/tests/autofillservice/res/layout/authentication_activity.xml b/tests/autofillservice/res/layout/authentication_activity.xml
new file mode 100644
index 0000000..23e58e7
--- /dev/null
+++ b/tests/autofillservice/res/layout/authentication_activity.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:focusable="true"
+              android:focusableInTouchMode="true"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Authenticate?" />
+
+    <EditText
+        android:id="@+id/password"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:inputType="textPassword"
+        android:autofillHints="password" />
+
+    <Button
+        android:id="@+id/yes"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Yes" />
+
+</LinearLayout>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
index b247ec2..7ddfccc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
@@ -34,6 +34,8 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.autofill.AutofillManager;
+import android.widget.Button;
+import android.widget.EditText;
 
 import com.google.common.base.Preconditions;
 
@@ -58,6 +60,7 @@
 
 
     private static final int MSG_WAIT_FOR_LATCH = 1;
+    private static final int MSG_REQUEST_AUTOFILL = 2;
 
     private static Bundle sData;
     private static final SparseArray<CannedDataset> sDatasets = new SparseArray<>();
@@ -73,10 +76,18 @@
     // Used to block response until it's counted down.
     private static CountDownLatch sResponseLatch;
 
+    // Guarded by sLock
+    // Used to request autofill for a autofillable view in AuthenticationActivity
+    private static boolean sRequestAutofill;
+
     private Handler mHandler;
 
+    private EditText mPasswordEditText;
+    private Button mYesButton;
+
     static void resetStaticState() {
-        setResultCode(RESULT_OK);
+        setResultCode(null, RESULT_OK);
+        setRequestAutofillForAuthenticationActivity(/* requestAutofill */ false);
         sDatasets.clear();
         sResponses.clear();
         for (int i = 0; i < sPendingIntents.size(); i++) {
@@ -168,15 +179,30 @@
         }
     }
 
+    public static void setRequestAutofillForAuthenticationActivity(boolean requestAutofill) {
+        synchronized (sLock) {
+            sRequestAutofill = requestAutofill;
+        }
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        setContentView(R.layout.authentication_activity);
+
+        mPasswordEditText = findViewById(R.id.password);
+        mYesButton = findViewById(R.id.yes);
+        mYesButton.setOnClickListener(view -> doIt());
+
         mHandler = new Handler(Looper.getMainLooper(), (m) -> {
             switch (m.what) {
                 case MSG_WAIT_FOR_LATCH:
                     waitForLatchAndDoIt();
                     break;
+                case MSG_REQUEST_AUTOFILL:
+                    requestFocusOnPassword();
+                    break;
                 default:
                     throw new IllegalArgumentException("invalid message: " + m);
             }
@@ -186,11 +212,17 @@
         if (sResponseLatch != null) {
             Log.d(TAG, "Delaying message until latch is counted down");
             mHandler.dispatchMessage(mHandler.obtainMessage(MSG_WAIT_FOR_LATCH));
+        } else if (sRequestAutofill) {
+            mHandler.dispatchMessage(mHandler.obtainMessage(MSG_REQUEST_AUTOFILL));
         } else {
             doIt();
         }
     }
 
+    private void requestFocusOnPassword() {
+        syncRunOnUiThread(() -> mPasswordEditText.requestFocus());
+    }
+
     private void waitForLatchAndDoIt() {
         try {
             final boolean called = sResponseLatch.await(5, TimeUnit.SECONDS);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index 838d4ab..f0e1179 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -101,6 +101,10 @@
             return sDefaultUiBot2;
         }
 
+        protected static UiBot getDropdownUiBot() {
+            return sDefaultUiBot;
+        }
+
         @ClassRule
         public static final SettingsStateKeeperRule sPublicServiceSettingsKeeper =
                 sTheRealServiceSettingsKeeper;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
index 2b6afe7..cb30cdd 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.Activity.RESULT_CANCELED;
 import static android.app.Activity.RESULT_OK;
+import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
 import static android.autofillservice.cts.Helper.ID_PASSWORD;
 import static android.autofillservice.cts.Helper.ID_USERNAME;
 import static android.autofillservice.cts.Helper.UNUSED_AUTOFILL_VALUE;
@@ -34,6 +35,7 @@
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.Helper;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.autofillservice.cts.UiBot;
 import android.content.IntentSender;
 import android.platform.test.annotations.AppModeFull;
 
@@ -61,6 +63,101 @@
         Helper.enableAutofillService(getContext(), SERVICE_NAME);
     }
 
+    /**
+     * This test verifies the behavior that user starts a new AutofillSession in Authentication
+     * Activity during the FillResponse authentication flow, we will fallback to dropdown when
+     * authentication done and then back to original Activity.
+     */
+    @Test
+    public void testFillResponseAuth_withNewAutofillSessionStartByActivity()
+            throws Exception {
+        // Set service.
+        enableService();
+
+        // Prepare the authenticated response
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                new CannedFillResponse.Builder().addDataset(
+                        new CannedDataset.Builder()
+                                .setField(ID_USERNAME, "dude")
+                                .setField(ID_PASSWORD, "sweet")
+                                .setId("name")
+                                .setInlinePresentation(createInlinePresentation("Dataset"))
+                                .setPresentation(createPresentation("Dataset"))
+                                .build()).build());
+        // Configure the service behavior
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setAuthentication(authentication, ID_USERNAME, ID_PASSWORD)
+                .setPresentation(createPresentation("Tap to auth!"))
+                .setInlinePresentation(createInlinePresentation("Tap to auth!"))
+                .build());
+
+        // Trigger auto-fill.
+        assertSuggestionShownBySelectViewId(ID_USERNAME, "Tap to auth!");
+        sReplier.getNextFillRequest();
+
+        // Need to trigger autofill on AuthenticationActivity
+        // Set expected response for autofill on AuthenticationActivity
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        AuthenticationActivity.setRequestAutofillForAuthenticationActivity(true);
+        sReplier.addResponse(NO_RESPONSE);
+        // Select the dataset to start authentication
+        mUiBot.selectDataset("Tap to auth!");
+        mUiBot.waitForIdle();
+        sReplier.getNextFillRequest();
+        // Select yes button in AuthenticationActivity to finish authentication
+        mUiBot.selectByRelativeId("yes");
+        mUiBot.waitForIdle();
+
+        // Check fallback to dropdown
+        final UiBot dropDownUiBot = getDropdownUiBot();
+        dropDownUiBot.assertDatasets("Dataset");
+    }
+
+    @Test
+    public void testFillResponseAuth() throws Exception {
+        // Set service.
+        enableService();
+
+        // Prepare the authenticated response
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                new CannedFillResponse.Builder().addDataset(
+                        new CannedDataset.Builder()
+                                .setField(ID_USERNAME, "dude")
+                                .setField(ID_PASSWORD, "sweet")
+                                .setId("name")
+                                .setInlinePresentation(createInlinePresentation("Dataset"))
+                                .setPresentation(createPresentation("Dataset"))
+                                .build()).build());
+        // Configure the service behavior
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setAuthentication(authentication, ID_USERNAME, ID_PASSWORD)
+                .setPresentation(createPresentation("Tap to auth!"))
+                .setInlinePresentation(createInlinePresentation("Tap to auth!"))
+                .build());
+
+        // Set expectation for the activity
+        mActivity.expectAutoFill("dude", "sweet");
+
+        // Trigger auto-fill
+        assertSuggestionShownBySelectViewId(ID_USERNAME, "Tap to auth!");
+
+        sReplier.getNextFillRequest();
+
+        // Set AuthenticationActivity result code
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        // Select the dataset to start authentication
+        mUiBot.selectDataset("Tap to auth!");
+        mUiBot.waitForIdle();
+        // Authentication done, show real dataset
+        mUiBot.assertDatasets("Dataset");
+
+        // Select the dataset and check the result is autofilled.
+        mUiBot.selectDataset("Dataset");
+        mUiBot.waitForIdle();
+        mUiBot.assertNoDatasets();
+        mActivity.assertAutoFilled();
+    }
+
     @Test
     public void testDatasetAuthTwoFields() throws Exception {
         datasetAuthTwoFields(/* cancelFirstAttempt */ false);