118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/* 218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Copyright (C) 2012 The Android Open Source Project 318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * you may not use this file except in compliance with the License. 618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You may obtain a copy of the License at 718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Unless required by applicable law or agreed to in writing, software 1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See the License for the specific language governing permissions and 1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * limitations under the License. 1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.uiautomator.core; 1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.SparseArray; 2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo; 2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.regex.Pattern; 2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/** 2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Specifies the elements in the layout hierarchy for tests to target, filtered 2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by properties such as text value, content-description, class name, and state 2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * information. You can also target an element by its location in a layout 2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * hierarchy. 2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic class UiSelector { 3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_NIL = 0; 3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_TEXT = 1; 3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_START_TEXT = 2; 3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CONTAINS_TEXT = 3; 3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CLASS = 4; 3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_DESCRIPTION = 5; 3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_START_DESCRIPTION = 6; 3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CONTAINS_DESCRIPTION = 7; 4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_INDEX = 8; 4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_INSTANCE = 9; 4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_ENABLED = 10; 4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_FOCUSED = 11; 4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_FOCUSABLE = 12; 4518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_SCROLLABLE = 13; 4618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CLICKABLE = 14; 4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CHECKED = 15; 4818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_SELECTED = 16; 4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_ID = 17; 5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_PACKAGE_NAME = 18; 5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CHILD = 19; 5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CONTAINER = 20; 5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_PATTERN = 21; 5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_PARENT = 22; 5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_COUNT = 23; 5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_LONG_CLICKABLE = 24; 5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_TEXT_REGEX = 25; 5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CLASS_REGEX = 26; 5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_DESCRIPTION_REGEX = 27; 6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_PACKAGE_NAME_REGEX = 28; 6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_RESOURCE_ID = 29; 6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_CHECKABLE = 30; 6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static final int SELECTOR_RESOURCE_ID_REGEX = 31; 6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>(); 6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector() { 7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector(UiSelector selector) { 7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mSelectorAttributes = selector.cloneSelector().mSelectorAttributes; 7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu protected UiSelector cloneSelector() { 8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector ret = new UiSelector(); 8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret.mSelectorAttributes = mSelectorAttributes.clone(); 8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (hasChildSelector()) 8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector())); 8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (hasParentSelector()) 8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector())); 8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (hasPatternSelector()) 8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector())); 8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ret; 9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static UiSelector patternBuilder(UiSelector selector) { 9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (!selector.hasPatternSelector()) { 9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector().patternSelector(selector); 9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return selector; 9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu static UiSelector patternBuilder(UiSelector container, UiSelector pattern) { 10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector( 10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu new UiSelector().containerSelector(container).patternSelector(pattern)); 10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the visible text displayed 10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * in a widget (for example, the text label to launch an app). 10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The text for the element must match exactly with the string in your input 10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * argument. Matching is case-sensitive. 11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param text Value to match 11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector text(String text) { 11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_TEXT, text); 11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the visible text displayed in a layout 12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * element, using a regular expression. 12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The text in the widget must match exactly with the string in your 12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * input argument. 12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param regex a regular expression 12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector textMatches(String regex) { 13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_TEXT_REGEX, Pattern.compile(regex)); 13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match visible text in a widget that is 13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * prefixed by the text parameter. 13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The matching is case-insensitive. 13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param text Value to match 14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 14418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector textStartsWith(String text) { 14518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_START_TEXT, text); 14618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 14718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 14818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 14918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the visible text in a widget 15018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * where the visible text must contain the string in your input argument. 15118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 15218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The matching is case-sensitive. 15318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 15418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param text Value to match 15518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 15618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 15718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 15818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector textContains(String text) { 15918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CONTAINS_TEXT, text); 16018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 16118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 16218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 16318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the class property 16418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for a widget (for example, "android.widget.Button"). 16518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 16618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param className Value to match 16718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 16818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 16918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 17018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector className(String className) { 17118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CLASS, className); 17218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 17318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 17418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 17518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the class property 17618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for a widget, using a regular expression. 17718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 17818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param regex a regular expression 17918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 18018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 18118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 18218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector classNameMatches(String regex) { 18318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CLASS_REGEX, Pattern.compile(regex)); 18418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 18518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 18618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 18718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the class property 18818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for a widget (for example, "android.widget.Button"). 18918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 19018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param type type 19118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 19218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 19318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 19418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public <T> UiSelector className(Class<T> type) { 19518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CLASS, type.getName()); 19618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 19718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 19818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 19918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the content-description 20018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * property for a widget. 20118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 20218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The content-description is typically used 20318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by the Android Accessibility framework to 20418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * provide an audio prompt for the widget when 20518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the widget is selected. The content-description 20618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for the widget must match exactly 20718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * with the string in your input argument. 20818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 20918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Matching is case-sensitive. 21018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 21118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param desc Value to match 21218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 21318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 21418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 21518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector description(String desc) { 21618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_DESCRIPTION, desc); 21718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 21818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 21918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 22018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the content-description 22118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * property for a widget. 22218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 22318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The content-description is typically used 22418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by the Android Accessibility framework to 22518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * provide an audio prompt for the widget when 22618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the widget is selected. The content-description 22718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for the widget must match exactly 22818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * with the string in your input argument. 22918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 23018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param regex a regular expression 23118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 23218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 23318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 23418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector descriptionMatches(String regex) { 23518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_DESCRIPTION_REGEX, Pattern.compile(regex)); 23618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 23718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 23818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 23918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the content-description 24018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * property for a widget. 24118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 24218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The content-description is typically used 24318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by the Android Accessibility framework to 24418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * provide an audio prompt for the widget when 24518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the widget is selected. The content-description 24618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for the widget must start 24718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * with the string in your input argument. 24818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 24918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Matching is case-insensitive. 25018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 25118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param desc Value to match 25218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 25318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 25418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 25518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector descriptionStartsWith(String desc) { 25618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_START_DESCRIPTION, desc); 25718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 25818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 25918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 26018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the content-description 26118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * property for a widget. 26218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 26318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The content-description is typically used 26418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by the Android Accessibility framework to 26518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * provide an audio prompt for the widget when 26618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the widget is selected. The content-description 26718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * for the widget must contain 26818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the string in your input argument. 26918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 27018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Matching is case-insensitive. 27118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 27218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param desc Value to match 27318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 27418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 27518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 27618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector descriptionContains(String desc) { 27718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc); 27818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 27918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 28018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 28118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the given resource ID. 28218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 28318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param id Value to match 28418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 28518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 28618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 28718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector resourceId(String id) { 28818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_RESOURCE_ID, id); 28918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 29018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 29118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 29218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the resource ID 29318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * of the widget, using a regular expression. 29418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 29518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param regex a regular expression 29618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 29718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 29818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 29918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector resourceIdMatches(String regex) { 30018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_RESOURCE_ID_REGEX, Pattern.compile(regex)); 30118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 30218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 30318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 30418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the widget by its node 30518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * index in the layout hierarchy. 30618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 30718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The index value must be 0 or greater. 30818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 30918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Using the index can be unreliable and should only 31018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * be used as a last resort for matching. Instead, 31118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * consider using the {@link #instance(int)} method. 31218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 31318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param index Value to match 31418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 31518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 31618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 31718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector index(final int index) { 31818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_INDEX, index); 31918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 32018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 32118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 32218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the 32318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * widget by its instance number. 32418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 32518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The instance value must be 0 or greater, where 32618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the first instance is 0. 32718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 32818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * For example, to simulate a user click on 32918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the third image that is enabled in a UI screen, you 33018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * could specify a a search criteria where the instance is 33118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 2, the {@link #className(String)} matches the image 33218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * widget class, and {@link #enabled(boolean)} is true. 33318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The code would look like this: 33418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * <code> 33518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * new UiSelector().className("android.widget.ImageView") 33618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * .enabled(true).instance(2); 33718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * </code> 33818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 33918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param instance Value to match 34018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 34118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 34218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 34318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector instance(final int instance) { 34418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_INSTANCE, instance); 34518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 34618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 34718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 34818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are enabled. 34918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 35018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 35118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 35218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 35318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 35418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 35518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 35618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 35718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 35818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 35918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 36018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 36118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 36218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector enabled(boolean val) { 36318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_ENABLED, val); 36418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 36518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 36618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 36718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that have focus. 36818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 36918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 37018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 37118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 37218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 37318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 37418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 37518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 37618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 37718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 37818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 37918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 38018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 38118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector focused(boolean val) { 38218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_FOCUSED, val); 38318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 38418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 38518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 38618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are focusable. 38718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 38818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 38918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 39018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 39118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 39218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 39318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 39418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 39518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 39618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 39718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 39818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 39918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 40018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector focusable(boolean val) { 40118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_FOCUSABLE, val); 40218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 40318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 40418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 40518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are scrollable. 40618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 40718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 40818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 40918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 41018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 41118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 41218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 41318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 41418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 41518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 41618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 41718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 41818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 41918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector scrollable(boolean val) { 42018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_SCROLLABLE, val); 42118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 42218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 42318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 42418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that 42518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * are currently selected. 42618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 42718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 42818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 42918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 43018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 43118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 43218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 43318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 43418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 43518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 43618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 43718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 43818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 43918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector selected(boolean val) { 44018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_SELECTED, val); 44118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 44218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 44318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 44418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that 44518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * are currently checked (usually for checkboxes). 44618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 44718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 44818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 44918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 45018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 45118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 45218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 45318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 45418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 45518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 45618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 45718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 45818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 45918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector checked(boolean val) { 46018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CHECKED, val); 46118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 46218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 46318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 46418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are clickable. 46518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 46618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 46718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 46818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 46918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 47018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 47118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 47218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 47318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 47418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 47518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 47618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 47718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 47818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector clickable(boolean val) { 47918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CLICKABLE, val); 48018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 48118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 48218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 48318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are checkable. 48418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 48518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 48618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 48718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 48818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 48918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 49018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 49118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 49218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 49318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 49418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 49518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 49618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 49718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector checkable(boolean val) { 49818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CHECKABLE, val); 49918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 50018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 50118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 50218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match widgets that are long-clickable. 50318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 50418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Typically, using this search criteria alone is not useful. 50518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You should also include additional criteria, such as text, 50618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * content-description, or the class name for a widget. 50718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 50818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If no other search criteria is specified, and there is more 50918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * than one matching widget, the first widget in the tree 51018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * is selected. 51118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 51218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param val Value to match 51318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 51418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 51518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 51618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector longClickable(boolean val) { 51718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_LONG_CLICKABLE, val); 51818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 51918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 52018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 52118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Adds a child UiSelector criteria to this selector. 52218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 52318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Use this selector to narrow the search scope to 52418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * child widgets under a specific parent widget. 52518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 52618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param selector 52718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with this added search criterion 52818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 52918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 53018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector childSelector(UiSelector selector) { 53118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CHILD, selector); 53218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 53318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 53418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiSelector patternSelector(UiSelector selector) { 53518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_PATTERN, selector); 53618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 53718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 53818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiSelector containerSelector(UiSelector selector) { 53918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_CONTAINER, selector); 54018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 54118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 54218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 54318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Adds a child UiSelector criteria to this selector which is used to 54418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * start search from the parent widget. 54518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 54618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Use this selector to narrow the search scope to 54718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * sibling widgets as well all child widgets under a parent. 54818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 54918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param selector 55018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with this added search criterion 55118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 55218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 55318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector fromParent(UiSelector selector) { 55418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_PARENT, selector); 55518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 55618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 55718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 55818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the package name 55918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * of the application that contains the widget. 56018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 56118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param name Value to match 56218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 56318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 56418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 56518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector packageName(String name) { 56618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_PACKAGE_NAME, name); 56718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 56918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 57018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Set the search criteria to match the package name 57118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * of the application that contains the widget. 57218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 57318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param regex a regular expression 57418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiSelector with the specified search criteria 57518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 57618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 57718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public UiSelector packageNameMatches(String regex) { 57818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, Pattern.compile(regex)); 57918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 58018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 58118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 58218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Building a UiSelector always returns a new UiSelector and never modifies the 58318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * existing UiSelector being used. 58418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 58518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiSelector buildSelector(int selectorId, Object selectorValue) { 58618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector selector = new UiSelector(this); 58718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT) 58818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue); 58918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu else 59018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu selector.mSelectorAttributes.put(selectorId, selectorValue); 59118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return selector; 59218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 59318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 59418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 59518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Selectors may have a hierarchy defined by specifying child nodes to be matched. 59618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * It is not necessary that every selector have more than one level. A selector 59718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * can also be a single level referencing only one node. In such cases the return 59818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * it null. 59918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 60018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return a child selector if one exists. Else null if this selector does not 60118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * reference child node. 60218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 60318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector getChildSelector() { 60418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null); 60518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (selector != null) 60618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector(selector); 60718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return null; 60818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 60918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 61018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector getPatternSelector() { 61118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector selector = 61218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null); 61318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (selector != null) 61418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector(selector); 61518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return null; 61618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 61718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 61818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector getContainerSelector() { 61918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector selector = 62018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null); 62118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (selector != null) 62218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector(selector); 62318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return null; 62418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 62518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 62618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector getParentSelector() { 62718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector selector = 62818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null); 62918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (selector != null) 63018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return new UiSelector(selector); 63118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return null; 63218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 63318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 63418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int getInstance() { 63518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getInt(UiSelector.SELECTOR_INSTANCE); 63618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 63718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 63818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String getString(int criterion) { 63918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return (String) mSelectorAttributes.get(criterion, null); 64018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 64118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 64218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean getBoolean(int criterion) { 64318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return (Boolean) mSelectorAttributes.get(criterion, false); 64418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 64518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 64618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int getInt(int criterion) { 64718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return (Integer) mSelectorAttributes.get(criterion, 0); 64818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 64918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 65018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Pattern getPattern(int criterion) { 65118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return (Pattern) mSelectorAttributes.get(criterion, null); 65218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 65318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 65418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean isMatchFor(AccessibilityNodeInfo node, int index) { 65518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int size = mSelectorAttributes.size(); 65618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for(int x = 0; x < size; x++) { 65718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu CharSequence s = null; 65818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int criterion = mSelectorAttributes.keyAt(x); 65918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu switch(criterion) { 66018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_INDEX: 66118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (index != this.getInt(criterion)) 66218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 66318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 66418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CHECKED: 66518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isChecked() != getBoolean(criterion)) { 66618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 66718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 66818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 66918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CLASS: 67018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getClassName(); 67118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 67218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 67318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 67418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 67518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CLASS_REGEX: 67618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getClassName(); 67718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !getPattern(criterion).matcher(s).matches()) { 67818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 67918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 68018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 68118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CLICKABLE: 68218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isClickable() != getBoolean(criterion)) { 68318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 68418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 68518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 68618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CHECKABLE: 68718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isCheckable() != getBoolean(criterion)) { 68818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 68918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 69018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 69118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_LONG_CLICKABLE: 69218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isLongClickable() != getBoolean(criterion)) { 69318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 69418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 69518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 69618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CONTAINS_DESCRIPTION: 69718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getContentDescription(); 69818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().toLowerCase() 69918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .contains(getString(criterion).toLowerCase())) { 70018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 70118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 70218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 70318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_START_DESCRIPTION: 70418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getContentDescription(); 70518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().toLowerCase() 70618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 70718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 70818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 70918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 71018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_DESCRIPTION: 71118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getContentDescription(); 71218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 71318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 71418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 71518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 71618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_DESCRIPTION_REGEX: 71718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getContentDescription(); 71818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !getPattern(criterion).matcher(s).matches()) { 71918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 72018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 72118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 72218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_CONTAINS_TEXT: 72318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getText(); 72418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().toLowerCase() 72518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .contains(getString(criterion).toLowerCase())) { 72618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 72718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 72818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 72918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_START_TEXT: 73018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getText(); 73118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().toLowerCase() 73218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 73318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 73418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 73518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 73618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_TEXT: 73718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getText(); 73818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 73918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 74018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 74118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 74218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_TEXT_REGEX: 74318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getText(); 74418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !getPattern(criterion).matcher(s).matches()) { 74518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 74618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 74718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 74818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_ENABLED: 74918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isEnabled() != getBoolean(criterion)) { 75018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 75118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 75218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 75318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_FOCUSABLE: 75418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isFocusable() != getBoolean(criterion)) { 75518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 75618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 75718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 75818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_FOCUSED: 75918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isFocused() != getBoolean(criterion)) { 76018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 76118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 76218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 76318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_ID: 76418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; //TODO: do we need this for AccessibilityNodeInfo.id? 76518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_PACKAGE_NAME: 76618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getPackageName(); 76718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 76818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 76918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 77018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 77118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_PACKAGE_NAME_REGEX: 77218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getPackageName(); 77318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !getPattern(criterion).matcher(s).matches()) { 77418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 77518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 77618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 77718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_SCROLLABLE: 77818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isScrollable() != getBoolean(criterion)) { 77918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 78018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 78118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 78218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_SELECTED: 78318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (node.isSelected() != getBoolean(criterion)) { 78418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 78518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 78618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 78718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_RESOURCE_ID: 78818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getViewIdResourceName(); 78918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 79018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 79118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 79218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 79318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case UiSelector.SELECTOR_RESOURCE_ID_REGEX: 79418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu s = node.getViewIdResourceName(); 79518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (s == null || !getPattern(criterion).matcher(s).matches()) { 79618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 79718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 79818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 79918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 80018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 80118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return matchOrUpdateInstance(); 80218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 80318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 80418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private boolean matchOrUpdateInstance() { 80518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int currentSelectorCounter = 0; 80618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int currentSelectorInstance = 0; 80718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 80818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // matched attributes - now check for matching instance number 80918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) >= 0) { 81018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu currentSelectorInstance = 81118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE); 81218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 81318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 81418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // instance is required. Add count if not already counting 81518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) >= 0) { 81618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT); 81718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 81818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 81918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // Verify 82018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (currentSelectorInstance == currentSelectorCounter) { 82118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 82218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 82318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // Update count 82418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (currentSelectorInstance > currentSelectorCounter) { 82518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter); 82618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 82718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 82818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 82918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 83018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 83118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Leaf selector indicates no more child or parent selectors 83218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * are declared in the this selector. 83318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if is leaf. 83418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 83518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean isLeaf() { 83618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 && 83718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 83818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 83918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 84018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 84118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 84218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 84318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean hasChildSelector() { 84418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) { 84518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 84618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 84718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 84818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 84918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 85018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean hasPatternSelector() { 85118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) { 85218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 85318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 85418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 85518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 85618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 85718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean hasContainerSelector() { 85818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) { 85918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 86018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 86118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 86218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 86318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 86418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean hasParentSelector() { 86518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 86618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 86718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 86818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 86918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 87018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 87118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 87218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Returns the deepest selector in the chain of possible sub selectors. 87318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)} 87418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of 87518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * a selector. 87618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return last UiSelector in chain 87718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 87818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiSelector getLastSubSelector() { 87918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) { 88018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD); 88118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (child.getLastSubSelector() == null) { 88218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return child; 88318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 88418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return child.getLastSubSelector(); 88518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) { 88618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT); 88718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (parent.getLastSubSelector() == null) { 88818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return parent; 88918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 89018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return parent.getLastSubSelector(); 89118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 89218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return this; 89318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 89418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 89518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 89618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String toString() { 89718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return dumpToString(true); 89818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 89918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 90018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String dumpToString(boolean all) { 90118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu StringBuilder builder = new StringBuilder(); 90218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append(UiSelector.class.getSimpleName() + "["); 90318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu final int criterionCount = mSelectorAttributes.size(); 90418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for (int i = 0; i < criterionCount; i++) { 90518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (i > 0) { 90618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append(", "); 90718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 90818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu final int criterion = mSelectorAttributes.keyAt(i); 90918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu switch (criterion) { 91018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_TEXT: 91118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("TEXT=").append(mSelectorAttributes.valueAt(i)); 91218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 91318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_TEXT_REGEX: 91418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i)); 91518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 91618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_START_TEXT: 91718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i)); 91818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 91918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CONTAINS_TEXT: 92018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i)); 92118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 92218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CLASS: 92318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CLASS=").append(mSelectorAttributes.valueAt(i)); 92418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 92518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CLASS_REGEX: 92618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i)); 92718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 92818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_DESCRIPTION: 92918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 93018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 93118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_DESCRIPTION_REGEX: 93218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i)); 93318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 93418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_START_DESCRIPTION: 93518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 93618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 93718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CONTAINS_DESCRIPTION: 93818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 93918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 94018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_INDEX: 94118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("INDEX=").append(mSelectorAttributes.valueAt(i)); 94218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 94318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_INSTANCE: 94418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i)); 94518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 94618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_ENABLED: 94718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i)); 94818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 94918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_FOCUSED: 95018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i)); 95118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 95218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_FOCUSABLE: 95318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i)); 95418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 95518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_SCROLLABLE: 95618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i)); 95718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 95818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CLICKABLE: 95918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i)); 96018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 96118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CHECKABLE: 96218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CHECKABLE=").append(mSelectorAttributes.valueAt(i)); 96318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 96418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_LONG_CLICKABLE: 96518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i)); 96618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 96718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CHECKED: 96818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i)); 96918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 97018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_SELECTED: 97118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i)); 97218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 97318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_ID: 97418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("ID=").append(mSelectorAttributes.valueAt(i)); 97518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 97618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CHILD: 97718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (all) 97818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CHILD=").append(mSelectorAttributes.valueAt(i)); 97918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu else 98018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CHILD[..]"); 98118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 98218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_PATTERN: 98318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (all) 98418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i)); 98518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu else 98618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PATTERN[..]"); 98718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 98818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_CONTAINER: 98918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (all) 99018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i)); 99118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu else 99218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("CONTAINER[..]"); 99318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 99418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_PARENT: 99518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (all) 99618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PARENT=").append(mSelectorAttributes.valueAt(i)); 99718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu else 99818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PARENT[..]"); 99918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 100018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_COUNT: 100118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("COUNT=").append(mSelectorAttributes.valueAt(i)); 100218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 100318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_PACKAGE_NAME: 100418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i)); 100518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 100618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_PACKAGE_NAME_REGEX: 100718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i)); 100818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 100918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_RESOURCE_ID: 101018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("RESOURCE_ID=").append(mSelectorAttributes.valueAt(i)); 101118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 101218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case SELECTOR_RESOURCE_ID_REGEX: 101318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("RESOURCE_ID_REGEX=").append(mSelectorAttributes.valueAt(i)); 101418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 101518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu default: 101618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i)); 101718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 101818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 101918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu builder.append("]"); 102018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return builder.toString(); 102118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 102218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu} 1023