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 17 package android.autofillservice.cts; 18 19 import static android.autofillservice.cts.Helper.findViewByAutofillHint; 20 import static android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO; 21 import static android.view.View.IMPORTANT_FOR_AUTOFILL_NO; 22 import static android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS; 23 import static android.view.View.IMPORTANT_FOR_AUTOFILL_YES; 24 import static android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS; 25 26 import static com.google.common.truth.Truth.assertThat; 27 28 import android.content.Context; 29 import android.os.Bundle; 30 import android.util.AttributeSet; 31 import android.view.View; 32 import android.widget.EditText; 33 import android.widget.ImageView; 34 import android.widget.LinearLayout; 35 36 /** 37 * An activity containing mostly widgets that should be removed from an auto-fill structure to 38 * optimize it. 39 */ 40 public class FatActivity extends AbstractAutoFillActivity { 41 42 static final String ID_CAPTCHA = "captcha"; 43 static final String ID_INPUT = "input"; 44 static final String ID_INPUT_CONTAINER = "input_container"; 45 static final String ID_IMAGE = "image"; 46 static final String ID_IMPORTANT_IMAGE = "important_image"; 47 static final String ID_ROOT = "root"; 48 49 static final String ID_NOT_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS = 50 "not_important_container_excluding_descendants"; 51 static final String ID_NOT_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS_CHILD = 52 "not_important_container_excluding_descendants_child"; 53 static final String ID_NOT_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS_GRAND_CHILD = 54 "not_important_container_excluding_descendants_grand_child"; 55 56 static final String ID_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS = 57 "important_container_excluding_descendants"; 58 static final String ID_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS_CHILD = 59 "important_container_excluding_descendants_child"; 60 static final String ID_IMPORTANT_CONTAINER_EXCLUDING_DESCENDANTS_GRAND_CHILD = 61 "important_container_excluding_descendants_grand_child"; 62 63 static final String ID_NOT_IMPORTANT_CONTAINER_MIXED_DESCENDANTS = 64 "not_important_container_mixed_descendants"; 65 static final String ID_NOT_IMPORTANT_CONTAINER_MIXED_DESCENDANTS_CHILD = 66 "not_important_container_mixed_descendants_child"; 67 static final String ID_NOT_IMPORTANT_CONTAINER_MIXED_DESCENDANTS_GRAND_CHILD = 68 "not_important_container_mixed_descendants_grand_child"; 69 70 private LinearLayout mRoot; 71 private EditText mCaptcha; 72 private EditText mInput; 73 private ImageView mImage; 74 private ImageView mImportantImage; 75 76 private View mNotImportantContainerExcludingDescendants; 77 private View mNotImportantContainerExcludingDescendantsChild; 78 private View mNotImportantContainerExcludingDescendantsGrandChild; 79 80 private View mImportantContainerExcludingDescendants; 81 private View mImportantContainerExcludingDescendantsChild; 82 private View mImportantContainerExcludingDescendantsGrandChild; 83 84 private View mNotImportantContainerMixedDescendants; 85 private View mNotImportantContainerMixedDescendantsChild; 86 private View mNotImportantContainerMixedDescendantsGrandChild; 87 88 private MyView mViewWithAutofillHints; 89 90 @Override onCreate(Bundle savedInstanceState)91 protected void onCreate(Bundle savedInstanceState) { 92 super.onCreate(savedInstanceState); 93 94 setContentView(R.layout.fat_activity); 95 96 mRoot = findViewById(R.id.root); 97 mCaptcha = findViewById(R.id.captcha); 98 mInput = findViewById(R.id.input); 99 mImage = findViewById(R.id.image); 100 mImportantImage = findViewById(R.id.important_image); 101 102 mNotImportantContainerExcludingDescendants = findViewById( 103 R.id.not_important_container_excluding_descendants); 104 mNotImportantContainerExcludingDescendantsChild = findViewById( 105 R.id.not_important_container_excluding_descendants_child); 106 mNotImportantContainerExcludingDescendantsGrandChild = findViewById( 107 R.id.not_important_container_excluding_descendants_grand_child); 108 109 mImportantContainerExcludingDescendants = findViewById( 110 R.id.important_container_excluding_descendants); 111 mImportantContainerExcludingDescendantsChild = findViewById( 112 R.id.important_container_excluding_descendants_child); 113 mImportantContainerExcludingDescendantsGrandChild = findViewById( 114 R.id.important_container_excluding_descendants_grand_child); 115 116 mNotImportantContainerMixedDescendants = findViewById( 117 R.id.not_important_container_mixed_descendants); 118 mNotImportantContainerMixedDescendantsChild = findViewById( 119 R.id.not_important_container_mixed_descendants_child); 120 mNotImportantContainerMixedDescendantsGrandChild = findViewById( 121 R.id.not_important_container_mixed_descendants_grand_child); 122 123 mViewWithAutofillHints = (MyView) findViewByAutofillHint(this, "importantAmI"); 124 assertThat(mViewWithAutofillHints).isNotNull(); 125 126 // Validation check for importantForAutofill modes 127 assertThat(mRoot.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_AUTO); 128 assertThat(mInput.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_YES); 129 assertThat(mCaptcha.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_NO); 130 assertThat(mImage.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_NO); 131 assertThat(mImportantImage.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_YES); 132 133 assertThat(mNotImportantContainerExcludingDescendants.getImportantForAutofill()) 134 .isEqualTo(IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS); 135 assertThat(mNotImportantContainerExcludingDescendantsChild.getImportantForAutofill()) 136 .isEqualTo(IMPORTANT_FOR_AUTOFILL_YES); 137 assertThat(mNotImportantContainerExcludingDescendantsGrandChild.getImportantForAutofill()) 138 .isEqualTo(IMPORTANT_FOR_AUTOFILL_AUTO); 139 140 assertThat(mImportantContainerExcludingDescendants.getImportantForAutofill()) 141 .isEqualTo(IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS); 142 assertThat(mImportantContainerExcludingDescendantsChild.getImportantForAutofill()) 143 .isEqualTo(IMPORTANT_FOR_AUTOFILL_YES); 144 assertThat(mImportantContainerExcludingDescendantsGrandChild.getImportantForAutofill()) 145 .isEqualTo(IMPORTANT_FOR_AUTOFILL_AUTO); 146 147 assertThat(mNotImportantContainerMixedDescendants.getImportantForAutofill()) 148 .isEqualTo(IMPORTANT_FOR_AUTOFILL_NO); 149 assertThat(mNotImportantContainerMixedDescendantsChild.getImportantForAutofill()) 150 .isEqualTo(IMPORTANT_FOR_AUTOFILL_YES); 151 assertThat(mNotImportantContainerMixedDescendantsGrandChild.getImportantForAutofill()) 152 .isEqualTo(IMPORTANT_FOR_AUTOFILL_NO); 153 154 assertThat(mViewWithAutofillHints.getImportantForAutofill()) 155 .isEqualTo(IMPORTANT_FOR_AUTOFILL_AUTO); 156 assertThat(mViewWithAutofillHints.isImportantForAutofill()).isTrue(); 157 } 158 159 /** 160 * Visits the {@code input} in the UiThread. 161 */ onInput(Visitor<EditText> v)162 void onInput(Visitor<EditText> v) { 163 syncRunOnUiThread(() -> { 164 v.visit(mInput); 165 }); 166 } 167 168 /** 169 * Custom view that defines an autofill type so autofill hints are set on {@code ViewNode}. 170 */ 171 public static class MyView extends View { MyView(Context context, AttributeSet attrs)172 public MyView(Context context, AttributeSet attrs) { 173 super(context, attrs); 174 } 175 176 @Override getAutofillType()177 public int getAutofillType() { 178 return AUTOFILL_TYPE_TEXT; 179 } 180 } 181 } 182