Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2017 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 package android.autofillservice.cts;
     17 
     18 import static android.autofillservice.cts.GridActivity.ID_L1C1;
     19 import static android.autofillservice.cts.GridActivity.ID_L1C2;
     20 import static android.autofillservice.cts.GridActivity.ID_L2C1;
     21 import static android.autofillservice.cts.GridActivity.ID_L2C2;
     22 import static android.autofillservice.cts.GridActivity.ID_L3C1;
     23 import static android.autofillservice.cts.GridActivity.ID_L3C2;
     24 import static android.autofillservice.cts.GridActivity.ID_L4C1;
     25 import static android.autofillservice.cts.GridActivity.ID_L4C2;
     26 import static android.autofillservice.cts.Helper.assertTextIsSanitized;
     27 import static android.autofillservice.cts.Helper.assertValue;
     28 import static android.autofillservice.cts.Helper.getMaxPartitions;
     29 import static android.autofillservice.cts.Helper.setMaxPartitions;
     30 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
     31 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_ADDRESS;
     32 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD;
     33 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_GENERIC;
     34 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
     35 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_USERNAME;
     36 
     37 import static com.google.common.truth.Truth.assertThat;
     38 import static com.google.common.truth.Truth.assertWithMessage;
     39 
     40 import android.app.assist.AssistStructure.ViewNode;
     41 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
     42 import android.autofillservice.cts.GridActivity.FillExpectation;
     43 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
     44 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
     45 import android.content.IntentSender;
     46 import android.os.Bundle;
     47 import android.service.autofill.FillResponse;
     48 import android.support.test.rule.ActivityTestRule;
     49 import android.widget.RemoteViews;
     50 
     51 import org.junit.Before;
     52 import org.junit.Rule;
     53 import org.junit.Test;
     54 
     55 /**
     56  * Test case for an activity containing multiple partitions.
     57  */
     58 public class PartitionedActivityTest extends AutoFillServiceTestCase {
     59 
     60     @Rule
     61     public final ActivityTestRule<GridActivity> mActivityRule =
     62         new ActivityTestRule<GridActivity>(GridActivity.class);
     63 
     64     private GridActivity mActivity;
     65 
     66     @Before
     67     public void setActivity() {
     68         mActivity = mActivityRule.getActivity();
     69     }
     70 
     71     @Test
     72     public void testAutofillTwoPartitionsSkipFirst() throws Exception {
     73         // Set service.
     74         enableService();
     75 
     76         // Prepare 1st partition.
     77         final CannedFillResponse response1 = new CannedFillResponse.Builder()
     78                 .addDataset(new CannedDataset.Builder()
     79                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
     80                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
     81                         .build())
     82                 .build();
     83         sReplier.addResponse(response1);
     84 
     85         // Trigger auto-fill on 1st partition.
     86         mActivity.focusCell(1, 1);
     87         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
     88         assertThat(fillRequest1.flags).isEqualTo(0);
     89         final ViewNode p1l1c1 = assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
     90         final ViewNode p1l1c2 = assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
     91         assertWithMessage("Focus on p1l1c1").that(p1l1c1.isFocused()).isTrue();
     92         assertWithMessage("Focus on p1l1c2").that(p1l1c2.isFocused()).isFalse();
     93 
     94         // Make sure UI is shown, but don't tap it.
     95         sUiBot.assertDatasets("l1c1");
     96         mActivity.focusCell(1, 2);
     97         sUiBot.assertDatasets("l1c2");
     98 
     99         // Now tap a field in a different partition
    100         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    101                 .addDataset(new CannedDataset.Builder()
    102                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    103                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    104                         .build())
    105                 .build();
    106         sReplier.addResponse(response2);
    107 
    108         // Trigger auto-fill on 2nd partition.
    109         mActivity.focusCell(2, 1);
    110         final FillRequest fillRequest2 = sReplier.getNextFillRequest();
    111         assertThat(fillRequest2.flags).isEqualTo(0);
    112         final ViewNode p2l1c1 = assertTextIsSanitized(fillRequest2.structure, ID_L1C1);
    113         final ViewNode p2l1c2 = assertTextIsSanitized(fillRequest2.structure, ID_L1C2);
    114         final ViewNode p2l2c1 = assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
    115         final ViewNode p2l2c2 = assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
    116         assertWithMessage("Focus on p2l1c1").that(p2l1c1.isFocused()).isFalse();
    117         assertWithMessage("Focus on p2l1c2").that(p2l1c2.isFocused()).isFalse();
    118         assertWithMessage("Focus on p2l2c1").that(p2l2c1.isFocused()).isTrue();
    119         assertWithMessage("Focus on p2l2c2").that(p2l2c2.isFocused()).isFalse();
    120         // Make sure UI is shown, but don't tap it.
    121         sUiBot.assertDatasets("l2c1");
    122         mActivity.focusCell(2, 2);
    123         sUiBot.assertDatasets("l2c2");
    124 
    125         // Now fill them
    126         final FillExpectation expectation1 = mActivity.expectAutofill()
    127               .onCell(1, 1, "l1c1")
    128               .onCell(1, 2, "l1c2");
    129         mActivity.focusCell(1, 1);
    130         sUiBot.selectDataset("l1c1");
    131         expectation1.assertAutoFilled();
    132 
    133         // Change previous values to make sure they are not filled again
    134         mActivity.setText(1, 1, "L1C1");
    135         mActivity.setText(1, 2, "L1C2");
    136 
    137         final FillExpectation expectation2 = mActivity.expectAutofill()
    138                 .onCell(2, 1, "l2c1")
    139                 .onCell(2, 2, "l2c2");
    140         mActivity.focusCell(2, 2);
    141         sUiBot.selectDataset("l2c2");
    142         expectation2.assertAutoFilled();
    143 
    144         // Make sure previous partition didn't change
    145         assertThat(mActivity.getText(1, 1)).isEqualTo("L1C1");
    146         assertThat(mActivity.getText(1, 2)).isEqualTo("L1C2");
    147     }
    148 
    149     @Test
    150     public void testAutofillTwoPartitionsInSequence() throws Exception {
    151         // Set service.
    152         enableService();
    153 
    154         // 1st partition
    155         // Prepare.
    156         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    157                 .addDataset(new CannedDataset.Builder()
    158                         .setPresentation(createPresentation("Partition 1"))
    159                         .setField(ID_L1C1, "l1c1")
    160                         .setField(ID_L1C2, "l1c2")
    161                         .build())
    162                 .build();
    163         sReplier.addResponse(response1);
    164         final FillExpectation expectation1 = mActivity.expectAutofill()
    165                 .onCell(1, 1, "l1c1")
    166                 .onCell(1, 2, "l1c2");
    167 
    168         // Trigger auto-fill.
    169         mActivity.focusCell(1, 1);
    170         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
    171         assertThat(fillRequest1.flags).isEqualTo(0);
    172 
    173         assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
    174         assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
    175 
    176         // Auto-fill it.
    177         sUiBot.selectDataset("Partition 1");
    178 
    179         // Check the results.
    180         expectation1.assertAutoFilled();
    181 
    182         // 2nd partition
    183         // Prepare.
    184         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    185                 .addDataset(new CannedDataset.Builder()
    186                         .setPresentation(createPresentation("Partition 2"))
    187                         .setField(ID_L2C1, "l2c1")
    188                         .setField(ID_L2C2, "l2c2")
    189                         .build())
    190                 .build();
    191         sReplier.addResponse(response2);
    192         final FillExpectation expectation2 = mActivity.expectAutofill()
    193                 .onCell(2, 1, "l2c1")
    194                 .onCell(2, 2, "l2c2");
    195 
    196         // Trigger auto-fill.
    197         mActivity.focusCell(2, 1);
    198         final FillRequest fillRequest2 = sReplier.getNextFillRequest();
    199         assertThat(fillRequest2.flags).isEqualTo(0);
    200 
    201         assertValue(fillRequest2.structure, ID_L1C1, "l1c1");
    202         assertValue(fillRequest2.structure, ID_L1C2, "l1c2");
    203         assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
    204         assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
    205 
    206         // Auto-fill it.
    207         sUiBot.selectDataset("Partition 2");
    208 
    209         // Check the results.
    210         expectation2.assertAutoFilled();
    211     }
    212 
    213     @Test
    214     public void testAutofill4PartitionsAutomatically() throws Exception {
    215         autofill4PartitionsTest(false);
    216     }
    217 
    218     @Test
    219     public void testAutofill4PartitionsManually() throws Exception {
    220         autofill4PartitionsTest(true);
    221     }
    222 
    223     private void autofill4PartitionsTest(boolean manually) throws Exception {
    224         final int expectedFlag = manually ? FLAG_MANUAL_REQUEST : 0;
    225 
    226         // Set service.
    227         enableService();
    228 
    229         // 1st partition
    230         // Prepare.
    231         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    232                 .addDataset(new CannedDataset.Builder()
    233                         .setPresentation(createPresentation("Partition 1"))
    234                         .setField(ID_L1C1, "l1c1")
    235                         .setField(ID_L1C2, "l1c2")
    236                         .build())
    237                 .build();
    238         sReplier.addResponse(response1);
    239         final FillExpectation expectation1 = mActivity.expectAutofill()
    240                 .onCell(1, 1, "l1c1")
    241                 .onCell(1, 2, "l1c2");
    242 
    243         // Trigger auto-fill.
    244         mActivity.triggerAutofill(manually, 1, 1);
    245         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
    246         assertThat(fillRequest1.flags).isEqualTo(expectedFlag);
    247 
    248         if (manually) {
    249             assertValue(fillRequest1.structure, ID_L1C1, "");
    250         } else {
    251             assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
    252         }
    253         assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
    254 
    255         // Auto-fill it.
    256         sUiBot.selectDataset("Partition 1");
    257 
    258         // Check the results.
    259         expectation1.assertAutoFilled();
    260 
    261         // 2nd partition
    262         // Prepare.
    263         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    264                 .addDataset(new CannedDataset.Builder()
    265                         .setPresentation(createPresentation("Partition 2"))
    266                         .setField(ID_L2C1, "l2c1")
    267                         .setField(ID_L2C2, "l2c2")
    268                         .build())
    269                 .build();
    270         sReplier.addResponse(response2);
    271         final FillExpectation expectation2 = mActivity.expectAutofill()
    272                 .onCell(2, 1, "l2c1")
    273                 .onCell(2, 2, "l2c2");
    274 
    275         // Trigger auto-fill.
    276         mActivity.triggerAutofill(manually, 2, 1);
    277         final FillRequest fillRequest2 = sReplier.getNextFillRequest();
    278         assertThat(fillRequest2.flags).isEqualTo(expectedFlag);
    279 
    280         assertValue(fillRequest2.structure, ID_L1C1, "l1c1");
    281         assertValue(fillRequest2.structure, ID_L1C2, "l1c2");
    282         if (manually) {
    283             assertValue(fillRequest2.structure, ID_L2C1, "");
    284         } else {
    285             assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
    286         }
    287         assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
    288 
    289         // Auto-fill it.
    290         sUiBot.selectDataset("Partition 2");
    291 
    292         // Check the results.
    293         expectation2.assertAutoFilled();
    294 
    295         // 3rd partition
    296         // Prepare.
    297         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    298                 .addDataset(new CannedDataset.Builder()
    299                         .setPresentation(createPresentation("Partition 3"))
    300                         .setField(ID_L3C1, "l3c1")
    301                         .setField(ID_L3C2, "l3c2")
    302                         .build())
    303                 .build();
    304         sReplier.addResponse(response3);
    305         final FillExpectation expectation3 = mActivity.expectAutofill()
    306                 .onCell(3, 1, "l3c1")
    307                 .onCell(3, 2, "l3c2");
    308 
    309         // Trigger auto-fill.
    310         mActivity.triggerAutofill(manually, 3, 1);
    311         final FillRequest fillRequest3 = sReplier.getNextFillRequest();
    312         assertThat(fillRequest3.flags).isEqualTo(expectedFlag);
    313 
    314         assertValue(fillRequest3.structure, ID_L1C1, "l1c1");
    315         assertValue(fillRequest3.structure, ID_L1C2, "l1c2");
    316         assertValue(fillRequest3.structure, ID_L2C1, "l2c1");
    317         assertValue(fillRequest3.structure, ID_L2C2, "l2c2");
    318         if (manually) {
    319             assertValue(fillRequest3.structure, ID_L3C1, "");
    320         } else {
    321             assertTextIsSanitized(fillRequest3.structure, ID_L3C1);
    322         }
    323         assertTextIsSanitized(fillRequest3.structure, ID_L3C2);
    324 
    325         // Auto-fill it.
    326         sUiBot.selectDataset("Partition 3");
    327 
    328         // Check the results.
    329         expectation3.assertAutoFilled();
    330 
    331         // 4th partition
    332         // Prepare.
    333         final CannedFillResponse response4 = new CannedFillResponse.Builder()
    334                 .addDataset(new CannedDataset.Builder()
    335                         .setPresentation(createPresentation("Partition 4"))
    336                         .setField(ID_L4C1, "l4c1")
    337                         .setField(ID_L4C2, "l4c2")
    338                         .build())
    339                 .build();
    340         sReplier.addResponse(response4);
    341         final FillExpectation expectation4 = mActivity.expectAutofill()
    342                 .onCell(4, 1, "l4c1")
    343                 .onCell(4, 2, "l4c2");
    344 
    345         // Trigger auto-fill.
    346         mActivity.triggerAutofill(manually, 4, 1);
    347         final FillRequest fillRequest4 = sReplier.getNextFillRequest();
    348         assertThat(fillRequest4.flags).isEqualTo(expectedFlag);
    349 
    350         assertValue(fillRequest4.structure, ID_L1C1, "l1c1");
    351         assertValue(fillRequest4.structure, ID_L1C2, "l1c2");
    352         assertValue(fillRequest4.structure, ID_L2C1, "l2c1");
    353         assertValue(fillRequest4.structure, ID_L2C2, "l2c2");
    354         assertValue(fillRequest4.structure, ID_L3C1, "l3c1");
    355         assertValue(fillRequest4.structure, ID_L3C2, "l3c2");
    356         if (manually) {
    357             assertValue(fillRequest4.structure, ID_L4C1, "");
    358         } else {
    359             assertTextIsSanitized(fillRequest4.structure, ID_L4C1);
    360         }
    361         assertTextIsSanitized(fillRequest4.structure, ID_L4C2);
    362 
    363         // Auto-fill it.
    364         sUiBot.selectDataset("Partition 4");
    365 
    366         // Check the results.
    367         expectation4.assertAutoFilled();
    368     }
    369 
    370     @Test
    371     public void testAutofill4PartitionsMixManualAndAuto() throws Exception {
    372         // Set service.
    373         enableService();
    374 
    375         // 1st partition - auto
    376         // Prepare.
    377         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    378                 .addDataset(new CannedDataset.Builder()
    379                         .setPresentation(createPresentation("Partition 1"))
    380                         .setField(ID_L1C1, "l1c1")
    381                         .setField(ID_L1C2, "l1c2")
    382                         .build())
    383                 .build();
    384         sReplier.addResponse(response1);
    385         final FillExpectation expectation1 = mActivity.expectAutofill()
    386                 .onCell(1, 1, "l1c1")
    387                 .onCell(1, 2, "l1c2");
    388 
    389         // Trigger auto-fill.
    390         mActivity.focusCell(1, 1);
    391         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
    392         assertThat(fillRequest1.flags).isEqualTo(0);
    393 
    394         assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
    395         assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
    396 
    397         // Auto-fill it.
    398         sUiBot.selectDataset("Partition 1");
    399 
    400         // Check the results.
    401         expectation1.assertAutoFilled();
    402 
    403         // 2nd partition - manual
    404         // Prepare
    405         // Must set text before creating expectation, and it must be a subset of the dataset values,
    406         // otherwise the UI won't be shown because of filtering
    407         mActivity.setText(2, 1, "l2");
    408         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    409                 .addDataset(new CannedDataset.Builder()
    410                         .setPresentation(createPresentation("Partition 2"))
    411                         .setField(ID_L2C1, "l2c1")
    412                         .setField(ID_L2C2, "l2c2")
    413                         .build())
    414                 .build();
    415         sReplier.addResponse(response2);
    416         final FillExpectation expectation2 = mActivity.expectAutofill()
    417                 .onCell(2, 1, "l2c1")
    418                 .onCell(2, 2, "l2c2");
    419 
    420         // Trigger auto-fill.
    421         mActivity.forceAutofill(2, 1);
    422         final FillRequest fillRequest2 = sReplier.getNextFillRequest();
    423         assertThat(fillRequest2.flags).isEqualTo(FLAG_MANUAL_REQUEST);
    424 
    425         assertValue(fillRequest2.structure, ID_L1C1, "l1c1");
    426         assertValue(fillRequest2.structure, ID_L1C2, "l1c2");
    427         assertValue(fillRequest2.structure, ID_L2C1, "l2");
    428         assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
    429 
    430         // Auto-fill it.
    431         sUiBot.selectDataset("Partition 2");
    432 
    433         // Check the results.
    434         expectation2.assertAutoFilled();
    435 
    436         // 3rd partition - auto
    437         // Prepare.
    438         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    439                 .addDataset(new CannedDataset.Builder()
    440                         .setPresentation(createPresentation("Partition 3"))
    441                         .setField(ID_L3C1, "l3c1")
    442                         .setField(ID_L3C2, "l3c2")
    443                         .build())
    444                 .build();
    445         sReplier.addResponse(response3);
    446         final FillExpectation expectation3 = mActivity.expectAutofill()
    447                 .onCell(3, 1, "l3c1")
    448                 .onCell(3, 2, "l3c2");
    449 
    450         // Trigger auto-fill.
    451         mActivity.focusCell(3, 1);
    452         final FillRequest fillRequest3 = sReplier.getNextFillRequest();
    453         assertThat(fillRequest3.flags).isEqualTo(0);
    454 
    455         assertValue(fillRequest3.structure, ID_L1C1, "l1c1");
    456         assertValue(fillRequest3.structure, ID_L1C2, "l1c2");
    457         assertValue(fillRequest3.structure, ID_L2C1, "l2c1");
    458         assertValue(fillRequest3.structure, ID_L2C2, "l2c2");
    459         assertTextIsSanitized(fillRequest3.structure, ID_L3C1);
    460         assertTextIsSanitized(fillRequest3.structure, ID_L3C2);
    461 
    462         // Auto-fill it.
    463         sUiBot.selectDataset("Partition 3");
    464 
    465         // Check the results.
    466         expectation3.assertAutoFilled();
    467 
    468         // 4th partition - manual
    469         // Must set text before creating expectation, and it must be a subset of the dataset values,
    470         // otherwise the UI won't be shown because of filtering
    471         mActivity.setText(4, 1, "l4");
    472         final CannedFillResponse response4 = new CannedFillResponse.Builder()
    473                 .addDataset(new CannedDataset.Builder()
    474                         .setPresentation(createPresentation("Partition 4"))
    475                         .setField(ID_L4C1, "l4c1")
    476                         .setField(ID_L4C2, "l4c2")
    477                         .build())
    478                 .build();
    479         sReplier.addResponse(response4);
    480         final FillExpectation expectation4 = mActivity.expectAutofill()
    481                 .onCell(4, 1, "l4c1")
    482                 .onCell(4, 2, "l4c2");
    483 
    484         // Trigger auto-fill.
    485         mActivity.forceAutofill(4, 1);
    486         final FillRequest fillRequest4 = sReplier.getNextFillRequest();
    487         assertThat(fillRequest4.flags).isEqualTo(FLAG_MANUAL_REQUEST);
    488 
    489         assertValue(fillRequest4.structure, ID_L1C1, "l1c1");
    490         assertValue(fillRequest4.structure, ID_L1C2, "l1c2");
    491         assertValue(fillRequest4.structure, ID_L2C1, "l2c1");
    492         assertValue(fillRequest4.structure, ID_L2C2, "l2c2");
    493         assertValue(fillRequest4.structure, ID_L3C1, "l3c1");
    494         assertValue(fillRequest4.structure, ID_L3C2, "l3c2");
    495         assertValue(fillRequest4.structure, ID_L4C1, "l4");
    496         assertTextIsSanitized(fillRequest4.structure, ID_L4C2);
    497 
    498         // Auto-fill it.
    499         sUiBot.selectDataset("Partition 4");
    500 
    501         // Check the results.
    502         expectation4.assertAutoFilled();
    503     }
    504 
    505     @Test
    506     public void testAutofillBundleDataIsPassedAlong() throws Exception {
    507         // Set service.
    508         enableService();
    509 
    510         final Bundle extras = new Bundle();
    511         extras.putString("numbers", "4");
    512 
    513         // Prepare 1st partition.
    514         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    515                 .addDataset(new CannedDataset.Builder()
    516                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    517                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    518                         .build())
    519                 .setExtras(extras)
    520                 .build();
    521         sReplier.addResponse(response1);
    522 
    523         // Trigger auto-fill on 1st partition.
    524         mActivity.focusCell(1, 1);
    525         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
    526         assertThat(fillRequest1.flags).isEqualTo(0);
    527         assertThat(fillRequest1.data).isNull();
    528         sUiBot.assertDatasets("l1c1");
    529 
    530         // Prepare 2nd partition; it replaces 'number' and adds 'numbers2'
    531         extras.clear();
    532         extras.putString("numbers", "48");
    533         extras.putString("numbers2", "1516");
    534 
    535         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    536                 .addDataset(new CannedDataset.Builder()
    537                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    538                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    539                         .build())
    540                 .setExtras(extras)
    541                 .build();
    542         sReplier.addResponse(response2);
    543 
    544         // Trigger auto-fill on 2nd partition
    545         mActivity.focusCell(2, 1);
    546         final FillRequest fillRequest2 = sReplier.getNextFillRequest();
    547         assertThat(fillRequest2.flags).isEqualTo(0);
    548         assertWithMessage("null bundle on request 2").that(fillRequest2.data).isNotNull();
    549         assertWithMessage("wrong number of extras on request 2 bundle")
    550                 .that(fillRequest2.data.size()).isEqualTo(1);
    551         assertThat(fillRequest2.data.getString("numbers")).isEqualTo("4");
    552 
    553         // Prepare 3nd partition; it has no extras
    554         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    555                 .addDataset(new CannedDataset.Builder()
    556                         .setField(ID_L3C1, "l3c1", createPresentation("l3c1"))
    557                         .setField(ID_L3C2, "l3c2", createPresentation("l3c2"))
    558                         .build())
    559                 .setExtras(null)
    560                 .build();
    561         sReplier.addResponse(response3);
    562 
    563         // Trigger auto-fill on 3rd partition
    564         mActivity.focusCell(3, 1);
    565         final FillRequest fillRequest3 = sReplier.getNextFillRequest();
    566         assertThat(fillRequest3.flags).isEqualTo(0);
    567         assertWithMessage("null bundle on request 3").that(fillRequest2.data).isNotNull();
    568         assertWithMessage("wrong number of extras on request 3 bundle")
    569                 .that(fillRequest3.data.size()).isEqualTo(2);
    570         assertThat(fillRequest3.data.getString("numbers")).isEqualTo("48");
    571         assertThat(fillRequest3.data.getString("numbers2")).isEqualTo("1516");
    572 
    573 
    574         // Prepare 4th partition; it contains just 'numbers4'
    575         extras.clear();
    576         extras.putString("numbers4", "2342");
    577 
    578         final CannedFillResponse response4 = new CannedFillResponse.Builder()
    579                 .addDataset(new CannedDataset.Builder()
    580                         .setField(ID_L4C1, "l4c1", createPresentation("l4c1"))
    581                         .setField(ID_L4C2, "l4c2", createPresentation("l4c2"))
    582                         .build())
    583                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    584                 .setExtras(extras)
    585                 .build();
    586         sReplier.addResponse(response4);
    587 
    588         // Trigger auto-fill on 4th partition
    589         mActivity.focusCell(4, 1);
    590         final FillRequest fillRequest4 = sReplier.getNextFillRequest();
    591         assertThat(fillRequest4.flags).isEqualTo(0);
    592         assertWithMessage("non-null bundle on request 4").that(fillRequest4.data).isNull();
    593 
    594         // Trigger save
    595         mActivity.setText(1, 1, "L1C1");
    596         mActivity.save();
    597 
    598         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
    599         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    600 
    601         assertWithMessage("wrong number of extras on save request bundle")
    602                 .that(saveRequest.data.size()).isEqualTo(1);
    603         assertThat(saveRequest.data.getString("numbers4")).isEqualTo("2342");
    604     }
    605 
    606     @Test
    607     public void testSaveOneSaveInfoOnFirstPartitionWithIdsOnSecond() throws Exception {
    608         // Set service.
    609         enableService();
    610 
    611         // Trigger 1st partition.
    612         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    613                 .addDataset(new CannedDataset.Builder()
    614                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    615                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    616                         .build())
    617                 .build();
    618         sReplier.addResponse(response1);
    619         mActivity.focusCell(1, 1);
    620         sReplier.getNextFillRequest();
    621 
    622         // Trigger 2nd partition.
    623         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    624                 .addDataset(new CannedDataset.Builder()
    625                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    626                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    627                         .build())
    628                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L2C1)
    629                 .build();
    630         sReplier.addResponse(response2);
    631         mActivity.focusCell(2, 1);
    632         sReplier.getNextFillRequest();
    633 
    634         // Trigger save
    635         mActivity.setText(2, 1, "L2C1");
    636         mActivity.save();
    637 
    638         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
    639         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    640         assertValue(saveRequest.structure, ID_L2C1, "L2C1");
    641     }
    642 
    643     @Test
    644     public void testSaveOneSaveInfoOnSecondPartitionWithIdsOnFirst() throws Exception {
    645         // Set service.
    646         enableService();
    647 
    648         // Trigger 1st partition.
    649         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    650                 .addDataset(new CannedDataset.Builder()
    651                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    652                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    653                         .build())
    654                 .build();
    655         sReplier.addResponse(response1);
    656         mActivity.focusCell(1, 1);
    657         sReplier.getNextFillRequest();
    658 
    659         // Trigger 2nd partition.
    660         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    661                 .addDataset(new CannedDataset.Builder()
    662                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    663                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    664                         .build())
    665                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    666                 .build();
    667         sReplier.addResponse(response2);
    668         mActivity.focusCell(2, 1);
    669         sReplier.getNextFillRequest();
    670 
    671         // Trigger save
    672         mActivity.setText(1, 1, "L1C1");
    673         mActivity.save();
    674 
    675         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
    676         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    677         assertValue(saveRequest.structure, ID_L1C1, "L1C1");
    678     }
    679 
    680     @Test
    681     public void testSaveTwoSaveInfosDifferentTypes() throws Exception {
    682         // Set service.
    683         enableService();
    684 
    685         // Trigger 1st partition.
    686         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    687                 .addDataset(new CannedDataset.Builder()
    688                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    689                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    690                         .build())
    691                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    692                 .build();
    693         sReplier.addResponse(response1);
    694         mActivity.focusCell(1, 1);
    695         sReplier.getNextFillRequest();
    696 
    697         // Trigger 2nd partition.
    698         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    699                 .addDataset(new CannedDataset.Builder()
    700                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    701                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    702                         .build())
    703                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD,
    704                         ID_L2C1)
    705                 .build();
    706         sReplier.addResponse(response2);
    707         mActivity.focusCell(2, 1);
    708         sReplier.getNextFillRequest();
    709 
    710         // Trigger save
    711         mActivity.setText(1, 1, "L1C1");
    712         mActivity.setText(2, 1, "L2C1");
    713         mActivity.save();
    714 
    715         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD, SAVE_DATA_TYPE_CREDIT_CARD);
    716         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    717         assertValue(saveRequest.structure, ID_L1C1, "L1C1");
    718         assertValue(saveRequest.structure, ID_L2C1, "L2C1");
    719     }
    720 
    721     @Test
    722     public void testSaveThreeSaveInfosDifferentTypes() throws Exception {
    723         // Set service.
    724         enableService();
    725 
    726         // Trigger 1st partition.
    727         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    728                 .addDataset(new CannedDataset.Builder()
    729                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    730                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    731                         .build())
    732                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    733                 .build();
    734         sReplier.addResponse(response1);
    735         mActivity.focusCell(1, 1);
    736         sReplier.getNextFillRequest();
    737 
    738         // Trigger 2nd partition.
    739         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    740                 .addDataset(new CannedDataset.Builder()
    741                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    742                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    743                         .build())
    744                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD,
    745                         ID_L2C1)
    746                 .build();
    747         sReplier.addResponse(response2);
    748         mActivity.focusCell(2, 1);
    749         sReplier.getNextFillRequest();
    750 
    751         // Trigger 3rd partition.
    752         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    753                 .addDataset(new CannedDataset.Builder()
    754                         .setField(ID_L3C1, "l3c1", createPresentation("l3c1"))
    755                         .setField(ID_L3C2, "l3c2", createPresentation("l3c2"))
    756                         .build())
    757                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD
    758                         | SAVE_DATA_TYPE_USERNAME, ID_L3C1)
    759                 .build();
    760         sReplier.addResponse(response3);
    761         mActivity.focusCell(3, 1);
    762         sReplier.getNextFillRequest();
    763 
    764         // Trigger save
    765         mActivity.setText(1, 1, "L1C1");
    766         mActivity.setText(2, 1, "L2C1");
    767         mActivity.setText(3, 1, "L3C1");
    768         mActivity.save();
    769 
    770         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD, SAVE_DATA_TYPE_CREDIT_CARD,
    771                 SAVE_DATA_TYPE_USERNAME);
    772         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    773         assertValue(saveRequest.structure, ID_L1C1, "L1C1");
    774         assertValue(saveRequest.structure, ID_L2C1, "L2C1");
    775         assertValue(saveRequest.structure, ID_L3C1, "L3C1");
    776     }
    777 
    778     @Test
    779     public void testSaveThreeSaveInfosDifferentTypesIncludingGeneric() throws Exception {
    780         // Set service.
    781         enableService();
    782 
    783         // Trigger 1st partition.
    784         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    785                 .addDataset(new CannedDataset.Builder()
    786                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    787                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    788                         .build())
    789                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    790                 .build();
    791         sReplier.addResponse(response1);
    792         mActivity.focusCell(1, 1);
    793         sReplier.getNextFillRequest();
    794 
    795         // Trigger 2nd partition.
    796         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    797                 .addDataset(new CannedDataset.Builder()
    798                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    799                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    800                         .build())
    801                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_GENERIC, ID_L2C1)
    802                 .build();
    803         sReplier.addResponse(response2);
    804         mActivity.focusCell(2, 1);
    805         sReplier.getNextFillRequest();
    806 
    807         // Trigger 3rd partition.
    808         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    809                 .addDataset(new CannedDataset.Builder()
    810                         .setField(ID_L3C1, "l3c1", createPresentation("l3c1"))
    811                         .setField(ID_L3C2, "l3c2", createPresentation("l3c2"))
    812                         .build())
    813                 .setRequiredSavableIds(
    814                         SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_GENERIC | SAVE_DATA_TYPE_USERNAME,
    815                         ID_L3C1)
    816                 .build();
    817         sReplier.addResponse(response3);
    818         mActivity.focusCell(3, 1);
    819         sReplier.getNextFillRequest();
    820 
    821 
    822         // Trigger save
    823         mActivity.setText(1, 1, "L1C1");
    824         mActivity.setText(2, 1, "L2C1");
    825         mActivity.setText(3, 1, "L3C1");
    826         mActivity.save();
    827 
    828         // Make sure GENERIC type is not shown on snackbar
    829         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD, SAVE_DATA_TYPE_USERNAME);
    830         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    831         assertValue(saveRequest.structure, ID_L1C1, "L1C1");
    832         assertValue(saveRequest.structure, ID_L2C1, "L2C1");
    833         assertValue(saveRequest.structure, ID_L3C1, "L3C1");
    834     }
    835 
    836     @Test
    837     public void testSaveMoreThanThreeSaveInfosDifferentTypes() throws Exception {
    838         // Set service.
    839         enableService();
    840 
    841         // Trigger 1st partition.
    842         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    843                 .addDataset(new CannedDataset.Builder()
    844                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    845                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    846                         .build())
    847                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_L1C1)
    848                 .build();
    849         sReplier.addResponse(response1);
    850         mActivity.focusCell(1, 1);
    851         sReplier.getNextFillRequest();
    852 
    853         // Trigger 2nd partition.
    854         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    855                 .addDataset(new CannedDataset.Builder()
    856                         .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
    857                         .setField(ID_L2C2, "l2c2", createPresentation("l2c2"))
    858                         .build())
    859                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD,
    860                         ID_L2C1)
    861                 .build();
    862         sReplier.addResponse(response2);
    863         mActivity.focusCell(2, 1);
    864         sReplier.getNextFillRequest();
    865 
    866         // Trigger 3rd partition.
    867         final CannedFillResponse response3 = new CannedFillResponse.Builder()
    868                 .addDataset(new CannedDataset.Builder()
    869                         .setField(ID_L3C1, "l3c1", createPresentation("l3c1"))
    870                         .setField(ID_L3C2, "l3c2", createPresentation("l3c2"))
    871                         .build())
    872                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD
    873                         | SAVE_DATA_TYPE_USERNAME, ID_L3C1)
    874                 .build();
    875         sReplier.addResponse(response3);
    876         mActivity.focusCell(3, 1);
    877         sReplier.getNextFillRequest();
    878 
    879         // Trigger 4th partition.
    880         final CannedFillResponse response4 = new CannedFillResponse.Builder()
    881                 .addDataset(new CannedDataset.Builder()
    882                         .setField(ID_L4C1, "l4c1", createPresentation("l4c1"))
    883                         .setField(ID_L4C2, "l4c2", createPresentation("l4c2"))
    884                         .build())
    885                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD | SAVE_DATA_TYPE_CREDIT_CARD
    886                         | SAVE_DATA_TYPE_USERNAME | SAVE_DATA_TYPE_ADDRESS, ID_L4C1)
    887                 .build();
    888         sReplier.addResponse(response4);
    889         mActivity.focusCell(4, 1);
    890         sReplier.getNextFillRequest();
    891 
    892 
    893         // Trigger save
    894         mActivity.setText(1, 1, "L1C1");
    895         mActivity.setText(2, 1, "L2C1");
    896         mActivity.setText(3, 1, "L3C1");
    897         mActivity.setText(4, 1, "L4C1");
    898         mActivity.save();
    899 
    900         sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
    901         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
    902         assertValue(saveRequest.structure, ID_L1C1, "L1C1");
    903         assertValue(saveRequest.structure, ID_L2C1, "L2C1");
    904         assertValue(saveRequest.structure, ID_L3C1, "L3C1");
    905         assertValue(saveRequest.structure, ID_L4C1, "L4C1");
    906     }
    907 
    908     @Test
    909     public void testIgnoredFieldsDontTriggerAutofill() throws Exception {
    910         // Set service.
    911         enableService();
    912 
    913         // Prepare 1st partition.
    914         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    915                 .addDataset(new CannedDataset.Builder()
    916                         .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
    917                         .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
    918                         .build())
    919                 .setIgnoreFields(ID_L2C1, ID_L2C2)
    920                 .build();
    921         sReplier.addResponse(response1);
    922 
    923         // Trigger auto-fill on 1st partition.
    924         mActivity.focusCell(1, 1);
    925         final FillRequest fillRequest1 = sReplier.getNextFillRequest();
    926         assertThat(fillRequest1.flags).isEqualTo(0);
    927         final ViewNode p1l1c1 = assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
    928         final ViewNode p1l1c2 = assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
    929         assertWithMessage("Focus on p1l1c1").that(p1l1c1.isFocused()).isTrue();
    930         assertWithMessage("Focus on p1l1c2").that(p1l1c2.isFocused()).isFalse();
    931 
    932         // Make sure UI is shown on 1st partition
    933         sUiBot.assertDatasets("l1c1");
    934         mActivity.focusCell(1, 2);
    935         sUiBot.assertDatasets("l1c2");
    936 
    937         // Make sure UI is not shown on ignored partition
    938         mActivity.focusCell(2, 1);
    939         sUiBot.assertNoDatasets();
    940         mActivity.focusCell(2, 2);
    941         sUiBot.assertNoDatasets();
    942     }
    943 
    944     /**
    945      * Tests scenario where each partition has more than one dataset, but they don't overlap, i.e.,
    946      * each {@link FillResponse} only contain fields within the partition.
    947      */
    948     @Test
    949     public void testAutofillMultipleDatasetsNoOverlap() throws Exception {
    950         // Set service.
    951         enableService();
    952 
    953         /**
    954          * 1st partition.
    955          */
    956         // Set expectations.
    957         final CannedFillResponse response1 = new CannedFillResponse.Builder()
    958                 .addDataset(new CannedDataset.Builder()
    959                         .setPresentation(createPresentation("P1D1"))
    960                         .setField(ID_L1C1, "l1c1")
    961                         .setField(ID_L1C2, "l1c2")
    962                         .build())
    963                 .addDataset(new CannedDataset.Builder()
    964                         .setPresentation(createPresentation("P1D2"))
    965                         .setField(ID_L1C1, "L1C1")
    966                         .build())
    967                 .build();
    968         sReplier.addResponse(response1);
    969         final FillExpectation expectation1 = mActivity.expectAutofill()
    970                 .onCell(1, 1, "l1c1")
    971                 .onCell(1, 2, "l1c2");
    972 
    973         // Trigger partition.
    974         mActivity.focusCell(1, 1);
    975         sReplier.getNextFillRequest();
    976 
    977 
    978         /**
    979          * 2nd partition.
    980          */
    981         // Set expectations.
    982         final CannedFillResponse response2 = new CannedFillResponse.Builder()
    983                 .addDataset(new CannedDataset.Builder()
    984                         .setPresentation(createPresentation("P2D1"))
    985                         .setField(ID_L2C1, "l2c1")
    986                         .setField(ID_L2C2, "l2c2")
    987                         .build())
    988                 .addDataset(new CannedDataset.Builder()
    989                         .setPresentation(createPresentation("P2D2"))
    990                         .setField(ID_L2C2, "L2C2")
    991                         .build())
    992                 .build();
    993         sReplier.addResponse(response2);
    994         final FillExpectation expectation2 = mActivity.expectAutofill()
    995                 .onCell(2, 2, "L2C2");
    996 
    997         // Trigger partition.
    998         mActivity.focusCell(2, 1);
    999         sReplier.getNextFillRequest();
   1000 
   1001         /**
   1002          * 3rd partition.
   1003          */
   1004         // Set expectations.
   1005         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1006                 .addDataset(new CannedDataset.Builder()
   1007                         .setPresentation(createPresentation("P3D1"))
   1008                         .setField(ID_L3C1, "l3c1")
   1009                         .setField(ID_L3C2, "l3c2")
   1010                         .build())
   1011                 .addDataset(new CannedDataset.Builder()
   1012                         .setPresentation(createPresentation("P3D2"))
   1013                         .setField(ID_L3C1, "L3C1")
   1014                         .setField(ID_L3C2, "L3C2")
   1015                         .build())
   1016                 .build();
   1017         sReplier.addResponse(response3);
   1018         final FillExpectation expectation3 = mActivity.expectAutofill()
   1019                 .onCell(3, 1, "L3C1")
   1020                 .onCell(3, 2, "L3C2");
   1021 
   1022         // Trigger partition.
   1023         mActivity.focusCell(3, 1);
   1024         sReplier.getNextFillRequest();
   1025 
   1026         /**
   1027          * 4th partition.
   1028          */
   1029         // Set expectations.
   1030         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   1031                 .addDataset(new CannedDataset.Builder()
   1032                         .setPresentation(createPresentation("P4D1"))
   1033                         .setField(ID_L4C1, "l4c1")
   1034                         .build())
   1035                 .addDataset(new CannedDataset.Builder()
   1036                         .setPresentation(createPresentation("P4D2"))
   1037                         .setField(ID_L4C1, "L4C1")
   1038                         .setField(ID_L4C2, "L4C2")
   1039                         .build())
   1040                 .build();
   1041         sReplier.addResponse(response4);
   1042         final FillExpectation expectation4 = mActivity.expectAutofill()
   1043                 .onCell(4, 1, "l4c1");
   1044 
   1045         // Trigger partition.
   1046         mActivity.focusCell(4, 1);
   1047         sReplier.getNextFillRequest();
   1048 
   1049         /*
   1050          *  Now move focus around to make sure the proper values are displayed each time.
   1051          */
   1052         mActivity.focusCell(1, 1);
   1053         sUiBot.assertDatasets("P1D1", "P1D2");
   1054         mActivity.focusCell(1, 2);
   1055         sUiBot.assertDatasets("P1D1");
   1056 
   1057         mActivity.focusCell(2, 1);
   1058         sUiBot.assertDatasets("P2D1");
   1059         mActivity.focusCell(2, 2);
   1060         sUiBot.assertDatasets("P2D1", "P2D2");
   1061 
   1062         mActivity.focusCell(4, 1);
   1063         sUiBot.assertDatasets("P4D1", "P4D2");
   1064         mActivity.focusCell(4, 2);
   1065         sUiBot.assertDatasets("P4D2");
   1066 
   1067         mActivity.focusCell(3, 2);
   1068         sUiBot.assertDatasets("P3D1", "P3D2");
   1069         mActivity.focusCell(3, 1);
   1070         sUiBot.assertDatasets("P3D1", "P3D2");
   1071 
   1072         /*
   1073          *  Finally, autofill and check results.
   1074          */
   1075         mActivity.focusCell(4, 1);
   1076         sUiBot.selectDataset("P4D1");
   1077         expectation4.assertAutoFilled();
   1078 
   1079         mActivity.focusCell(1, 1);
   1080         sUiBot.selectDataset("P1D1");
   1081         expectation1.assertAutoFilled();
   1082 
   1083         mActivity.focusCell(3, 1);
   1084         sUiBot.selectDataset("P3D2");
   1085         expectation3.assertAutoFilled();
   1086 
   1087         mActivity.focusCell(2, 2);
   1088         sUiBot.selectDataset("P2D2");
   1089         expectation2.assertAutoFilled();
   1090     }
   1091 
   1092     /**
   1093      * Tests scenario where each partition has more than one dataset, but they overlap, i.e.,
   1094      * some fields are present in more than one partition.
   1095      *
   1096      * <p>Whenever a new partition defines a field previously present in another partittion, that
   1097      * partition will "own" that field.
   1098      *
   1099      * <p>In the end, 4th partition will one all fields in 2 datasets; and this test cases picks
   1100      * the first.
   1101      */
   1102     @Test
   1103     public void testAutofillMultipleDatasetsOverlappingPicksFirst() throws Exception {
   1104         autofillMultipleDatasetsOverlapping(true);
   1105     }
   1106 
   1107     /**
   1108      * Tests scenario where each partition has more than one dataset, but they overlap, i.e.,
   1109      * some fields are present in more than one partition.
   1110      *
   1111      * <p>Whenever a new partition defines a field previously present in another partittion, that
   1112      * partition will "own" that field.
   1113      *
   1114      * <p>In the end, 4th partition will one all fields in 2 datasets; and this test cases picks
   1115      * the second.
   1116      */
   1117     @Test
   1118     public void testAutofillMultipleDatasetsOverlappingPicksSecond() throws Exception {
   1119         autofillMultipleDatasetsOverlapping(false);
   1120     }
   1121 
   1122     private void autofillMultipleDatasetsOverlapping(boolean pickFirst) throws Exception {
   1123         // Set service.
   1124         enableService();
   1125 
   1126         /**
   1127          * 1st partition.
   1128          */
   1129         // Set expectations.
   1130         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   1131                 .addDataset(new CannedDataset.Builder()
   1132                         .setPresentation(createPresentation("P1D1"))
   1133                         .setField(ID_L1C1, "1l1c1")
   1134                         .setField(ID_L1C2, "1l1c2")
   1135                         .build())
   1136                 .addDataset(new CannedDataset.Builder()
   1137                         .setPresentation(createPresentation("P1D2"))
   1138                         .setField(ID_L1C1, "1L1C1")
   1139                         .build())
   1140                 .build();
   1141         sReplier.addResponse(response1);
   1142 
   1143         // Trigger partition.
   1144         mActivity.focusCell(1, 1);
   1145         sReplier.getNextFillRequest();
   1146 
   1147         // Asserts proper datasets are shown on each field defined so far.
   1148         mActivity.focusCell(1, 1);
   1149         sUiBot.assertDatasets("P1D1", "P1D2");
   1150         mActivity.focusCell(1, 2);
   1151         sUiBot.assertDatasets("P1D1");
   1152 
   1153         /**
   1154          * 2nd partition.
   1155          */
   1156         // Set expectations.
   1157         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   1158                 .addDataset(new CannedDataset.Builder()
   1159                         .setPresentation(createPresentation("P2D1"))
   1160                         .setField(ID_L1C1, "2l1c1") // from previous partition
   1161                         .setField(ID_L2C1, "2l2c1")
   1162                         .setField(ID_L2C2, "2l2c2")
   1163                         .build())
   1164                 .addDataset(new CannedDataset.Builder()
   1165                         .setPresentation(createPresentation("P2D2"))
   1166                         .setField(ID_L2C2, "2L2C2")
   1167                         .build())
   1168                 .build();
   1169         sReplier.addResponse(response2);
   1170 
   1171         // Trigger partition.
   1172         mActivity.focusCell(2, 1);
   1173         sReplier.getNextFillRequest();
   1174 
   1175         // Asserts proper datasets are shown on each field defined so far.
   1176         mActivity.focusCell(1, 1);
   1177         sUiBot.assertDatasets("P2D1"); // changed
   1178         mActivity.focusCell(1, 2);
   1179         sUiBot.assertDatasets("P1D1");
   1180         mActivity.focusCell(2, 1);
   1181         sUiBot.assertDatasets("P2D1");
   1182         mActivity.focusCell(2, 2);
   1183         sUiBot.assertDatasets("P2D1", "P2D2");
   1184 
   1185         /**
   1186          * 3rd partition.
   1187          */
   1188         // Set expectations.
   1189         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1190                 .addDataset(new CannedDataset.Builder()
   1191                         .setPresentation(createPresentation("P3D1"))
   1192                         .setField(ID_L1C2, "3l1c2")
   1193                         .setField(ID_L3C1, "3l3c1")
   1194                         .setField(ID_L3C2, "3l3c2")
   1195                         .build())
   1196                 .addDataset(new CannedDataset.Builder()
   1197                         .setPresentation(createPresentation("P3D2"))
   1198                         .setField(ID_L2C2, "3l2c2")
   1199                         .setField(ID_L3C1, "3L3C1")
   1200                         .setField(ID_L3C2, "3L3C2")
   1201                         .build())
   1202                 .build();
   1203         sReplier.addResponse(response3);
   1204 
   1205         // Trigger partition.
   1206         mActivity.focusCell(3, 1);
   1207         sReplier.getNextFillRequest();
   1208 
   1209         // Asserts proper datasets are shown on each field defined so far.
   1210         mActivity.focusCell(1, 1);
   1211         sUiBot.assertDatasets("P2D1");
   1212         mActivity.focusCell(1, 2);
   1213         sUiBot.assertDatasets("P3D1"); // changed
   1214         mActivity.focusCell(2, 1);
   1215         sUiBot.assertDatasets("P2D1");
   1216         mActivity.focusCell(2, 2);
   1217         sUiBot.assertDatasets("P3D2"); // changed
   1218         mActivity.focusCell(3, 2);
   1219         sUiBot.assertDatasets("P3D1", "P3D2");
   1220         mActivity.focusCell(3, 1);
   1221         sUiBot.assertDatasets("P3D1", "P3D2");
   1222 
   1223         /**
   1224          * 4th partition.
   1225          */
   1226         // Set expectations.
   1227         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   1228                 .addDataset(new CannedDataset.Builder()
   1229                         .setPresentation(createPresentation("P4D1"))
   1230                         .setField(ID_L1C1, "4l1c1")
   1231                         .setField(ID_L1C2, "4l1c2")
   1232                         .setField(ID_L2C1, "4l2c1")
   1233                         .setField(ID_L2C2, "4l2c2")
   1234                         .setField(ID_L3C1, "4l3c1")
   1235                         .setField(ID_L3C2, "4l3c2")
   1236                         .setField(ID_L4C1, "4l4c1")
   1237                         .build())
   1238                 .addDataset(new CannedDataset.Builder()
   1239                         .setPresentation(createPresentation("P4D2"))
   1240                         .setField(ID_L1C1, "4L1C1")
   1241                         .setField(ID_L1C2, "4L1C2")
   1242                         .setField(ID_L2C1, "4L2C1")
   1243                         .setField(ID_L2C2, "4L2C2")
   1244                         .setField(ID_L3C1, "4L3C1")
   1245                         .setField(ID_L3C2, "4L3C2")
   1246                         .setField(ID_L1C1, "4L1C1")
   1247                         .setField(ID_L4C1, "4L4C1")
   1248                         .setField(ID_L4C2, "4L4C2")
   1249                         .build())
   1250                 .build();
   1251         sReplier.addResponse(response4);
   1252 
   1253         // Trigger partition.
   1254         mActivity.focusCell(4, 1);
   1255         sReplier.getNextFillRequest();
   1256 
   1257         // Asserts proper datasets are shown on each field defined so far.
   1258         mActivity.focusCell(1, 1);
   1259         sUiBot.assertDatasets("P4D1", "P4D2");
   1260         mActivity.focusCell(1, 2);
   1261         sUiBot.assertDatasets("P4D1", "P4D2");
   1262         mActivity.focusCell(2, 1);
   1263         sUiBot.assertDatasets("P4D1", "P4D2");
   1264         mActivity.focusCell(2, 2);
   1265         sUiBot.assertDatasets("P4D1", "P4D2");
   1266         mActivity.focusCell(3, 2);
   1267         sUiBot.assertDatasets("P4D1", "P4D2");
   1268         mActivity.focusCell(3, 1);
   1269         sUiBot.assertDatasets("P4D1", "P4D2");
   1270         mActivity.focusCell(4, 1);
   1271         sUiBot.assertDatasets("P4D1", "P4D2");
   1272         mActivity.focusCell(4, 2);
   1273         sUiBot.assertDatasets("P4D2");
   1274 
   1275         /*
   1276          * Finally, autofill and check results.
   1277          */
   1278         final FillExpectation expectation = mActivity.expectAutofill();
   1279         final String chosenOne;
   1280         if (pickFirst) {
   1281             expectation
   1282                 .onCell(1, 1, "4l1c1")
   1283                 .onCell(1, 2, "4l1c2")
   1284                 .onCell(2, 1, "4l2c1")
   1285                 .onCell(2, 2, "4l2c2")
   1286                 .onCell(3, 1, "4l3c1")
   1287                 .onCell(3, 2, "4l3c2")
   1288                 .onCell(4, 1, "4l4c1");
   1289             chosenOne = "P4D1";
   1290         } else {
   1291             expectation
   1292                 .onCell(1, 1, "4L1C1")
   1293                 .onCell(1, 2, "4L1C2")
   1294                 .onCell(2, 1, "4L2C1")
   1295                 .onCell(2, 2, "4L2C2")
   1296                 .onCell(3, 1, "4L3C1")
   1297                 .onCell(3, 2, "4L3C2")
   1298                 .onCell(4, 1, "4L4C1")
   1299                 .onCell(4, 2, "4L4C2");
   1300             chosenOne = "P4D2";
   1301         }
   1302 
   1303         mActivity.focusCell(4, 1);
   1304         sUiBot.selectDataset(chosenOne);
   1305         expectation.assertAutoFilled();
   1306     }
   1307 
   1308     @Test
   1309     public void testAutofillMultipleAuthDatasetsInSequence() throws Exception {
   1310         // Set service.
   1311         enableService();
   1312 
   1313         // TODO: current API requires these fields...
   1314         final RemoteViews bogusPresentation = createPresentation("Whatever man, I'm not used...");
   1315         final String bogusValue = "Y U REQUIRE IT?";
   1316 
   1317         /**
   1318          * 1st partition.
   1319          */
   1320         // Set expectations.
   1321         final IntentSender auth11 = AuthenticationActivity.createSender(getContext(), 11,
   1322                 new CannedDataset.Builder()
   1323                         .setField(ID_L1C1, "l1c1")
   1324                         .setField(ID_L1C2, "l1c2")
   1325                         .setPresentation(bogusPresentation)
   1326                         .build());
   1327         final IntentSender auth12 = AuthenticationActivity.createSender(getContext(), 12);
   1328         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   1329                 .addDataset(new CannedDataset.Builder()
   1330                         .setAuthentication(auth11)
   1331                         .setField(ID_L1C1, bogusValue)
   1332                         .setField(ID_L1C2, bogusValue)
   1333                         .setPresentation(createPresentation("P1D1"))
   1334                         .build())
   1335                 .addDataset(new CannedDataset.Builder()
   1336                         .setAuthentication(auth12)
   1337                         .setField(ID_L1C1, bogusValue)
   1338                         .setPresentation(createPresentation("P1D2"))
   1339                         .build())
   1340                 .build();
   1341         sReplier.addResponse(response1);
   1342         final FillExpectation expectation1 = mActivity.expectAutofill()
   1343                 .onCell(1, 1, "l1c1")
   1344                 .onCell(1, 2, "l1c2");
   1345 
   1346         // Trigger partition.
   1347         mActivity.focusCell(1, 1);
   1348         sReplier.getNextFillRequest();
   1349 
   1350         // Focus around different fields in the partition.
   1351         sUiBot.assertDatasets("P1D1", "P1D2");
   1352         mActivity.focusCell(1, 2);
   1353         sUiBot.assertDatasets("P1D1");
   1354 
   1355         // Autofill it...
   1356         sUiBot.selectDataset("P1D1");
   1357         // ... and assert result
   1358         expectation1.assertAutoFilled();
   1359 
   1360         /**
   1361          * 2nd partition.
   1362          */
   1363         // Set expectations.
   1364         final IntentSender auth21 = AuthenticationActivity.createSender(getContext(), 21);
   1365         final IntentSender auth22 = AuthenticationActivity.createSender(getContext(), 22,
   1366                 new CannedDataset.Builder()
   1367                     .setField(ID_L2C2, "L2C2")
   1368                     .setPresentation(bogusPresentation)
   1369                     .build());
   1370         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   1371                 .addDataset(new CannedDataset.Builder()
   1372                         .setAuthentication(auth21)
   1373                         .setPresentation(createPresentation("P2D1"))
   1374                         .setField(ID_L2C1, bogusValue)
   1375                         .setField(ID_L2C2, bogusValue)
   1376                         .build())
   1377                 .addDataset(new CannedDataset.Builder()
   1378                         .setAuthentication(auth22)
   1379                         .setPresentation(createPresentation("P2D2"))
   1380                         .setField(ID_L2C2, bogusValue)
   1381                         .build())
   1382                 .build();
   1383         sReplier.addResponse(response2);
   1384         final FillExpectation expectation2 = mActivity.expectAutofill()
   1385                 .onCell(2, 2, "L2C2");
   1386 
   1387         // Trigger partition.
   1388         mActivity.focusCell(2, 1);
   1389         sReplier.getNextFillRequest();
   1390 
   1391         // Focus around different fields in the partition.
   1392         sUiBot.assertDatasets("P2D1");
   1393         mActivity.focusCell(2, 2);
   1394         sUiBot.assertDatasets("P2D1", "P2D2");
   1395 
   1396         // Autofill it...
   1397         sUiBot.selectDataset("P2D2");
   1398         // ... and assert result
   1399         expectation2.assertAutoFilled();
   1400 
   1401         /**
   1402          * 3rd partition.
   1403          */
   1404         // Set expectations.
   1405         final IntentSender auth31 = AuthenticationActivity.createSender(getContext(), 31,
   1406                 new CannedDataset.Builder()
   1407                         .setField(ID_L3C1, "l3c1")
   1408                         .setField(ID_L3C2, "l3c2")
   1409                         .setPresentation(bogusPresentation)
   1410                         .build());
   1411         final IntentSender auth32 = AuthenticationActivity.createSender(getContext(), 32);
   1412         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1413                 .addDataset(new CannedDataset.Builder()
   1414                         .setAuthentication(auth31)
   1415                         .setPresentation(createPresentation("P3D1"))
   1416                         .setField(ID_L3C1, bogusValue)
   1417                         .setField(ID_L3C2, bogusValue)
   1418                         .build())
   1419                 .addDataset(new CannedDataset.Builder()
   1420                         .setAuthentication(auth32)
   1421                         .setPresentation(createPresentation("P3D2"))
   1422                         .setField(ID_L3C1, bogusValue)
   1423                         .setField(ID_L3C2, bogusValue)
   1424                         .build())
   1425                 .build();
   1426         sReplier.addResponse(response3);
   1427         final FillExpectation expectation3 = mActivity.expectAutofill()
   1428                 .onCell(3, 1, "l3c1")
   1429                 .onCell(3, 2, "l3c2");
   1430 
   1431         // Trigger partition.
   1432         mActivity.focusCell(3, 2);
   1433         sReplier.getNextFillRequest();
   1434 
   1435         // Focus around different fields in the partition.
   1436         sUiBot.assertDatasets("P3D1", "P3D2");
   1437         mActivity.focusCell(3, 1);
   1438         sUiBot.assertDatasets("P3D1", "P3D2");
   1439 
   1440         // Autofill it...
   1441         sUiBot.selectDataset("P3D1");
   1442         // ... and assert result
   1443         expectation3.assertAutoFilled();
   1444 
   1445         /**
   1446          * 4th partition.
   1447          */
   1448         // Set expectations.
   1449         final IntentSender auth41 = AuthenticationActivity.createSender(getContext(), 41);
   1450         final IntentSender auth42 = AuthenticationActivity.createSender(getContext(), 42,
   1451                 new CannedDataset.Builder()
   1452                     .setField(ID_L4C1, "L4C1")
   1453                     .setField(ID_L4C2, "L4C2")
   1454                     .setPresentation(bogusPresentation)
   1455                     .build());
   1456         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   1457                 .addDataset(new CannedDataset.Builder()
   1458                         .setAuthentication(auth41)
   1459                         .setPresentation(createPresentation("P4D1"))
   1460                         .setField(ID_L4C1, bogusValue)
   1461                         .build())
   1462                 .addDataset(new CannedDataset.Builder()
   1463                         .setAuthentication(auth42)
   1464                         .setPresentation(createPresentation("P4D2"))
   1465                         .setField(ID_L4C1, bogusValue)
   1466                         .setField(ID_L4C2, bogusValue)
   1467                         .build())
   1468                 .build();
   1469         sReplier.addResponse(response4);
   1470         final FillExpectation expectation4 = mActivity.expectAutofill()
   1471                 .onCell(4, 1, "L4C1")
   1472                 .onCell(4, 2, "L4C2");
   1473 
   1474         // Trigger partition.
   1475         mActivity.focusCell(4, 1);
   1476         sReplier.getNextFillRequest();
   1477 
   1478         // Focus around different fields in the partition.
   1479         sUiBot.assertDatasets("P4D1", "P4D2");
   1480         mActivity.focusCell(4, 2);
   1481         sUiBot.assertDatasets("P4D2");
   1482 
   1483         // Autofill it...
   1484         sUiBot.selectDataset("P4D2");
   1485         // ... and assert result
   1486         expectation4.assertAutoFilled();
   1487     }
   1488 
   1489     /**
   1490      * Tests scenario where each partition has more than one dataset and all datasets require auth,
   1491      * but they don't overlap, i.e., each {@link FillResponse} only contain fields within the
   1492      * partition.
   1493      */
   1494     @Test
   1495     public void testAutofillMultipleAuthDatasetsNoOverlap() throws Exception {
   1496         // Set service.
   1497         enableService();
   1498 
   1499         // TODO: current API requires these fields...
   1500         final RemoteViews bogusPresentation = createPresentation("Whatever man, I'm not used...");
   1501         final String bogusValue = "Y U REQUIRE IT?";
   1502 
   1503         /**
   1504          * 1st partition.
   1505          */
   1506         // Set expectations.
   1507         final IntentSender auth11 = AuthenticationActivity.createSender(getContext(), 11,
   1508                 new CannedDataset.Builder()
   1509                         .setField(ID_L1C1, "l1c1")
   1510                         .setField(ID_L1C2, "l1c2")
   1511                         .setPresentation(bogusPresentation)
   1512                         .build());
   1513         final IntentSender auth12 = AuthenticationActivity.createSender(getContext(), 12);
   1514         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   1515                 .addDataset(new CannedDataset.Builder()
   1516                         .setAuthentication(auth11)
   1517                         .setField(ID_L1C1, bogusValue)
   1518                         .setField(ID_L1C2, bogusValue)
   1519                         .setPresentation(createPresentation("P1D1"))
   1520                         .build())
   1521                 .addDataset(new CannedDataset.Builder()
   1522                         .setAuthentication(auth12)
   1523                         .setField(ID_L1C1, bogusValue)
   1524                         .setPresentation(createPresentation("P1D2"))
   1525                         .build())
   1526                 .build();
   1527         sReplier.addResponse(response1);
   1528         final FillExpectation expectation1 = mActivity.expectAutofill()
   1529                 .onCell(1, 1, "l1c1")
   1530                 .onCell(1, 2, "l1c2");
   1531 
   1532         // Trigger partition.
   1533         mActivity.focusCell(1, 1);
   1534         sReplier.getNextFillRequest();
   1535 
   1536         /**
   1537          * 2nd partition.
   1538          */
   1539         // Set expectations.
   1540         final IntentSender auth21 = AuthenticationActivity.createSender(getContext(), 21);
   1541         final IntentSender auth22 = AuthenticationActivity.createSender(getContext(), 22,
   1542                 new CannedDataset.Builder()
   1543                     .setField(ID_L2C2, "L2C2")
   1544                     .setPresentation(bogusPresentation)
   1545                     .build());
   1546         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   1547                 .addDataset(new CannedDataset.Builder()
   1548                         .setAuthentication(auth21)
   1549                         .setPresentation(createPresentation("P2D1"))
   1550                         .setField(ID_L2C1, bogusValue)
   1551                         .setField(ID_L2C2, bogusValue)
   1552                         .build())
   1553                 .addDataset(new CannedDataset.Builder()
   1554                         .setAuthentication(auth22)
   1555                         .setPresentation(createPresentation("P2D2"))
   1556                         .setField(ID_L2C2, bogusValue)
   1557                         .build())
   1558                 .build();
   1559         sReplier.addResponse(response2);
   1560         final FillExpectation expectation2 = mActivity.expectAutofill()
   1561                 .onCell(2, 2, "L2C2");
   1562 
   1563         // Trigger partition.
   1564         mActivity.focusCell(2, 1);
   1565         sReplier.getNextFillRequest();
   1566 
   1567         /**
   1568          * 3rd partition.
   1569          */
   1570         // Set expectations.
   1571         final IntentSender auth31 = AuthenticationActivity.createSender(getContext(), 31,
   1572                 new CannedDataset.Builder()
   1573                         .setField(ID_L3C1, "l3c1")
   1574                         .setField(ID_L3C2, "l3c2")
   1575                         .setPresentation(bogusPresentation)
   1576                         .build());
   1577         final IntentSender auth32 = AuthenticationActivity.createSender(getContext(), 32);
   1578         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1579                 .addDataset(new CannedDataset.Builder()
   1580                         .setAuthentication(auth31)
   1581                         .setPresentation(createPresentation("P3D1"))
   1582                         .setField(ID_L3C1, bogusValue)
   1583                         .setField(ID_L3C2, bogusValue)
   1584                         .build())
   1585                 .addDataset(new CannedDataset.Builder()
   1586                         .setAuthentication(auth32)
   1587                         .setPresentation(createPresentation("P3D2"))
   1588                         .setField(ID_L3C1, bogusValue)
   1589                         .setField(ID_L3C2, bogusValue)
   1590                         .build())
   1591                 .build();
   1592         sReplier.addResponse(response3);
   1593         final FillExpectation expectation3 = mActivity.expectAutofill()
   1594                 .onCell(3, 1, "l3c1")
   1595                 .onCell(3, 2, "l3c2");
   1596 
   1597         // Trigger partition.
   1598         mActivity.focusCell(3, 2);
   1599         sReplier.getNextFillRequest();
   1600 
   1601         /**
   1602          * 4th partition.
   1603          */
   1604         // Set expectations.
   1605         final IntentSender auth41 = AuthenticationActivity.createSender(getContext(), 41);
   1606         final IntentSender auth42 = AuthenticationActivity.createSender(getContext(), 42,
   1607                 new CannedDataset.Builder()
   1608                     .setField(ID_L4C1, "L4C1")
   1609                     .setField(ID_L4C2, "L4C2")
   1610                     .setPresentation(bogusPresentation)
   1611                     .build());
   1612         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   1613                 .addDataset(new CannedDataset.Builder()
   1614                         .setAuthentication(auth41)
   1615                         .setPresentation(createPresentation("P4D1"))
   1616                         .setField(ID_L4C1, bogusValue)
   1617                         .build())
   1618                 .addDataset(new CannedDataset.Builder()
   1619                         .setAuthentication(auth42)
   1620                         .setPresentation(createPresentation("P4D2"))
   1621                         .setField(ID_L4C1, bogusValue)
   1622                         .setField(ID_L4C2, bogusValue)
   1623                         .build())
   1624                 .build();
   1625         sReplier.addResponse(response4);
   1626         final FillExpectation expectation4 = mActivity.expectAutofill()
   1627                 .onCell(4, 1, "L4C1")
   1628                 .onCell(4, 2, "L4C2");
   1629 
   1630         mActivity.focusCell(4, 1);
   1631         sReplier.getNextFillRequest();
   1632 
   1633         /*
   1634          *  Now move focus around to make sure the proper values are displayed each time.
   1635          */
   1636         mActivity.focusCell(1, 1);
   1637         sUiBot.assertDatasets("P1D1", "P1D2");
   1638         mActivity.focusCell(1, 2);
   1639         sUiBot.assertDatasets("P1D1");
   1640 
   1641         mActivity.focusCell(2, 1);
   1642         sUiBot.assertDatasets("P2D1");
   1643         mActivity.focusCell(2, 2);
   1644         sUiBot.assertDatasets("P2D1", "P2D2");
   1645 
   1646         mActivity.focusCell(4, 1);
   1647         sUiBot.assertDatasets("P4D1", "P4D2");
   1648         mActivity.focusCell(4, 2);
   1649         sUiBot.assertDatasets("P4D2");
   1650 
   1651         mActivity.focusCell(3, 2);
   1652         sUiBot.assertDatasets("P3D1", "P3D2");
   1653         mActivity.focusCell(3, 1);
   1654         sUiBot.assertDatasets("P3D1", "P3D2");
   1655 
   1656         /*
   1657          *  Finally, autofill and check results.
   1658          */
   1659         mActivity.focusCell(4, 1);
   1660         sUiBot.selectDataset("P4D2");
   1661         expectation4.assertAutoFilled();
   1662 
   1663         mActivity.focusCell(1, 1);
   1664         sUiBot.selectDataset("P1D1");
   1665         expectation1.assertAutoFilled();
   1666 
   1667         mActivity.focusCell(3, 1);
   1668         sUiBot.selectDataset("P3D1");
   1669         expectation3.assertAutoFilled();
   1670 
   1671         mActivity.focusCell(2, 2);
   1672         sUiBot.selectDataset("P2D2");
   1673         expectation2.assertAutoFilled();
   1674     }
   1675 
   1676     /**
   1677      * Tests scenario where each partition has more than one dataset and some datasets require auth,
   1678      * but they don't overlap, i.e., each {@link FillResponse} only contain fields within the
   1679      * partition.
   1680      */
   1681     @Test
   1682     public void testAutofillMultipleDatasetsMixedAuthNoAuthNoOverlap() throws Exception {
   1683         // Set service.
   1684         enableService();
   1685 
   1686         // TODO: current API requires these fields...
   1687         final RemoteViews bogusPresentation = createPresentation("Whatever man, I'm not used...");
   1688         final String bogusValue = "Y U REQUIRE IT?";
   1689 
   1690         /**
   1691          * 1st partition.
   1692          */
   1693         // Set expectations.
   1694         final IntentSender auth12 = AuthenticationActivity.createSender(getContext(), 12);
   1695         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   1696                 .addDataset(new CannedDataset.Builder()
   1697                         .setField(ID_L1C1, "l1c1")
   1698                         .setField(ID_L1C2, "l1c2")
   1699                         .setPresentation(createPresentation("P1D1"))
   1700                         .build())
   1701                 .addDataset(new CannedDataset.Builder()
   1702                         .setAuthentication(auth12)
   1703                         .setField(ID_L1C1, bogusValue)
   1704                         .setPresentation(createPresentation("P1D2"))
   1705                         .build())
   1706                 .build();
   1707         sReplier.addResponse(response1);
   1708         final FillExpectation expectation1 = mActivity.expectAutofill()
   1709                 .onCell(1, 1, "l1c1")
   1710                 .onCell(1, 2, "l1c2");
   1711 
   1712         // Trigger partition.
   1713         mActivity.focusCell(1, 1);
   1714         sReplier.getNextFillRequest();
   1715 
   1716         /**
   1717          * 2nd partition.
   1718          */
   1719         // Set expectations.
   1720         final IntentSender auth22 = AuthenticationActivity.createSender(getContext(), 22,
   1721                 new CannedDataset.Builder()
   1722                     .setField(ID_L2C2, "L2C2")
   1723                     .setPresentation(bogusPresentation)
   1724                     .build());
   1725         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   1726                 .addDataset(new CannedDataset.Builder()
   1727                         .setPresentation(createPresentation("P2D1"))
   1728                         .setField(ID_L2C1, "l2c1")
   1729                         .setField(ID_L2C2, "l2c2")
   1730                         .build())
   1731                 .addDataset(new CannedDataset.Builder()
   1732                         .setAuthentication(auth22)
   1733                         .setPresentation(createPresentation("P2D2"))
   1734                         .setField(ID_L2C2, bogusValue)
   1735                         .build())
   1736                 .build();
   1737         sReplier.addResponse(response2);
   1738         final FillExpectation expectation2 = mActivity.expectAutofill()
   1739                 .onCell(2, 2, "L2C2");
   1740 
   1741         // Trigger partition.
   1742         mActivity.focusCell(2, 1);
   1743         sReplier.getNextFillRequest();
   1744 
   1745         /**
   1746          * 3rd partition.
   1747          */
   1748         // Set expectations.
   1749         final IntentSender auth31 = AuthenticationActivity.createSender(getContext(), 31,
   1750                 new CannedDataset.Builder()
   1751                         .setField(ID_L3C1, "l3c1")
   1752                         .setField(ID_L3C2, "l3c2")
   1753                         .setPresentation(bogusPresentation)
   1754                         .build());
   1755         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1756                 .addDataset(new CannedDataset.Builder()
   1757                         .setAuthentication(auth31)
   1758                         .setPresentation(createPresentation("P3D1"))
   1759                         .setField(ID_L3C1, bogusValue)
   1760                         .setField(ID_L3C2, bogusValue)
   1761                         .build())
   1762                 .addDataset(new CannedDataset.Builder()
   1763                         .setPresentation(createPresentation("P3D2"))
   1764                         .setField(ID_L3C1, "L3C1")
   1765                         .setField(ID_L3C2, "L3C2")
   1766                         .build())
   1767                 .build();
   1768         sReplier.addResponse(response3);
   1769         final FillExpectation expectation3 = mActivity.expectAutofill()
   1770                 .onCell(3, 1, "l3c1")
   1771                 .onCell(3, 2, "l3c2");
   1772 
   1773         // Trigger partition.
   1774         mActivity.focusCell(3, 2);
   1775         sReplier.getNextFillRequest();
   1776 
   1777         /**
   1778          * 4th partition.
   1779          */
   1780         // Set expectations.
   1781         final IntentSender auth41 = AuthenticationActivity.createSender(getContext(), 41);
   1782         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   1783                 .addDataset(new CannedDataset.Builder()
   1784                         .setAuthentication(auth41)
   1785                         .setPresentation(createPresentation("P4D1"))
   1786                         .setField(ID_L4C1, bogusValue)
   1787                         .build())
   1788                 .addDataset(new CannedDataset.Builder()
   1789                         .setPresentation(createPresentation("P4D2"))
   1790                         .setField(ID_L4C1, "L4C1")
   1791                         .setField(ID_L4C2, "L4C2")
   1792                         .build())
   1793                 .build();
   1794         sReplier.addResponse(response4);
   1795         final FillExpectation expectation4 = mActivity.expectAutofill()
   1796                 .onCell(4, 1, "L4C1")
   1797                 .onCell(4, 2, "L4C2");
   1798 
   1799         mActivity.focusCell(4, 1);
   1800         sReplier.getNextFillRequest();
   1801 
   1802         /*
   1803          *  Now move focus around to make sure the proper values are displayed each time.
   1804          */
   1805         mActivity.focusCell(1, 1);
   1806         sUiBot.assertDatasets("P1D1", "P1D2");
   1807         mActivity.focusCell(1, 2);
   1808         sUiBot.assertDatasets("P1D1");
   1809 
   1810         mActivity.focusCell(2, 1);
   1811         sUiBot.assertDatasets("P2D1");
   1812         mActivity.focusCell(2, 2);
   1813         sUiBot.assertDatasets("P2D1", "P2D2");
   1814 
   1815         mActivity.focusCell(4, 1);
   1816         sUiBot.assertDatasets("P4D1", "P4D2");
   1817         mActivity.focusCell(4, 2);
   1818         sUiBot.assertDatasets("P4D2");
   1819 
   1820         mActivity.focusCell(3, 2);
   1821         sUiBot.assertDatasets("P3D1", "P3D2");
   1822         mActivity.focusCell(3, 1);
   1823         sUiBot.assertDatasets("P3D1", "P3D2");
   1824 
   1825         /*
   1826          *  Finally, autofill and check results.
   1827          */
   1828         mActivity.focusCell(4, 1);
   1829         sUiBot.selectDataset("P4D2");
   1830         expectation4.assertAutoFilled();
   1831 
   1832         mActivity.focusCell(1, 1);
   1833         sUiBot.selectDataset("P1D1");
   1834         expectation1.assertAutoFilled();
   1835 
   1836         mActivity.focusCell(3, 1);
   1837         sUiBot.selectDataset("P3D1");
   1838         expectation3.assertAutoFilled();
   1839 
   1840         mActivity.focusCell(2, 2);
   1841         sUiBot.selectDataset("P2D2");
   1842         expectation2.assertAutoFilled();
   1843     }
   1844 
   1845     /**
   1846      * Tests scenario where each partition has more than one dataset - some authenticated and some
   1847      * not - but they overlap, i.e., some fields are present in more than one partition.
   1848      *
   1849      * <p>Whenever a new partition defines a field previously present in another partittion, that
   1850      * partition will "own" that field.
   1851      *
   1852      * <p>In the end, 4th partition will one all fields in 2 datasets; and this test cases picks
   1853      * the first.
   1854      */
   1855     @Test
   1856     public void testAutofillMultipleAuthDatasetsOverlapPickFirst() throws Exception {
   1857         autofillMultipleAuthDatasetsOverlapping(true);
   1858     }
   1859 
   1860     /**
   1861      * Tests scenario where each partition has more than one dataset - some authenticated and some
   1862      * not - but they overlap, i.e., some fields are present in more than one partition.
   1863      *
   1864      * <p>Whenever a new partition defines a field previously present in another partittion, that
   1865      * partition will "own" that field.
   1866      *
   1867      * <p>In the end, 4th partition will one all fields in 2 datasets; and this test cases picks
   1868      * the second.
   1869      */
   1870     @Test
   1871     public void testAutofillMultipleAuthDatasetsOverlapPickSecond() throws Exception {
   1872         autofillMultipleAuthDatasetsOverlapping(false);
   1873     }
   1874 
   1875     private void autofillMultipleAuthDatasetsOverlapping(boolean pickFirst) throws Exception {
   1876         // Set service.
   1877         enableService();
   1878 
   1879         // TODO: current API requires these fields...
   1880         final RemoteViews bogusPresentation = createPresentation("Whatever man, I'm not used...");
   1881         final String bogusValue = "Y U REQUIRE IT?";
   1882 
   1883         /**
   1884          * 1st partition.
   1885          */
   1886         // Set expectations.
   1887         final IntentSender auth12 = AuthenticationActivity.createSender(getContext(), 12);
   1888         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   1889                 .addDataset(new CannedDataset.Builder()
   1890                         .setField(ID_L1C1, "1l1c1")
   1891                         .setField(ID_L1C2, "1l1c2")
   1892                         .setPresentation(createPresentation("P1D1"))
   1893                         .build())
   1894                 .addDataset(new CannedDataset.Builder()
   1895                         .setAuthentication(auth12)
   1896                         .setField(ID_L1C1, bogusValue)
   1897                         .setPresentation(createPresentation("P1D2"))
   1898                         .build())
   1899                 .build();
   1900         sReplier.addResponse(response1);
   1901         // Trigger partition.
   1902         mActivity.focusCell(1, 1);
   1903         sReplier.getNextFillRequest();
   1904 
   1905         // Asserts proper datasets are shown on each field defined so far.
   1906         mActivity.focusCell(1, 1);
   1907         sUiBot.assertDatasets("P1D1", "P1D2");
   1908         mActivity.focusCell(1, 2);
   1909         sUiBot.assertDatasets("P1D1");
   1910 
   1911         /**
   1912          * 2nd partition.
   1913          */
   1914         // Set expectations.
   1915         final IntentSender auth21 = AuthenticationActivity.createSender(getContext(), 22,
   1916                 new CannedDataset.Builder()
   1917                     .setField(ID_L1C1, "2l1c1") // from previous partition
   1918                     .setField(ID_L2C1, "2l2c1")
   1919                     .setField(ID_L2C2, "2l2c2")
   1920                     .setPresentation(bogusPresentation)
   1921                     .build());
   1922         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   1923                 .addDataset(new CannedDataset.Builder()
   1924                         .setAuthentication(auth21)
   1925                         .setPresentation(createPresentation("P2D1"))
   1926                         .setField(ID_L1C1, bogusValue) // from previous partition
   1927                         .setField(ID_L2C1, bogusValue)
   1928                         .setField(ID_L2C2, bogusValue)
   1929                         .build())
   1930                 .addDataset(new CannedDataset.Builder()
   1931                         .setPresentation(createPresentation("P2D2"))
   1932                         .setField(ID_L2C2, "2L2C2")
   1933                         .build())
   1934                 .build();
   1935         sReplier.addResponse(response2);
   1936 
   1937         // Trigger partition.
   1938         mActivity.focusCell(2, 1);
   1939         sReplier.getNextFillRequest();
   1940 
   1941         // Asserts proper datasets are shown on each field defined so far.
   1942         mActivity.focusCell(1, 1);
   1943         sUiBot.assertDatasets("P2D1"); // changed
   1944         mActivity.focusCell(1, 2);
   1945         sUiBot.assertDatasets("P1D1");
   1946         mActivity.focusCell(2, 1);
   1947         sUiBot.assertDatasets("P2D1");
   1948         mActivity.focusCell(2, 2);
   1949         sUiBot.assertDatasets("P2D1", "P2D2");
   1950 
   1951         /**
   1952          * 3rd partition.
   1953          */
   1954         // Set expectations.
   1955         final IntentSender auth31 = AuthenticationActivity.createSender(getContext(), 31,
   1956                 new CannedDataset.Builder()
   1957                         .setField(ID_L1C2, "3l1c2") // from previous partition
   1958                         .setField(ID_L3C1, "3l3c1")
   1959                         .setField(ID_L3C2, "3l3c2")
   1960                         .setPresentation(bogusPresentation)
   1961                         .build());
   1962         final IntentSender auth32 = AuthenticationActivity.createSender(getContext(), 32);
   1963         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   1964                 .addDataset(new CannedDataset.Builder()
   1965                         .setAuthentication(auth31)
   1966                         .setPresentation(createPresentation("P3D1"))
   1967                         .setField(ID_L1C2, bogusValue) // from previous partition
   1968                         .setField(ID_L3C1, bogusValue)
   1969                         .setField(ID_L3C2, bogusValue)
   1970                         .build())
   1971                 .addDataset(new CannedDataset.Builder()
   1972                         .setAuthentication(auth32)
   1973                         .setPresentation(createPresentation("P3D2"))
   1974                         .setField(ID_L2C2, bogusValue) // from previous partition
   1975                         .setField(ID_L3C1, bogusValue)
   1976                         .setField(ID_L3C2, bogusValue)
   1977                         .build())
   1978                 .build();
   1979         sReplier.addResponse(response3);
   1980 
   1981         // Trigger partition.
   1982         mActivity.focusCell(3, 1);
   1983         sReplier.getNextFillRequest();
   1984 
   1985         // Asserts proper datasets are shown on each field defined so far.
   1986         mActivity.focusCell(1, 1);
   1987         sUiBot.assertDatasets("P2D1");
   1988         mActivity.focusCell(1, 2);
   1989         sUiBot.assertDatasets("P3D1"); // changed
   1990         mActivity.focusCell(2, 1);
   1991         sUiBot.assertDatasets("P2D1");
   1992         mActivity.focusCell(2, 2);
   1993         sUiBot.assertDatasets("P3D2"); // changed
   1994         mActivity.focusCell(3, 2);
   1995         sUiBot.assertDatasets("P3D1", "P3D2");
   1996         mActivity.focusCell(3, 1);
   1997         sUiBot.assertDatasets("P3D1", "P3D2");
   1998 
   1999         /**
   2000          * 4th partition.
   2001          */
   2002         // Set expectations.
   2003         final IntentSender auth41 = AuthenticationActivity.createSender(getContext(), 41,
   2004                 new CannedDataset.Builder()
   2005                         .setField(ID_L1C1, "4l1c1") // from previous partition
   2006                         .setField(ID_L1C2, "4l1c2") // from previous partition
   2007                         .setField(ID_L2C1, "4l2c1") // from previous partition
   2008                         .setField(ID_L2C2, "4l2c2") // from previous partition
   2009                         .setField(ID_L3C1, "4l3c1") // from previous partition
   2010                         .setField(ID_L3C2, "4l3c2") // from previous partition
   2011                         .setField(ID_L4C1, "4l4c1")
   2012                         .setPresentation(bogusPresentation)
   2013                         .build());
   2014         final IntentSender auth42 = AuthenticationActivity.createSender(getContext(), 42,
   2015                 new CannedDataset.Builder()
   2016                         .setField(ID_L1C1, "4L1C1") // from previous partition
   2017                         .setField(ID_L1C2, "4L1C2") // from previous partition
   2018                         .setField(ID_L2C1, "4L2C1") // from previous partition
   2019                         .setField(ID_L2C2, "4L2C2") // from previous partition
   2020                         .setField(ID_L3C1, "4L3C1") // from previous partition
   2021                         .setField(ID_L3C2, "4L3C2") // from previous partition
   2022                         .setField(ID_L1C1, "4L1C1") // from previous partition
   2023                         .setField(ID_L4C1, "4L4C1")
   2024                         .setField(ID_L4C2, "4L4C2")
   2025                         .setPresentation(bogusPresentation)
   2026                         .build());
   2027         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   2028                 .addDataset(new CannedDataset.Builder()
   2029                         .setAuthentication(auth41)
   2030                         .setPresentation(createPresentation("P4D1"))
   2031                         .setField(ID_L1C1, bogusValue) // from previous partition
   2032                         .setField(ID_L1C2, bogusValue) // from previous partition
   2033                         .setField(ID_L2C1, bogusValue) // from previous partition
   2034                         .setField(ID_L2C2, bogusValue) // from previous partition
   2035                         .setField(ID_L3C1, bogusValue) // from previous partition
   2036                         .setField(ID_L3C2, bogusValue) // from previous partition
   2037                         .setField(ID_L4C1, bogusValue)
   2038                         .build())
   2039                 .addDataset(new CannedDataset.Builder()
   2040                         .setAuthentication(auth42)
   2041                         .setPresentation(createPresentation("P4D2"))
   2042                         .setField(ID_L1C1, bogusValue) // from previous partition
   2043                         .setField(ID_L1C2, bogusValue) // from previous partition
   2044                         .setField(ID_L2C1, bogusValue) // from previous partition
   2045                         .setField(ID_L2C2, bogusValue) // from previous partition
   2046                         .setField(ID_L3C1, bogusValue) // from previous partition
   2047                         .setField(ID_L3C2, bogusValue) // from previous partition
   2048                         .setField(ID_L1C1, bogusValue) // from previous partition
   2049                         .setField(ID_L4C1, bogusValue)
   2050                         .setField(ID_L4C2, bogusValue)
   2051                         .build())
   2052                 .build();
   2053         sReplier.addResponse(response4);
   2054 
   2055         // Trigger partition.
   2056         mActivity.focusCell(4, 1);
   2057         sReplier.getNextFillRequest();
   2058 
   2059         // Asserts proper datasets are shown on each field defined so far.
   2060         mActivity.focusCell(1, 1);
   2061         sUiBot.assertDatasets("P4D1", "P4D2");
   2062         mActivity.focusCell(1, 2);
   2063         sUiBot.assertDatasets("P4D1", "P4D2");
   2064         mActivity.focusCell(2, 1);
   2065         sUiBot.assertDatasets("P4D1", "P4D2");
   2066         mActivity.focusCell(2, 2);
   2067         sUiBot.assertDatasets("P4D1", "P4D2");
   2068         mActivity.focusCell(3, 2);
   2069         sUiBot.assertDatasets("P4D1", "P4D2");
   2070         mActivity.focusCell(3, 1);
   2071         sUiBot.assertDatasets("P4D1", "P4D2");
   2072         mActivity.focusCell(4, 1);
   2073         sUiBot.assertDatasets("P4D1", "P4D2");
   2074         mActivity.focusCell(4, 2);
   2075         sUiBot.assertDatasets("P4D2");
   2076 
   2077         /*
   2078          * Finally, autofill and check results.
   2079          */
   2080         final FillExpectation expectation = mActivity.expectAutofill();
   2081         final String chosenOne;
   2082         if (pickFirst) {
   2083             expectation
   2084                 .onCell(1, 1, "4l1c1")
   2085                 .onCell(1, 2, "4l1c2")
   2086                 .onCell(2, 1, "4l2c1")
   2087                 .onCell(2, 2, "4l2c2")
   2088                 .onCell(3, 1, "4l3c1")
   2089                 .onCell(3, 2, "4l3c2")
   2090                 .onCell(4, 1, "4l4c1");
   2091             chosenOne = "P4D1";
   2092         } else {
   2093             expectation
   2094                 .onCell(1, 1, "4L1C1")
   2095                 .onCell(1, 2, "4L1C2")
   2096                 .onCell(2, 1, "4L2C1")
   2097                 .onCell(2, 2, "4L2C2")
   2098                 .onCell(3, 1, "4L3C1")
   2099                 .onCell(3, 2, "4L3C2")
   2100                 .onCell(4, 1, "4L4C1")
   2101                 .onCell(4, 2, "4L4C2");
   2102             chosenOne = "P4D2";
   2103         }
   2104 
   2105           mActivity.focusCell(4, 1);
   2106           sUiBot.selectDataset(chosenOne);
   2107           expectation.assertAutoFilled();
   2108     }
   2109 
   2110     @Test
   2111     public void testAutofillAllResponsesAuthenticated() throws Exception {
   2112         // Set service.
   2113         enableService();
   2114 
   2115         // Prepare 1st partition.
   2116         final IntentSender auth1 = AuthenticationActivity.createSender(getContext(), 1,
   2117                 new CannedFillResponse.Builder()
   2118                         .addDataset(new CannedDataset.Builder()
   2119                                 .setPresentation(createPresentation("Partition 1"))
   2120                                 .setField(ID_L1C1, "l1c1")
   2121                                 .setField(ID_L1C2, "l1c2")
   2122                                 .build())
   2123                         .build());
   2124         final CannedFillResponse response1 = new CannedFillResponse.Builder()
   2125                 .setPresentation(createPresentation("Auth 1"))
   2126                 .setAuthentication(auth1, ID_L1C1, ID_L1C2)
   2127                 .build();
   2128         sReplier.addResponse(response1);
   2129         final FillExpectation expectation1 = mActivity.expectAutofill()
   2130                 .onCell(1, 1, "l1c1")
   2131                 .onCell(1, 2, "l1c2");
   2132         mActivity.focusCell(1, 1);
   2133         sReplier.getNextFillRequest();
   2134 
   2135         sUiBot.assertDatasets("Auth 1");
   2136 
   2137         // Prepare 2nd partition.
   2138         final IntentSender auth2 = AuthenticationActivity.createSender(getContext(), 2,
   2139                 new CannedFillResponse.Builder()
   2140                         .addDataset(new CannedDataset.Builder()
   2141                                 .setPresentation(createPresentation("Partition 2"))
   2142                                 .setField(ID_L2C1, "l2c1")
   2143                                 .setField(ID_L2C2, "l2c2")
   2144                                 .build())
   2145                         .build());
   2146         final CannedFillResponse response2 = new CannedFillResponse.Builder()
   2147                 .setPresentation(createPresentation("Auth 2"))
   2148                 .setAuthentication(auth2, ID_L2C1, ID_L2C2)
   2149                 .build();
   2150         sReplier.addResponse(response2);
   2151         final FillExpectation expectation2 = mActivity.expectAutofill()
   2152                 .onCell(2, 1, "l2c1")
   2153                 .onCell(2, 2, "l2c2");
   2154         mActivity.focusCell(2, 1);
   2155         sReplier.getNextFillRequest();
   2156 
   2157         sUiBot.assertDatasets("Auth 2");
   2158 
   2159         // Prepare 3rd partition.
   2160         final IntentSender auth3 = AuthenticationActivity.createSender(getContext(), 3,
   2161                 new CannedFillResponse.Builder()
   2162                         .addDataset(new CannedDataset.Builder()
   2163                                 .setPresentation(createPresentation("Partition 3"))
   2164                                 .setField(ID_L3C1, "l3c1")
   2165                                 .setField(ID_L3C2, "l3c2")
   2166                                 .build())
   2167                         .build());
   2168         final CannedFillResponse response3 = new CannedFillResponse.Builder()
   2169                 .setPresentation(createPresentation("Auth 3"))
   2170                 .setAuthentication(auth3, ID_L3C1, ID_L3C2)
   2171                 .build();
   2172         sReplier.addResponse(response3);
   2173         final FillExpectation expectation3 = mActivity.expectAutofill()
   2174                 .onCell(3, 1, "l3c1")
   2175                 .onCell(3, 2, "l3c2");
   2176         mActivity.focusCell(3, 1);
   2177         sReplier.getNextFillRequest();
   2178 
   2179         sUiBot.assertDatasets("Auth 3");
   2180 
   2181         // Prepare 4th partition.
   2182         final IntentSender auth4 = AuthenticationActivity.createSender(getContext(), 4,
   2183                 new CannedFillResponse.Builder()
   2184                         .addDataset(new CannedDataset.Builder()
   2185                                 .setPresentation(createPresentation("Partition 4"))
   2186                                 .setField(ID_L4C1, "l4c1")
   2187                                 .setField(ID_L4C2, "l4c2")
   2188                                 .build())
   2189                         .build());
   2190         final CannedFillResponse response4 = new CannedFillResponse.Builder()
   2191                 .setPresentation(createPresentation("Auth 4"))
   2192                 .setAuthentication(auth4, ID_L4C1, ID_L4C2)
   2193                 .build();
   2194         sReplier.addResponse(response4);
   2195         final FillExpectation expectation4 = mActivity.expectAutofill()
   2196                 .onCell(4, 1, "l4c1")
   2197                 .onCell(4, 2, "l4c2");
   2198         mActivity.focusCell(4, 1);
   2199         sReplier.getNextFillRequest();
   2200 
   2201         sUiBot.assertDatasets("Auth 4");
   2202 
   2203         // Now play around the focus to make sure they still display the right values.
   2204 
   2205         mActivity.focusCell(1, 2);
   2206         sUiBot.assertDatasets("Auth 1");
   2207         mActivity.focusCell(1, 1);
   2208         sUiBot.assertDatasets("Auth 1");
   2209 
   2210         mActivity.focusCell(3, 1);
   2211         sUiBot.assertDatasets("Auth 3");
   2212         mActivity.focusCell(3, 2);
   2213         sUiBot.assertDatasets("Auth 3");
   2214 
   2215         mActivity.focusCell(2, 1);
   2216         sUiBot.assertDatasets("Auth 2");
   2217         mActivity.focusCell(4, 2);
   2218         sUiBot.assertDatasets("Auth 4");
   2219 
   2220         mActivity.focusCell(2, 2);
   2221         sUiBot.assertDatasets("Auth 2");
   2222         mActivity.focusCell(4, 1);
   2223         sUiBot.assertDatasets("Auth 4");
   2224 
   2225         // Finally, autofill and check them.
   2226         mActivity.focusCell(2, 1);
   2227         sUiBot.selectDataset("Auth 2");
   2228         sUiBot.selectDataset("Partition 2");
   2229         expectation2.assertAutoFilled();
   2230 
   2231         mActivity.focusCell(4, 1);
   2232         sUiBot.selectDataset("Auth 4");
   2233         sUiBot.selectDataset("Partition 4");
   2234         expectation4.assertAutoFilled();
   2235 
   2236         mActivity.focusCell(3, 1);
   2237         sUiBot.selectDataset("Auth 3");
   2238         sUiBot.selectDataset("Partition 3");
   2239         expectation3.assertAutoFilled();
   2240 
   2241         mActivity.focusCell(1, 1);
   2242         sUiBot.selectDataset("Auth 1");
   2243         sUiBot.selectDataset("Partition 1");
   2244         expectation1.assertAutoFilled();
   2245     }
   2246 
   2247     @Test
   2248     public void testNoMorePartitionsAfterLimitReached() throws Exception {
   2249         final int maxBefore = getMaxPartitions();
   2250         try {
   2251             setMaxPartitions(1);
   2252             // Set service.
   2253             enableService();
   2254 
   2255             // Prepare 1st partition.
   2256             final CannedFillResponse response1 = new CannedFillResponse.Builder()
   2257                     .addDataset(new CannedDataset.Builder()
   2258                             .setField(ID_L1C1, "l1c1", createPresentation("l1c1"))
   2259                             .setField(ID_L1C2, "l1c2", createPresentation("l1c2"))
   2260                             .build())
   2261                     .build();
   2262             sReplier.addResponse(response1);
   2263 
   2264             // Trigger autofill.
   2265             mActivity.focusCell(1, 1);
   2266             sReplier.getNextFillRequest();
   2267 
   2268             // Make sure UI is shown, but don't tap it.
   2269             sUiBot.assertDatasets("l1c1");
   2270             mActivity.focusCell(1, 2);
   2271             sUiBot.assertDatasets("l1c2");
   2272 
   2273             // Prepare 2nd partition.
   2274             final CannedFillResponse response2 = new CannedFillResponse.Builder()
   2275                     .addDataset(new CannedDataset.Builder()
   2276                             .setField(ID_L2C1, "l2c1", createPresentation("l2c1"))
   2277                             .build())
   2278                     .build();
   2279             sReplier.addResponse(response2);
   2280 
   2281             // Trigger autofill on 2nd partition.
   2282             mActivity.focusCell(2, 1);
   2283 
   2284             // Make sure it was ignored.
   2285             sUiBot.assertNoDatasets();
   2286 
   2287             // Make sure 1st partition is still working.
   2288             mActivity.focusCell(1, 2);
   2289             sUiBot.assertDatasets("l1c2");
   2290             mActivity.focusCell(1, 1);
   2291             sUiBot.assertDatasets("l1c1");
   2292 
   2293             // Prepare 3rd partition.
   2294             final CannedFillResponse response3 = new CannedFillResponse.Builder()
   2295                     .addDataset(new CannedDataset.Builder()
   2296                             .setField(ID_L3C2, "l3c2", createPresentation("l3c2"))
   2297                             .build())
   2298                     .build();
   2299             sReplier.addResponse(response3);
   2300             // Trigger autofill on 3rd partition.
   2301             mActivity.focusCell(3, 2);
   2302 
   2303             // Make sure it was ignored.
   2304             sUiBot.assertNoDatasets();
   2305 
   2306             // Make sure 1st partition is still working...
   2307             mActivity.focusCell(1, 2);
   2308             sUiBot.assertDatasets("l1c2");
   2309             mActivity.focusCell(1, 1);
   2310             sUiBot.assertDatasets("l1c1");
   2311 
   2312             //...and can be autofilled.
   2313             final FillExpectation expectation = mActivity.expectAutofill()
   2314                     .onCell(1, 1, "l1c1");
   2315             sUiBot.selectDataset("l1c1");
   2316             expectation.assertAutoFilled();
   2317         } finally {
   2318             setMaxPartitions(maxBefore);
   2319         }
   2320     }
   2321 }
   2322