• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.autofillservice.cts.augmented;
18 
19 import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
20 import static android.autofillservice.cts.Helper.ID_PASSWORD;
21 import static android.autofillservice.cts.Helper.ID_USERNAME;
22 import static android.autofillservice.cts.Helper.assertHasFlags;
23 import static android.autofillservice.cts.Helper.assertTextAndValue;
24 import static android.autofillservice.cts.Helper.assertViewAutofillState;
25 import static android.autofillservice.cts.Helper.findNodeByResourceId;
26 import static android.autofillservice.cts.LoginActivity.getWelcomeMessage;
27 import static android.autofillservice.cts.UiBot.LANDSCAPE;
28 import static android.autofillservice.cts.UiBot.PORTRAIT;
29 import static android.autofillservice.cts.augmented.AugmentedHelper.assertBasicRequestInfo;
30 import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
31 import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.DO_NOT_REPLY_AUGMENTED_RESPONSE;
32 import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.NO_AUGMENTED_RESPONSE;
33 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
34 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
35 
36 import static com.google.common.truth.Truth.assertThat;
37 import static com.google.common.truth.Truth.assertWithMessage;
38 
39 import static org.junit.Assume.assumeTrue;
40 import static org.testng.Assert.assertThrows;
41 
42 import android.app.assist.AssistStructure.ViewNode;
43 import android.autofillservice.cts.AutofillActivityTestRule;
44 import android.autofillservice.cts.CannedFillResponse;
45 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
46 import android.autofillservice.cts.Helper;
47 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
48 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
49 import android.autofillservice.cts.LoginActivity;
50 import android.autofillservice.cts.MyAutofillCallback;
51 import android.autofillservice.cts.OneTimeCancellationSignalListener;
52 import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
53 import android.content.ComponentName;
54 import android.os.CancellationSignal;
55 import android.platform.test.annotations.AppModeFull;
56 import android.support.test.uiautomator.UiObject2;
57 import android.util.ArraySet;
58 import android.view.View;
59 import android.view.autofill.AutofillId;
60 import android.view.autofill.AutofillManager;
61 import android.view.autofill.AutofillValue;
62 import android.widget.EditText;
63 
64 import org.junit.Test;
65 
66 import java.util.Set;
67 
68 public class AugmentedLoginActivityTest
69         extends AugmentedAutofillAutoActivityLaunchTestCase<AugmentedLoginActivity> {
70 
71     protected AugmentedLoginActivity mActivity;
72 
73     @Override
getActivityRule()74     protected AutofillActivityTestRule<AugmentedLoginActivity> getActivityRule() {
75         return new AutofillActivityTestRule<AugmentedLoginActivity>(
76                 AugmentedLoginActivity.class) {
77             @Override
78             protected void afterActivityLaunched() {
79                 mActivity = getActivity();
80             }
81         };
82     }
83 
84     @Test
85     public void testServiceLifecycle() throws Exception {
86         enableService();
87         CtsAugmentedAutofillService augmentedService = enableAugmentedService();
88 
89         AugmentedHelper.resetAugmentedService();
90         augmentedService.waitUntilDisconnected();
91     }
92 
93     @Test
94     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
95     public void testAutoFill_neitherServiceCanAutofill() throws Exception {
96         // Set services
97         enableService();
98         enableAugmentedService();
99 
100         // Set expectations
101         final EditText username = mActivity.getUsername();
102         final AutofillValue expectedFocusedValue = username.getAutofillValue();
103         final AutofillId usernameId = username.getAutofillId();
104         sReplier.addResponse(NO_RESPONSE);
105         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
106 
107         // Trigger autofill
108         mActivity.onUsername(View::requestFocus);
109         sReplier.getNextFillRequest();
110         final AugmentedFillRequest augmentedRequest = sAugmentedReplier.getNextFillRequest();
111 
112         // Assert request
113         assertBasicRequestInfo(augmentedRequest, mActivity, usernameId, expectedFocusedValue);
114 
115         // Make sure standard Autofill UI is not shown.
116         mUiBot.assertNoDatasetsEver();
117 
118         // Make sure Augmented Autofill UI is not shown.
119         mAugmentedUiBot.assertUiNeverShown();
120     }
121 
122     @Test
123     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
124     public void testAutoFill_neitherServiceCanAutofill_manualRequest() throws Exception {
125         // Set services
126         enableService();
127         enableAugmentedService();
128 
129         // Set expectations
130         final EditText username = mActivity.getUsername();
131         final AutofillValue expectedFocusedValue = username.getAutofillValue();
132         final AutofillId usernameId = username.getAutofillId();
133         sReplier.addResponse(NO_RESPONSE);
134         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
135 
136         // Trigger autofill
137         mActivity.forceAutofillOnUsername();
138         sReplier.getNextFillRequest();
139         final AugmentedFillRequest augmentedRequest = sAugmentedReplier.getNextFillRequest();
140 
141         // Assert request
142         assertBasicRequestInfo(augmentedRequest, mActivity, usernameId, expectedFocusedValue);
143 
144         // Make sure standard Autofill UI is not shown.
145         mUiBot.assertNoDatasetsEver();
146 
147         // Make sure Augmented Autofill UI is not shown.
148         mAugmentedUiBot.assertUiNeverShown();
149     }
150 
151     @Test
152     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
153     public void testAutoFill_neitherServiceCanAutofill_thenManualRequest() throws Exception {
154         // Set services
155         enableService();
156         enableAugmentedService();
157 
158         // Set expectations
159         final EditText username = mActivity.getUsername();
160         final AutofillValue expectedFocusedValue = username.getAutofillValue();
161         final AutofillId expectedFocusedId = username.getAutofillId();
162         sReplier.addResponse(NO_RESPONSE);
163         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
164 
165         // Trigger autofill
166         mActivity.onUsername(View::requestFocus);
167         sReplier.getNextFillRequest();
168         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
169 
170         // Assert request
171         assertBasicRequestInfo(request, mActivity, expectedFocusedId, expectedFocusedValue);
172 
173         // Make sure standard Autofill UI is not shown.
174         mUiBot.assertNoDatasetsEver();
175 
176         // Make sure Augmented Autofill UI is not shown.
177         mAugmentedUiBot.assertUiNeverShown();
178 
179         // Try again, forcing it
180         sReplier.addResponse(new CannedFillResponse.Builder()
181                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
182                 .addDataset(new CannedDataset.Builder()
183                         .setField(ID_USERNAME, "dude")
184                         .setField(ID_PASSWORD, "sweet")
185                         .setPresentation(createPresentation("The Dude"))
186                         .build())
187                 .build());
188         mActivity.expectAutoFill("dude", "sweet");
189         mActivity.forceAutofillOnUsername();
190         final FillRequest fillRequest = sReplier.getNextFillRequest();
191         assertHasFlags(fillRequest.flags, FLAG_MANUAL_REQUEST);
192         mAugmentedUiBot.assertUiNeverShown();
193 
194         mUiBot.selectDataset("The Dude");
195         mActivity.assertAutoFilled();
196 
197         // Now force save to make sure the values changes are notified
198         mActivity.onUsername((v) -> v.setText("malkovich"));
199         mActivity.onPassword((v) -> v.setText("malkovich"));
200         final String expectedMessage = getWelcomeMessage("malkovich");
201         final String actualMessage = mActivity.tapLogin();
202         assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
203 
204         // Assert the snack bar is shown and tap "Save".
205         mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
206         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
207         sReplier.assertNoUnhandledSaveRequests();
208         assertThat(saveRequest.datasetIds).isNull();
209 
210         // Assert value of expected fields - should not be sanitized.
211         final ViewNode usernameNode = findNodeByResourceId(saveRequest.structure, ID_USERNAME);
212         assertTextAndValue(usernameNode, "malkovich");
213         final ViewNode passwordNode = findNodeByResourceId(saveRequest.structure, ID_PASSWORD);
214         assertTextAndValue(passwordNode, "malkovich");
215     }
216 
217     @Test
218     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
219     public void testAutoFill_notImportantForAutofill_thenManualRequest() throws Exception {
220         // Set services
221         enableService();
222         enableAugmentedService();
223 
224         // Set IMPORTANT_FOR_AUTOFILL_NO
225         mActivity.onUsername((v) -> v.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO));
226 
227         // Set expectations
228         final EditText username = mActivity.getUsername();
229         final AutofillValue expectedFocusedValue = username.getAutofillValue();
230         final AutofillId expectedFocusedId = username.getAutofillId();
231         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
232 
233         // Trigger autofill
234         mActivity.onUsername(View::requestFocus);
235         sReplier.assertOnFillRequestNotCalled();
236         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
237 
238         // Assert request
239         assertBasicRequestInfo(request, mActivity, expectedFocusedId, expectedFocusedValue);
240 
241         // Make sure standard Autofill UI is not shown.
242         mUiBot.assertNoDatasetsEver();
243 
244         // Make sure Augmented Autofill UI is not shown.
245         mAugmentedUiBot.assertUiNeverShown();
246 
247         // Try again, forcing it
248         sReplier.addResponse(new CannedFillResponse.Builder()
249                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
250                 .addDataset(new CannedDataset.Builder()
251                         .setField(ID_USERNAME, "dude")
252                         .setField(ID_PASSWORD, "sweet")
253                         .setPresentation(createPresentation("The Dude"))
254                         .build())
255                 .build());
256         mActivity.expectAutoFill("dude", "sweet");
257         mActivity.forceAutofillOnUsername();
258         final FillRequest fillRequest = sReplier.getNextFillRequest();
259         assertHasFlags(fillRequest.flags, FLAG_MANUAL_REQUEST);
260         mAugmentedUiBot.assertUiNeverShown();
261 
262         mUiBot.selectDataset("The Dude");
263         mActivity.assertAutoFilled();
264 
265         // Now force save to make sure the values changes are notified
266         mActivity.onUsername((v) -> v.setText("malkovich"));
267         mActivity.onPassword((v) -> v.setText("malkovich"));
268         final String expectedMessage = getWelcomeMessage("malkovich");
269         final String actualMessage = mActivity.tapLogin();
270         assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
271 
272         // Assert the snack bar is shown and tap "Save".
273         mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
274         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
275         sReplier.assertNoUnhandledSaveRequests();
276         assertThat(saveRequest.datasetIds).isNull();
277 
278         // Assert value of expected fields - should not be sanitized.
279         final ViewNode usernameNode = findNodeByResourceId(saveRequest.structure, ID_USERNAME);
280         assertTextAndValue(usernameNode, "malkovich");
281         final ViewNode passwordNode = findNodeByResourceId(saveRequest.structure, ID_PASSWORD);
282         assertTextAndValue(passwordNode, "malkovich");
283     }
284 
285     @Test
286     public void testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField() throws Exception {
287         // Set services
288         enableService();
289         enableAugmentedService();
290 
291         // Set expectations
292         final EditText username = mActivity.getUsername();
293         final AutofillId usernameId = username.getAutofillId();
294         final AutofillValue expectedFocusedValue = username.getAutofillValue();
295         sReplier.addResponse(NO_RESPONSE);
296         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
297                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
298                         .setField(usernameId, "dude")
299                         .build(), usernameId)
300                 .build());
301         mActivity.expectAutoFill("dude");
302 
303         // Trigger autofill
304         mActivity.onUsername(View::requestFocus);
305         sReplier.getNextFillRequest();
306         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
307 
308         // Assert request
309         assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
310 
311         // Make sure standard Autofill UI is not shown.
312         mUiBot.assertNoDatasetsEver();
313 
314         // Make sure Augmented Autofill UI is shown.
315         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
316 
317         // Autofill
318         ui.click();
319         mActivity.assertAutoFilled();
320         mAugmentedUiBot.assertUiGone();
321     }
322 
323     @Test
324     public void testAutoFill_augmentedFillRequestCancelled() throws Exception {
325         // Set services
326         enableService();
327         enableAugmentedService();
328 
329         // Set expectations
330         final EditText username = mActivity.getUsername();
331         final AutofillId usernameId = username.getAutofillId();
332         sReplier.addResponse(NO_RESPONSE);
333         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
334                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
335                         .setField(usernameId, "dude")
336                         .build(), usernameId)
337                 .setDelay(AUGMENTED_FILL_TIMEOUT.ms() + 6000)
338                 .build());
339 
340         // Trigger autofill
341         mActivity.onUsername(View::requestFocus);
342         sReplier.getNextFillRequest();
343         sAugmentedReplier.getNextFillRequest();
344 
345         // Make sure standard Autofill UI is not shown.
346         mUiBot.assertNoDatasetsEver();
347 
348         // Make sure Augmented Autofill UI is shown.
349         mAugmentedUiBot.assertUiNeverShown();
350     }
351 
352     @Test
353     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
354     public void testAutoFill_mainServiceReturnedNull_augmentedAutofillTwoFields() throws Exception {
355         // Set services
356         enableService();
357         enableAugmentedService();
358 
359         // Set expectations
360         final EditText username = mActivity.getUsername();
361         final AutofillId usernameId = username.getAutofillId();
362         final AutofillValue expectedFocusedValue = username.getAutofillValue();
363         sReplier.addResponse(NO_RESPONSE);
364         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
365                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
366                         .setField(usernameId, "dude")
367                         .setField(mActivity.getPassword().getAutofillId(), "sweet")
368                         .build(), usernameId)
369                 .build());
370         mActivity.expectAutoFill("dude", "sweet");
371 
372         // Trigger autofill
373         mActivity.onUsername(View::requestFocus);
374         sReplier.getNextFillRequest();
375         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
376 
377         // Assert request
378         assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
379 
380         // Make sure standard Autofill UI is not shown.
381         mUiBot.assertNoDatasetsEver();
382 
383         // Make sure Augmented Autofill UI is shown.
384         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
385 
386         // Autofill
387         ui.click();
388         mActivity.assertAutoFilled();
389         mAugmentedUiBot.assertUiGone();
390     }
391 
392     @Test
393     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
394     public void testCancellationSignalCalledAfterTimeout() throws Exception {
395         // Set services
396         enableService();
397         enableAugmentedService();
398 
399         // Set expectations
400         sReplier.addResponse(NO_RESPONSE);
401         sAugmentedReplier.addResponse(DO_NOT_REPLY_AUGMENTED_RESPONSE);
402         final OneTimeCancellationSignalListener listener =
403                 new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 5000);
404 
405         // Trigger autofill
406         mActivity.onUsername(View::requestFocus);
407         sReplier.getNextFillRequest();
408 
409         final CancellationSignal cancellationSignal = sAugmentedReplier.getNextFillRequest()
410                 .cancellationSignal;
411 
412         assertThat(cancellationSignal).isNotNull();
413         cancellationSignal.setOnCancelListener(listener);
414 
415         // Assert results
416         listener.assertOnCancelCalled();
417     }
418 
419     @Test
420     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
421     public void testCancellationSignalCalled_retriggerAugmentedAutofill() throws Exception {
422         // Set services
423         enableService();
424         enableAugmentedService();
425 
426         // Set expectations
427         final EditText username = mActivity.getUsername();
428         final AutofillId usernameId = username.getAutofillId();
429         final AutofillValue expectedFocusedValue = username.getAutofillValue();
430         sReplier.addResponse(NO_RESPONSE);
431         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
432                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
433                         .setField(usernameId, "dude")
434                         .setField(mActivity.getPassword().getAutofillId(), "sweet")
435                         .build(), usernameId)
436                 .build());
437 
438         final OneTimeCancellationSignalListener listener =
439                 new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 5000);
440 
441         // Trigger autofill
442         mActivity.onUsername(View::requestFocus);
443         sReplier.getNextFillRequest();
444         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
445 
446         // Assert request
447         assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
448         mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
449 
450         final CancellationSignal cancellationSignal = request.cancellationSignal;
451 
452         assertThat(cancellationSignal).isNotNull();
453         cancellationSignal.setOnCancelListener(listener);
454 
455         // Move focus away to make sure Augmented Autofill UI is gone.
456         mActivity.clearFocus();
457         mAugmentedUiBot.assertUiGone();
458 
459         // Set expectations for username again.
460         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
461                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
462                         .setField(usernameId, "dude")
463                         .setField(mActivity.getPassword().getAutofillId(), "sweet")
464                         .build(), usernameId)
465                 .build());
466 
467         // Tap on username again
468         mActivity.onUsername(View::requestFocus);
469         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
470 
471         // Assert first request cancelled
472         listener.assertOnCancelCalled();
473 
474         // Assert request
475         assertBasicRequestInfo(request2, mActivity, usernameId, expectedFocusedValue);
476         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
477 
478         // ...and autofill this time
479         mActivity.expectAutoFill("dude", "sweet");
480         ui.click();
481         mActivity.assertAutoFilled();
482         mAugmentedUiBot.assertUiGone();
483     }
484 
485     @Test
486     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
487     public void testAugmentedAutoFill_multipleRequests() throws Exception {
488         // Set services
489         enableService();
490         enableAugmentedService();
491 
492         // Set expectations
493         final EditText username = mActivity.getUsername();
494         final AutofillId usernameId = username.getAutofillId();
495         final AutofillValue usernameValue = username.getAutofillValue();
496         sReplier.addResponse(NO_RESPONSE);
497         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
498                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("req1")
499                         .build(), usernameId)
500                 .build());
501 
502         // Trigger autofill
503         mActivity.onUsername(View::requestFocus);
504         sReplier.getNextFillRequest();
505         final AugmentedFillRequest request1 = sAugmentedReplier.getNextFillRequest();
506 
507         // Assert request
508         assertBasicRequestInfo(request1, mActivity, usernameId, usernameValue);
509 
510         // Make sure standard Autofill UI is not shown.
511         mUiBot.assertNoDatasetsEver();
512 
513         // Make sure Augmented Autofill UI is shown.
514         mAugmentedUiBot.assertUiShown(usernameId, "req1");
515 
516         // Move focus away to make sure Augmented Autofill UI is gone.
517         mActivity.onLogin(View::requestFocus);
518         mAugmentedUiBot.assertUiGone();
519 
520         // Tap on password field
521         final EditText password = mActivity.getPassword();
522         final AutofillId passwordId = password.getAutofillId();
523         final AutofillValue passwordValue = password.getAutofillValue();
524         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
525                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("req2")
526                         .build(), passwordId)
527                 .build());
528         mActivity.onPassword(View::requestFocus);
529         mUiBot.assertNoDatasetsEver();
530         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
531         assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
532 
533         mAugmentedUiBot.assertUiShown(passwordId, "req2");
534 
535         // Tap on username again...
536         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
537                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
538                         .setField(usernameId, "dude")
539                         .setField(passwordId, "sweet")
540                         .build(), usernameId)
541                 .build());
542 
543         mActivity.onUsername(View::requestFocus);
544         final AugmentedFillRequest request3 = sAugmentedReplier.getNextFillRequest();
545         assertBasicRequestInfo(request3, mActivity, usernameId, usernameValue);
546         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
547 
548         // ...and autofill this time
549         mActivity.expectAutoFill("dude", "sweet");
550         ui.click();
551         mActivity.assertAutoFilled();
552         mAugmentedUiBot.assertUiGone();
553     }
554 
555     @Test
556     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
557     public void testAugmentedAutoFill_thenEditField() throws Exception {
558         // Set services
559         enableService();
560         enableAugmentedService();
561 
562         // Set expectations
563         final EditText username = mActivity.getUsername();
564         final AutofillId usernameId = username.getAutofillId();
565         final AutofillValue expectedFocusedValue = username.getAutofillValue();
566         sReplier.addResponse(NO_RESPONSE);
567         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
568                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
569                         .setField(usernameId, "dude")
570                         .build(), usernameId)
571                 .build());
572         mActivity.expectAutoFill("dude");
573 
574         // Trigger autofill
575         mActivity.onUsername(View::requestFocus);
576         sReplier.getNextFillRequest();
577         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
578 
579         // Assert request
580         assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
581 
582         // Make sure standard Autofill UI is not shown.
583         mUiBot.assertNoDatasetsEver();
584 
585         // Make sure Augmented Autofill UI is shown.
586         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
587 
588         // Autofill
589         ui.click();
590         mActivity.assertAutoFilled();
591         mAugmentedUiBot.assertUiGone();
592         assertViewAutofillState(mActivity.getUsername(), true);
593 
594         // Now change value and make sure autofill status is changed
595         mActivity.onUsername((v) -> v.setText("I AM GROOT"));
596         assertViewAutofillState(mActivity.getUsername(), false);
597     }
598 
599     @Test
600     public void testAugmentedAutoFill_callback() throws Exception {
601         // Set services
602         enableService();
603         enableAugmentedService();
604 
605         // Set expectations
606         final MyAutofillCallback callback = mActivity.registerCallback();
607         final EditText username = mActivity.getUsername();
608         final AutofillId usernameId = username.getAutofillId();
609         final AutofillValue usernameValue = username.getAutofillValue();
610         sReplier.addResponse(NO_RESPONSE);
611         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
612                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("req1")
613                         .build(), usernameId)
614                 .build());
615 
616         // Trigger autofill
617         mActivity.onUsername(View::requestFocus);
618         sReplier.getNextFillRequest();
619         final AugmentedFillRequest request1 = sAugmentedReplier.getNextFillRequest();
620 
621         // Assert request
622         assertBasicRequestInfo(request1, mActivity, usernameId, usernameValue);
623 
624         // Make sure standard Autofill UI is not shown.
625         mUiBot.assertNoDatasetsEver();
626 
627         // Make sure Augmented Autofill UI is shown.
628         callback.assertUiShownEvent(username);
629         mAugmentedUiBot.assertUiShown(usernameId, "req1");
630 
631         // Move focus away to make sure Augmented Autofill UI is gone.
632         mActivity.onLogin(View::requestFocus);
633         mAugmentedUiBot.assertUiGone();
634         callback.assertUiHiddenEvent(username);
635 
636         // Tap on password field
637         final EditText password = mActivity.getPassword();
638         final AutofillId passwordId = password.getAutofillId();
639         final AutofillValue passwordValue = password.getAutofillValue();
640         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
641                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("req2")
642                         .build(), passwordId)
643                 .build());
644         mActivity.onPassword(View::requestFocus);
645         mUiBot.assertNoDatasetsEver();
646         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
647         assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
648 
649         callback.assertUiShownEvent(password);
650         mAugmentedUiBot.assertUiShown(passwordId, "req2");
651 
652         // Tap on username again...
653         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
654                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
655                         .setField(usernameId, "dude")
656                         .setField(passwordId, "sweet")
657                         .build(), usernameId)
658                 .build());
659 
660         mActivity.onUsername(View::requestFocus);
661         final AugmentedFillRequest request3 = sAugmentedReplier.getNextFillRequest();
662         assertBasicRequestInfo(request3, mActivity, usernameId, usernameValue);
663         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
664 
665         // ...and autofill this time
666         mActivity.expectAutoFill("dude", "sweet");
667         ui.click();
668         mActivity.assertAutoFilled();
669         mAugmentedUiBot.assertUiGone();
670         callback.assertUiHiddenEvent(password);
671     }
672 
673     @Test
674     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
675     public void testAugmentedAutoFill_rotateDevice() throws Exception {
676         assumeTrue("Rotation is supported", Helper.isRotationSupported(mContext));
677 
678         // Set services
679         enableService();
680         enableAugmentedService();
681 
682         // Set expectations
683         final EditText username = mActivity.getUsername();
684         final AutofillId usernameId = username.getAutofillId();
685         final AutofillValue usernameValue = username.getAutofillValue();
686         sReplier.addResponse(NO_RESPONSE);
687         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
688                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 1")
689                         .setField(usernameId, "dude1")
690                         .build(), usernameId)
691                 .build());
692 
693         // Trigger autofill
694         mActivity.onUsername(View::requestFocus);
695         sReplier.getNextFillRequest();
696         final AugmentedFillRequest request1 = sAugmentedReplier.getNextFillRequest();
697 
698         AugmentedLoginActivity currentActivity = mActivity;
699 
700         // Assert request
701         assertBasicRequestInfo(request1, currentActivity, usernameId, usernameValue);
702 
703         // Make sure standard Autofill UI is not shown.
704         mUiBot.assertNoDatasetsEver();
705 
706         // Make sure Augmented Autofill UI is shown.
707         mAugmentedUiBot.assertUiShown(usernameId, "Augment Me 1");
708 
709         // 1st landscape rotation
710         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
711                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 2")
712                         .setField(usernameId, "dude2")
713                         .build(), usernameId)
714                 .build());
715         mUiBot.setScreenOrientation(LANDSCAPE);
716         mUiBot.assertNoDatasetsEver();
717 
718         // Must update currentActivity after each rotation because it generates a new instance
719         currentActivity = LoginActivity.getCurrentActivity();
720 
721         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
722         assertBasicRequestInfo(request2, currentActivity, usernameId, usernameValue);
723         mAugmentedUiBot.assertUiShown(usernameId, "Augment Me 2");
724 
725         // Rotate back
726         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
727                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 3")
728                         .setField(usernameId, "dude3")
729                         .build(), usernameId)
730                 .build());
731         mUiBot.setScreenOrientation(PORTRAIT);
732         mUiBot.assertNoDatasetsEver();
733         currentActivity = LoginActivity.getCurrentActivity();
734 
735         final AugmentedFillRequest request3 = sAugmentedReplier.getNextFillRequest();
736         assertBasicRequestInfo(request3, currentActivity, usernameId, usernameValue);
737         mAugmentedUiBot.assertUiShown(usernameId, "Augment Me 3");
738 
739         // 2nd landscape rotation
740         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
741                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 4")
742                         .setField(usernameId, "dude4")
743                         .build(), usernameId)
744                 .build());
745         mUiBot.setScreenOrientation(LANDSCAPE);
746         mUiBot.assertNoDatasetsEver();
747         currentActivity = LoginActivity.getCurrentActivity();
748 
749         final AugmentedFillRequest request4 = sAugmentedReplier.getNextFillRequest();
750         assertBasicRequestInfo(request4, currentActivity, usernameId, usernameValue);
751         mAugmentedUiBot.assertUiShown(usernameId, "Augment Me 4");
752 
753         // Final rotation - should be enough....
754         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
755                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 5")
756                         .setField(usernameId, "dude5")
757                         .build(), usernameId)
758                 .build());
759         mUiBot.setScreenOrientation(PORTRAIT);
760         mUiBot.assertNoDatasetsEver();
761         currentActivity = LoginActivity.getCurrentActivity();
762 
763         final AugmentedFillRequest request5 = sAugmentedReplier.getNextFillRequest();
764         assertBasicRequestInfo(request5, mActivity, usernameId, usernameValue);
765         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me 5");
766 
767         // ..then autofill
768 
769         // Must get the latest activity because each rotation creates a new object.
770         currentActivity.expectAutoFill("dude5");
771         ui.click();
772         mAugmentedUiBot.assertUiGone();
773         currentActivity.assertAutoFilled();
774     }
775 
776     @Test
777     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
778     public void testAugmentedAutoFill_mainServiceDisabled() throws Exception {
779         // Set services
780         Helper.disableAutofillService(sContext);
781         enableAugmentedService();
782 
783         // Set expectations
784         final EditText username = mActivity.getUsername();
785         final AutofillId usernameId = username.getAutofillId();
786         final AutofillValue usernameValue = username.getAutofillValue();
787         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
788                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
789                         .setField(usernameId, "dude")
790                         .build(), usernameId)
791                 .build());
792         mActivity.expectAutoFill("dude");
793 
794         // Trigger autofill
795         mActivity.onUsername(View::requestFocus);
796         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
797 
798         // Assert request
799         assertBasicRequestInfo(request, mActivity, usernameId, usernameValue);
800 
801         // Make sure standard Autofill UI is not shown.
802         mUiBot.assertNoDatasetsEver();
803 
804         // Make sure Augmented Autofill UI is shown.
805         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
806 
807         // Autofill
808         ui.click();
809         mActivity.assertAutoFilled();
810         mAugmentedUiBot.assertUiGone();
811     }
812 
813     @Test
814     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
815     public void testAugmentedAutoFill_mainServiceDisabled_manualRequest() throws Exception {
816         // Set services
817         Helper.disableAutofillService(sContext);
818         enableAugmentedService();
819 
820         // Set expectations
821         final EditText username = mActivity.getUsername();
822         final AutofillId usernameId = username.getAutofillId();
823         final AutofillValue usernameValue = username.getAutofillValue();
824         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
825                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
826                         .setField(usernameId, "dude")
827                         .build(), usernameId)
828                 .build());
829         mActivity.expectAutoFill("dude");
830 
831         // Trigger autofill
832         mActivity.forceAutofillOnUsername();
833         final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
834 
835         // Assert request
836         assertBasicRequestInfo(request, mActivity, usernameId, usernameValue);
837 
838         // Make sure standard Autofill UI is not shown.
839         mUiBot.assertNoDatasetsEver();
840 
841         // Make sure Augmented Autofill UI is shown.
842         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
843 
844         // Autofill
845         ui.click();
846         mActivity.assertAutoFilled();
847         mAugmentedUiBot.assertUiGone();
848     }
849 
850     @Test
851     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
852     public void testAugmentedAutoFill_mainServiceDisabled_autoThenManualRequest() throws Exception {
853         // Set services
854         Helper.disableAutofillService(sContext);
855         enableAugmentedService();
856 
857         // Set expectations
858         final EditText username = mActivity.getUsername();
859         final AutofillId usernameId = username.getAutofillId();
860         final AutofillValue usernameValue = username.getAutofillValue();
861         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
862 
863         // Trigger autofill
864         mActivity.onUsername(View::requestFocus);
865         final AugmentedFillRequest request1 = sAugmentedReplier.getNextFillRequest();
866         assertBasicRequestInfo(request1, mActivity, usernameId, usernameValue);
867 
868         // Make sure standard no UI is not shown.
869         mUiBot.assertNoDatasetsEver();
870         mAugmentedUiBot.assertUiNeverShown();
871 
872 
873         // Trigger 2nd request, manually
874         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
875                 .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
876                         .setField(usernameId, "dude")
877                         .build(), usernameId)
878                 .build());
879         mActivity.expectAutoFill("dude");
880         mActivity.forceAutofillOnUsername();
881         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
882         assertBasicRequestInfo(request2, mActivity, usernameId, usernameValue);
883 
884         // Make sure standard Autofill UI is not shown.
885         mUiBot.assertNoDatasetsEver();
886 
887         // Make sure Augmented Autofill UI is shown.
888         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
889 
890         // Autofill
891         ui.click();
892         mActivity.assertAutoFilled();
893         mAugmentedUiBot.assertUiGone();
894     }
895 
896     @Test
897     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
898     public void testAugmentedAutoFill_mainServiceDisabled_valueChangedOnSecondRequest()
899             throws Exception {
900         // Set services
901         Helper.disableAutofillService(sContext);
902         enableAugmentedService();
903 
904         // Set expectations
905         final EditText username = mActivity.getUsername();
906         final AutofillId usernameId = username.getAutofillId();
907         final AutofillValue initialValue = username.getAutofillValue();
908         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
909 
910         // Trigger autofill
911         mActivity.onUsername(View::requestFocus);
912         final AugmentedFillRequest request1 = sAugmentedReplier.getNextFillRequest();
913 
914         // Assert request
915         assertBasicRequestInfo(request1, mActivity, usernameId, initialValue);
916 
917         // Make sure UIs were not shown
918         mUiBot.assertNoDatasetsEver();
919         mAugmentedUiBot.assertUiNeverShown();
920 
921         // Change field value
922         mActivity.onUsername((v) -> v.setText("DOH"));
923 
924         // Trigger autofill again
925         sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
926         mActivity.onUsername(View::performClick);
927         final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
928 
929         // Assert 2nd request
930         assertBasicRequestInfo(request2, mActivity, usernameId, "DOH");
931 
932         // Make sure UIs were not shown
933         mUiBot.assertNoDatasetsEver();
934         mAugmentedUiBot.assertUiNeverShown();
935     }
936 
937     @Test
938     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
939     public void testSetAugmentedAutofillWhitelist_noStandardServiceSet() throws Exception {
940         final AutofillManager mgr = mActivity.getAutofillManager();
941         assertThrows(SecurityException.class,
942                 () -> mgr.setAugmentedAutofillWhitelist((Set<String>) null,
943                         (Set<ComponentName>) null));
944     }
945 
946     @Test
947     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
948     public void testSetAugmentedAutofillWhitelist_notAugmentedService() throws Exception {
949         enableService();
950         final AutofillManager mgr = mActivity.getAutofillManager();
951         assertThrows(SecurityException.class,
952                 () -> mgr.setAugmentedAutofillWhitelist((Set<String>) null,
953                         (Set<ComponentName>) null));
954     }
955 
956     @Test
957     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
958     public void testAugmentedAutofill_packageNotWhitelisted() throws Exception {
959         // Set services
960         enableService();
961         enableAugmentedService();
962 
963         final AutofillManager mgr = mActivity.getAutofillManager();
964         mgr.setAugmentedAutofillWhitelist((Set) null, (Set) null);
965 
966         // Set expectations
967         sReplier.addResponse(NO_RESPONSE);
968 
969         // Trigger autofill
970         mActivity.onUsername(View::requestFocus);
971         sReplier.getNextFillRequest();
972 
973         // Assert no fill requests
974         sAugmentedReplier.assertNoUnhandledFillRequests();
975 
976         // Make sure standard Autofill UI is not shown.
977         mUiBot.assertNoDatasetsEver();
978 
979         // Make sure Augmented Autofill UI is not shown.
980         mAugmentedUiBot.assertUiNeverShown();
981     }
982 
983     @Test
984     @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
985     public void testAugmentedAutofill_activityNotWhitelisted() throws Exception {
986         // Set services
987         enableService();
988         enableAugmentedService();
989 
990         final AutofillManager mgr = mActivity.getAutofillManager();
991         final ArraySet<ComponentName> components = new ArraySet<>();
992         components.add(new ComponentName(Helper.MY_PACKAGE, "some.activity"));
993         mgr.setAugmentedAutofillWhitelist(null, components);
994 
995         // Set expectations
996         sReplier.addResponse(NO_RESPONSE);
997 
998         // Trigger autofill
999         mActivity.onUsername(View::requestFocus);
1000         sReplier.getNextFillRequest();
1001 
1002         // Assert no fill requests
1003         sAugmentedReplier.assertNoUnhandledFillRequests();
1004 
1005         // Make sure standard Autofill UI is not shown.
1006         mUiBot.assertNoDatasetsEver();
1007 
1008         // Make sure Augmented Autofill UI is not shown.
1009         mAugmentedUiBot.assertUiNeverShown();
1010     }
1011 
1012     /*
1013      * TODO(b/123542344) - add moarrrr tests:
1014      *
1015      * - Augmented service returned null
1016      * - Focus back and forth between username and passwod
1017      *   - When Augmented service shows UI on one field (like username) but not other.
1018      *   - When Augmented service shows UI on one field (like username) on both.
1019      * - Tap back
1020      * - Tap home (then bring activity back)
1021      * - Acitivy is killed (and restored)
1022      * - Main service returns non-null response that doesn't show UI (for example, has just
1023      *   SaveInfo)
1024      *   - Augmented autofill show UI, user fills, Save UI is shown
1025      *   - etc ...
1026      * - No augmented autofill calls when the main service is not set.
1027      * - etc...
1028      */
1029 }
1030