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