1e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/* 2e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Copyright (C) 2012 The Android Open Source Project 3e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 4e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 5e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * you may not use this file except in compliance with the License. 6e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * You may obtain a copy of the License at 7e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 8e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 9e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 10e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Unless required by applicable law or agreed to in writing, software 11e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 12e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * See the License for the specific language governing permissions and 14e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * limitations under the License. 15e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 16e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 17e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupackage com.android.uiautomator.core; 18e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 19e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.util.SparseArray; 20e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo; 21e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 224f72d8d757b71a767999703016ba4d6db7333457Adam Momtazimport java.util.regex.Pattern; 234f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz 24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/** 25445e82ee022c484166ce7175973827f591ff2ea7quddusc * Specifies the elements in the layout hierarchy for tests to target, filtered 26445e82ee022c484166ce7175973827f591ff2ea7quddusc * by properties such as text value, content-description, class name, and state 27445e82ee022c484166ce7175973827f591ff2ea7quddusc * information. You can also target an element by its location in a layout 28445e82ee022c484166ce7175973827f591ff2ea7quddusc * hierarchy. 29dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 30e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 314ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtazpublic class UiSelector { 32e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_NIL = 0; 33e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_TEXT = 1; 34e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_START_TEXT = 2; 35e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINS_TEXT = 3; 36e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CLASS = 4; 37e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_DESCRIPTION = 5; 38e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_START_DESCRIPTION = 6; 39e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINS_DESCRIPTION = 7; 40e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_INDEX = 8; 41e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_INSTANCE = 9; 42e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_ENABLED = 10; 43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_FOCUSED = 11; 44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_FOCUSABLE = 12; 45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_SCROLLABLE = 13; 46e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CLICKABLE = 14; 47e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CHECKED = 15; 48e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_SELECTED = 16; 49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_ID = 17; 50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PACKAGE_NAME = 18; 51e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CHILD = 19; 52e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINER = 20; 53e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PATTERN = 21; 54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PARENT = 22; 55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_COUNT = 23; 56336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz static final int SELECTOR_LONG_CLICKABLE = 24; 57ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz static final int SELECTOR_TEXT_REGEX = 25; 58ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz static final int SELECTOR_CLASS_REGEX = 26; 59ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz static final int SELECTOR_DESCRIPTION_REGEX = 27; 60ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz static final int SELECTOR_PACKAGE_NAME_REGEX = 28; 61946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz static final int SELECTOR_RESOURCE_ID = 29; 6297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz static final int SELECTOR_CHECKABLE = 30; 634f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz static final int SELECTOR_RESOURCE_ID_REGEX = 31; 64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>(); 66e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 67dbba713661688a285e701a006ce2d199296ac328Guang Zhu /** 68dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 69dbba713661688a285e701a006ce2d199296ac328Guang Zhu */ 704ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector() { 71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 733d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector(UiSelector selector) { 743d50587be8ff021369c90554d814839335b445b0Adam Momtaz mSelectorAttributes = selector.cloneSelector().mSelectorAttributes; 75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 77dbba713661688a285e701a006ce2d199296ac328Guang Zhu /** 7879693ede92636fe6f3a6ec4dc049a438fd9504ffGuang Zhu * @since API Level 17 79dbba713661688a285e701a006ce2d199296ac328Guang Zhu */ 803d50587be8ff021369c90554d814839335b445b0Adam Momtaz protected UiSelector cloneSelector() { 814ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector ret = new UiSelector(); 82e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ret.mSelectorAttributes = mSelectorAttributes.clone(); 834f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (hasChildSelector()) 843d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector())); 854f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (hasParentSelector()) 863d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector())); 874f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (hasPatternSelector()) 883d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector())); 89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return ret; 90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 924ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz static UiSelector patternBuilder(UiSelector selector) { 934f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (!selector.hasPatternSelector()) { 944ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return new UiSelector().patternSelector(selector); 95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return selector; 97e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 98e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz static UiSelector patternBuilder(UiSelector container, UiSelector pattern) { 1004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return new UiSelector( 1014ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz new UiSelector().containerSelector(container).patternSelector(pattern)); 102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 104a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 105a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the visible text displayed 106445e82ee022c484166ce7175973827f591ff2ea7quddusc * in a widget (for example, the text label to launch an app). 107a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 108445e82ee022c484166ce7175973827f591ff2ea7quddusc * The text for the element must match exactly with the string in your input 109445e82ee022c484166ce7175973827f591ff2ea7quddusc * argument. Matching is case-sensitive. 110a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 111a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param text Value to match 112a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 113dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 114a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector text(String text) { 116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_TEXT, text); 117e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 118e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 119a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 120445e82ee022c484166ce7175973827f591ff2ea7quddusc * Set the search criteria to match the visible text displayed in a layout 121445e82ee022c484166ce7175973827f591ff2ea7quddusc * element, using a regular expression. 122ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 123445e82ee022c484166ce7175973827f591ff2ea7quddusc * The text in the widget must match exactly with the string in your 124445e82ee022c484166ce7175973827f591ff2ea7quddusc * input argument. 125ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 1261893caed0ad4e73b0676f206282d490c2d345316Thanh Le * @param regex a regular expression 127ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * @return UiSelector with the specified search criteria 128dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 129ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz */ 130ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz public UiSelector textMatches(String regex) { 1314f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return buildSelector(SELECTOR_TEXT_REGEX, Pattern.compile(regex)); 132ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 133ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz 134ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz /** 135445e82ee022c484166ce7175973827f591ff2ea7quddusc * Set the search criteria to match visible text in a widget that is 136445e82ee022c484166ce7175973827f591ff2ea7quddusc * prefixed by the text parameter. 137a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 138445e82ee022c484166ce7175973827f591ff2ea7quddusc * The matching is case-insensitive. 139a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 140445e82ee022c484166ce7175973827f591ff2ea7quddusc * @param text Value to match 141445e82ee022c484166ce7175973827f591ff2ea7quddusc * @return UiSelector with the specified search criteria 142dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 143a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1444ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector textStartsWith(String text) { 145e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_START_TEXT, text); 146e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 147e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 148a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 149445e82ee022c484166ce7175973827f591ff2ea7quddusc * Set the search criteria to match the visible text in a widget 150445e82ee022c484166ce7175973827f591ff2ea7quddusc * where the visible text must contain the string in your input argument. 151a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 152445e82ee022c484166ce7175973827f591ff2ea7quddusc * The matching is case-sensitive. 153a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 154a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param text Value to match 155a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 156dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 157a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector textContains(String text) { 159e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CONTAINS_TEXT, text); 160e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 161e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 162a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 163a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the class property 164a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for a widget (for example, "android.widget.Button"). 165a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 166a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param className Value to match 167a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 168dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 169a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1704ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector className(String className) { 171e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CLASS, className); 172e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 173e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 174a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 175ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * Set the search criteria to match the class property 176445e82ee022c484166ce7175973827f591ff2ea7quddusc * for a widget, using a regular expression. 177ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 1781893caed0ad4e73b0676f206282d490c2d345316Thanh Le * @param regex a regular expression 179ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * @return UiSelector with the specified search criteria 180dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 181ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz */ 182ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz public UiSelector classNameMatches(String regex) { 1834f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return buildSelector(SELECTOR_CLASS_REGEX, Pattern.compile(regex)); 184ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 185ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz 186ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz /** 187ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * Set the search criteria to match the class property 188ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * for a widget (for example, "android.widget.Button"). 189ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 1901893caed0ad4e73b0676f206282d490c2d345316Thanh Le * @param type type 191ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * @return UiSelector with the specified search criteria 192dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 193ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz */ 194ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz public <T> UiSelector className(Class<T> type) { 195ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz return buildSelector(SELECTOR_CLASS, type.getName()); 196ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 197ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz 198ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz /** 199a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 200a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 201a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 202a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 203a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 204a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 205a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 206a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must match exactly 207a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * with the string in your input argument. 208a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 209a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-sensitive. 210a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 211a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 212a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 213dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 214a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector description(String desc) { 216e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_DESCRIPTION, desc); 217e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 219a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 220a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 221a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 222a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 223a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 224a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 225a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 226a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 227ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * for the widget must match exactly 228ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * with the string in your input argument. 229ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 2301893caed0ad4e73b0676f206282d490c2d345316Thanh Le * @param regex a regular expression 231ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * @return UiSelector with the specified search criteria 232dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 233ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz */ 234ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz public UiSelector descriptionMatches(String regex) { 2354f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return buildSelector(SELECTOR_DESCRIPTION_REGEX, Pattern.compile(regex)); 236ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 237ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz 238ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz /** 239ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * Set the search criteria to match the content-description 240ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * property for a widget. 241ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 242ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * The content-description is typically used 243ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * by the Android Accessibility framework to 244ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * provide an audio prompt for the widget when 245ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * the widget is selected. The content-description 246a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must start 247a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * with the string in your input argument. 248a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 249a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-insensitive. 250a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 251a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 252a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 253dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 254a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2554ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector descriptionStartsWith(String desc) { 256e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_START_DESCRIPTION, desc); 257e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 258e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 259a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 260a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 261a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 262a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 263a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 264a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 265a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 266a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 267a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must contain 268a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the string in your input argument. 269a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 270a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-insensitive. 271a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 272a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 273a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 274dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 275a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2764ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector descriptionContains(String desc) { 277e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc); 278e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 279e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 280a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 281445e82ee022c484166ce7175973827f591ff2ea7quddusc * Set the search criteria to match the given resource ID. 28289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov * 283445e82ee022c484166ce7175973827f591ff2ea7quddusc * @param id Value to match 28489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov * @return UiSelector with the specified search criteria 28589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov * @since API Level 18 28689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov */ 287946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz public UiSelector resourceId(String id) { 288946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz return buildSelector(SELECTOR_RESOURCE_ID, id); 28989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov } 29089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov 29189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov /** 292445e82ee022c484166ce7175973827f591ff2ea7quddusc * Set the search criteria to match the resource ID 293445e82ee022c484166ce7175973827f591ff2ea7quddusc * of the widget, using a regular expression.http://blog.bettersoftwaretesting.com/ 2944f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz * 2954f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz * @param regex a regular expression 2964f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz * @return UiSelector with the specified search criteria 2974f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz * @since API Level 18 2984f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz */ 2994f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz public UiSelector resourceIdMatches(String regex) { 3004f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return buildSelector(SELECTOR_RESOURCE_ID_REGEX, Pattern.compile(regex)); 3014f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz } 3024f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz 3034f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz /** 304a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the widget by its node 305a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * index in the layout hierarchy. 306a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 307a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The index value must be 0 or greater. 308a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 309a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Using the index can be unreliable and should only 310a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * be used as a last resort for matching. Instead, 311a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * consider using the {@link #instance(int)} method. 312a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 313a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param index Value to match 314a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 315dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 316a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector index(final int index) { 318e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_INDEX, index); 319e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 320e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 321a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 322a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the 323a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * widget by its instance number. 324a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 325a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The instance value must be 0 or greater, where 326a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the first instance is 0. 327a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 328a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * For example, to simulate a user click on 329a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the third image that is enabled in a UI screen, you 330a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * could specify a a search criteria where the instance is 331a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 2, the {@link #className(String)} matches the image 332a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * widget class, and {@link #enabled(boolean)} is true. 333a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The code would look like this: 334a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * <code> 335a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * new UiSelector().className("android.widget.ImageView") 336a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * .enabled(true).instance(2); 337a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * </code> 338a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 339a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param instance Value to match 340a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 341dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 342a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3434ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector instance(final int instance) { 344e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_INSTANCE, instance); 345e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 346e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 347a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 348a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are enabled. 349a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 350a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 351a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 352a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 353a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 354a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 355a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 356a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 357a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 358a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 359a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 360dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 361a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3624ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector enabled(boolean val) { 363e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_ENABLED, val); 364e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 365e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 366a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 367a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that have focus. 368a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 369a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 370a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 371a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 372a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 373a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 374a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 375a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 376a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 377a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 378a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 379dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 380a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3814ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector focused(boolean val) { 382e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_FOCUSED, val); 383e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 384e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 385a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 386a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are focusable. 387a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 388a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 389a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 390a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 391a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 392a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 393a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 394a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 395a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 396a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 397a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 398dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 399a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector focusable(boolean val) { 401e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_FOCUSABLE, val); 402e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 403e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 404a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 405a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are scrollable. 406a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 407a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 408a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 409a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 410a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 411a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 412a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 413a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 414a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 415a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 416a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 417dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 418a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4194ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector scrollable(boolean val) { 420e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_SCROLLABLE, val); 421e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 422e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 423a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 424a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that 425a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * are currently selected. 426a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 427a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 428a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 429a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 430a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 431a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 432a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 433a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 434a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 435a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 436a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 437dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 438a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4394ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector selected(boolean val) { 440e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_SELECTED, val); 441e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 442e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 443a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 444a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that 445a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * are currently checked (usually for checkboxes). 446a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 447a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 448a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 449a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 450a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 451a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 452a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 453a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 454a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 455a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 456a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 457dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 458a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4594ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector checked(boolean val) { 460e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CHECKED, val); 461e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 462e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 463a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 464a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are clickable. 465a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 466a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 467a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 468a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 469a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 470a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 471a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 472a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 473a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 474a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 475a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 476dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 477a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector clickable(boolean val) { 479e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CLICKABLE, val); 480e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 481e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 482a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 48397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * Set the search criteria to match widgets that are checkable. 48497835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * 48597835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * Typically, using this search criteria alone is not useful. 48697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * You should also include additional criteria, such as text, 48797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * content-description, or the class name for a widget. 48897835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * 48997835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * If no other search criteria is specified, and there is more 49097835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * than one matching widget, the first widget in the tree 49197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * is selected. 49297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * 49397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * @param val Value to match 49497835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * @return UiSelector with the specified search criteria 49597835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz * @since API Level 18 49697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz */ 49797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz public UiSelector checkable(boolean val) { 49897835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz return buildSelector(SELECTOR_CHECKABLE, val); 49997835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz } 50097835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz 50197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz /** 502336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * Set the search criteria to match widgets that are long-clickable. 503336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * 504336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * Typically, using this search criteria alone is not useful. 505336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * You should also include additional criteria, such as text, 506336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * content-description, or the class name for a widget. 507336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * 508336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * If no other search criteria is specified, and there is more 509336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * than one matching widget, the first widget in the tree 510336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * is selected. 511336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * 512336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * @param val Value to match 513336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz * @return UiSelector with the specified search criteria 514dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 515336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz */ 516336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz public UiSelector longClickable(boolean val) { 517336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz return buildSelector(SELECTOR_LONG_CLICKABLE, val); 518336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz } 519336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz 520336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz /** 521a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Adds a child UiSelector criteria to this selector. 522a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 523a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Use this selector to narrow the search scope to 524a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * child widgets under a specific parent widget. 525a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 526a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param selector 527a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with this added search criterion 528dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 529a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 5303d50587be8ff021369c90554d814839335b445b0Adam Momtaz public UiSelector childSelector(UiSelector selector) { 5313d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_CHILD, selector); 532e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 533e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 5343d50587be8ff021369c90554d814839335b445b0Adam Momtaz private UiSelector patternSelector(UiSelector selector) { 5353d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_PATTERN, selector); 536e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 537e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 5383d50587be8ff021369c90554d814839335b445b0Adam Momtaz private UiSelector containerSelector(UiSelector selector) { 5393d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_CONTAINER, selector); 540e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 541e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 542a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 543a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Adds a child UiSelector criteria to this selector which is used to 544a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * start search from the parent widget. 545a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 546a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Use this selector to narrow the search scope to 547a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * sibling widgets as well all child widgets under a parent. 548a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 549a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param selector 550a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with this added search criterion 551dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 552a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 5533d50587be8ff021369c90554d814839335b445b0Adam Momtaz public UiSelector fromParent(UiSelector selector) { 5543d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_PARENT, selector); 555e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 556e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 557a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 558a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the package name 559a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * of the application that contains the widget. 560a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 561a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param name Value to match 562a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 563dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 16 564a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 5654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector packageName(String name) { 566e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_PACKAGE_NAME, name); 567e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 568e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 569e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 570ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * Set the search criteria to match the package name 571ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * of the application that contains the widget. 572ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * 5731893caed0ad4e73b0676f206282d490c2d345316Thanh Le * @param regex a regular expression 574ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz * @return UiSelector with the specified search criteria 575dbba713661688a285e701a006ce2d199296ac328Guang Zhu * @since API Level 17 576ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz */ 577ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz public UiSelector packageNameMatches(String regex) { 5784f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, Pattern.compile(regex)); 579ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 580ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz 581ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz /** 5823d50587be8ff021369c90554d814839335b445b0Adam Momtaz * Building a UiSelector always returns a new UiSelector and never modifies the 5833d50587be8ff021369c90554d814839335b445b0Adam Momtaz * existing UiSelector being used. 584e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 5854ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz private UiSelector buildSelector(int selectorId, Object selectorValue) { 5863d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = new UiSelector(this); 5874f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT) 5883d50587be8ff021369c90554d814839335b445b0Adam Momtaz selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue); 589e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 5903d50587be8ff021369c90554d814839335b445b0Adam Momtaz selector.mSelectorAttributes.put(selectorId, selectorValue); 5913d50587be8ff021369c90554d814839335b445b0Adam Momtaz return selector; 592e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 593e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 594e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 595e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Selectors may have a hierarchy defined by specifying child nodes to be matched. 596e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * It is not necessary that every selector have more than one level. A selector 597e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * can also be a single level referencing only one node. In such cases the return 598e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * it null. 599a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 600e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return a child selector if one exists. Else null if this selector does not 601e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * reference child node. 602e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 6034ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getChildSelector() { 6043d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null); 6054f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (selector != null) 6063d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 607e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 608e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 609e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 6104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getPatternSelector() { 6113d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 6123d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null); 6134f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (selector != null) 6143d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 615e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 616e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 617e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 6184ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getContainerSelector() { 6193d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 6203d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null); 6214f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (selector != null) 6223d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 623e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 624e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 625e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 6264ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getParentSelector() { 6273d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 6283d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null); 6294f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (selector != null) 6303d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 631e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 632e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 633e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 634e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int getInstance() { 6354ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return getInt(UiSelector.SELECTOR_INSTANCE); 636e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 637e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 638e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String getString(int criterion) { 639e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (String) mSelectorAttributes.get(criterion, null); 640e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 641e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 642e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean getBoolean(int criterion) { 643e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (Boolean) mSelectorAttributes.get(criterion, false); 644e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 645e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 646e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int getInt(int criterion) { 647e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (Integer) mSelectorAttributes.get(criterion, 0); 648e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 649e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 6504f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz Pattern getPattern(int criterion) { 6514f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return (Pattern) mSelectorAttributes.get(criterion, null); 6524f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz } 6534f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz 654e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean isMatchFor(AccessibilityNodeInfo node, int index) { 655e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int size = mSelectorAttributes.size(); 656e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for(int x = 0; x < size; x++) { 657e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu CharSequence s = null; 658e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int criterion = mSelectorAttributes.keyAt(x); 659e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu switch(criterion) { 6604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_INDEX: 6614f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (index != this.getInt(criterion)) 662e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 663e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 6644ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CHECKED: 665e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (node.isChecked() != getBoolean(criterion)) { 666e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 667e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 668e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 6694ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CLASS: 670e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getClassName(); 671e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 672e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 673e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 674e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 675ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case UiSelector.SELECTOR_CLASS_REGEX: 676ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz s = node.getClassName(); 6774f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !getPattern(criterion).matcher(s).matches()) { 678ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz return false; 679ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 680ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 6814ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CLICKABLE: 682e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (node.isClickable() != getBoolean(criterion)) { 683e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 684e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 685e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 68697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz case UiSelector.SELECTOR_CHECKABLE: 68797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz if (node.isCheckable() != getBoolean(criterion)) { 68897835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz return false; 68997835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz } 69097835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz break; 691336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz case UiSelector.SELECTOR_LONG_CLICKABLE: 692336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz if (node.isLongClickable() != getBoolean(criterion)) { 693336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz return false; 694336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz } 695336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz break; 6964ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CONTAINS_DESCRIPTION: 697e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 6984f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().toLowerCase() 699e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .contains(getString(criterion).toLowerCase())) { 700e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 701e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 702e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7034ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_START_DESCRIPTION: 704e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 7054f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().toLowerCase() 706e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 707e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 708e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 709e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_DESCRIPTION: 711e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 7124f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().contentEquals(getString(criterion))) { 713e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 714e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 715e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 716ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case UiSelector.SELECTOR_DESCRIPTION_REGEX: 717ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz s = node.getContentDescription(); 7184f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !getPattern(criterion).matcher(s).matches()) { 719ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz return false; 720ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 721ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 7224ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CONTAINS_TEXT: 723e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 7244f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().toLowerCase() 725e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .contains(getString(criterion).toLowerCase())) { 726e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 727e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 728e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_START_TEXT: 730e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 7314f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().toLowerCase() 732e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 733e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 734e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 735e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7364ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_TEXT: 737e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 7384f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().contentEquals(getString(criterion))) { 739e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 740e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 741e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 742ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case UiSelector.SELECTOR_TEXT_REGEX: 743ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz s = node.getText(); 7444f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !getPattern(criterion).matcher(s).matches()) { 745ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz return false; 746ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 747ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 7484ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_ENABLED: 7494f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (node.isEnabled() != getBoolean(criterion)) { 750e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 751e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 752e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7534ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_FOCUSABLE: 7544f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (node.isFocusable() != getBoolean(criterion)) { 755e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 756e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 757e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_FOCUSED: 7594f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (node.isFocused() != getBoolean(criterion)) { 760e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 761e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 762e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7634ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_ID: 764e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; //TODO: do we need this for AccessibilityNodeInfo.id? 7654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_PACKAGE_NAME: 766e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getPackageName(); 7674f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !s.toString().contentEquals(getString(criterion))) { 768e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 769e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 770e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 771ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case UiSelector.SELECTOR_PACKAGE_NAME_REGEX: 772ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz s = node.getPackageName(); 7734f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !getPattern(criterion).matcher(s).matches()) { 774ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz return false; 775ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz } 776ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 7774ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_SCROLLABLE: 7784f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (node.isScrollable() != getBoolean(criterion)) { 779e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 780e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 781e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 7824ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_SELECTED: 7834f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (node.isSelected() != getBoolean(criterion)) { 784e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 785e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 786e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 787946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz case UiSelector.SELECTOR_RESOURCE_ID: 7886b8d14ca5b3c2cbc066133da2e66658fb81f206eAdam Momtaz s = node.getViewIdResourceName(); 7896b8d14ca5b3c2cbc066133da2e66658fb81f206eAdam Momtaz if (s == null || !s.toString().contentEquals(getString(criterion))) { 79089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov return false; 79189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov } 79289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov break; 7934f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz case UiSelector.SELECTOR_RESOURCE_ID_REGEX: 7944f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz s = node.getViewIdResourceName(); 7954f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (s == null || !getPattern(criterion).matcher(s).matches()) { 7964f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz return false; 7974f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz } 7984f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz break; 799e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 800e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 801e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return matchOrUpdateInstance(); 802e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 803e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 804e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private boolean matchOrUpdateInstance() { 805e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int currentSelectorCounter = 0; 806e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int currentSelectorInstance = 0; 807e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 808e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // matched attributes - now check for matching instance number 8094f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) >= 0) { 8104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz currentSelectorInstance = 8114ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE); 812e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 813e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 814e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // instance is required. Add count if not already counting 8154f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) >= 0) { 8164ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT); 817e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 818e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 819e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Verify 820e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (currentSelectorInstance == currentSelectorCounter) { 821e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 822e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 823e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Update count 824e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (currentSelectorInstance > currentSelectorCounter) { 8254ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter); 826e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 827e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 828e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 829e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 830e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 831e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Leaf selector indicates no more child or parent selectors 832e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * are declared in the this selector. 833e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return true if is leaf. 834e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 835e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean isLeaf() { 8364f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 && 8374ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 838e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 839e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 840e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 841e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 842e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 843e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasChildSelector() { 8444f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) { 845e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 846e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 847e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 848e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 849e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 850e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasPatternSelector() { 8514f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) { 852e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 853e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 854e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 855e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 856e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 857e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasContainerSelector() { 8584f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) { 859e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 860e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 861e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 862e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 863e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 864e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasParentSelector() { 8654f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 866e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 867e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 868e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 869e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 870e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 871e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 872e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Returns the deepest selector in the chain of possible sub selectors. 8734ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)} 8744ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of 875e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * a selector. 8763d50587be8ff021369c90554d814839335b445b0Adam Momtaz * @return last UiSelector in chain 877e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 8784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz private UiSelector getLastSubSelector() { 8794f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) { 8804ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD); 8814f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (child.getLastSubSelector() == null) { 882e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return child; 883e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 884e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return child.getLastSubSelector(); 8854f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz } else if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) { 8864ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT); 8874f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (parent.getLastSubSelector() == null) { 888e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return parent; 889e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 890e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return parent.getLastSubSelector(); 891e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 892e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return this; 893e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 894e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 895e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 896e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public String toString() { 897e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return dumpToString(true); 898e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 899e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 900e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String dumpToString(boolean all) { 901e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu StringBuilder builder = new StringBuilder(); 9023d50587be8ff021369c90554d814839335b445b0Adam Momtaz builder.append(UiSelector.class.getSimpleName() + "["); 903e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu final int criterionCount = mSelectorAttributes.size(); 904e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (int i = 0; i < criterionCount; i++) { 905e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (i > 0) { 906e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append(", "); 907e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 908e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu final int criterion = mSelectorAttributes.keyAt(i); 909e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu switch (criterion) { 910e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_TEXT: 911e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("TEXT=").append(mSelectorAttributes.valueAt(i)); 912e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 913ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case SELECTOR_TEXT_REGEX: 914ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i)); 915ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 916e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_START_TEXT: 917e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i)); 918e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 919e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINS_TEXT: 920e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i)); 921e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 922e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CLASS: 923e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CLASS=").append(mSelectorAttributes.valueAt(i)); 924e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 925ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case SELECTOR_CLASS_REGEX: 926ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i)); 927ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 928e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_DESCRIPTION: 929e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 930e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 931ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case SELECTOR_DESCRIPTION_REGEX: 932ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i)); 933ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 934e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_START_DESCRIPTION: 935e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 936e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 937e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINS_DESCRIPTION: 938e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 939e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 940e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_INDEX: 941e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("INDEX=").append(mSelectorAttributes.valueAt(i)); 942e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 943e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_INSTANCE: 944e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i)); 945e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 946e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_ENABLED: 947e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i)); 948e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 949e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_FOCUSED: 950e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i)); 951e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 952e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_FOCUSABLE: 953e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i)); 954e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 955e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_SCROLLABLE: 956e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i)); 957e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 958e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CLICKABLE: 959e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i)); 960e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 96197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz case SELECTOR_CHECKABLE: 96297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz builder.append("CHECKABLE=").append(mSelectorAttributes.valueAt(i)); 96397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz break; 964336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz case SELECTOR_LONG_CLICKABLE: 965336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i)); 966336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz break; 967e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CHECKED: 968e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i)); 969e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 970e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_SELECTED: 971e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i)); 972e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 973e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_ID: 974e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("ID=").append(mSelectorAttributes.valueAt(i)); 975e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 976e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CHILD: 9774f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (all) 978e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHILD=").append(mSelectorAttributes.valueAt(i)); 979e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 980e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHILD[..]"); 981e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 982e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PATTERN: 9834f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (all) 984e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i)); 985e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 986e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PATTERN[..]"); 987e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 988e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINER: 9894f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (all) 990e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i)); 991e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 992e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINER[..]"); 993e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 994e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PARENT: 9954f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz if (all) 996e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PARENT=").append(mSelectorAttributes.valueAt(i)); 997e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 998e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PARENT[..]"); 999e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 1000e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_COUNT: 1001e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("COUNT=").append(mSelectorAttributes.valueAt(i)); 1002e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 1003e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PACKAGE_NAME: 1004e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i)); 1005e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 1006ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz case SELECTOR_PACKAGE_NAME_REGEX: 1007ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i)); 1008ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz break; 1009946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz case SELECTOR_RESOURCE_ID: 1010946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz builder.append("RESOURCE_ID=").append(mSelectorAttributes.valueAt(i)); 101189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov break; 10124f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz case SELECTOR_RESOURCE_ID_REGEX: 10134f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz builder.append("RESOURCE_ID_REGEX=").append(mSelectorAttributes.valueAt(i)); 10144f72d8d757b71a767999703016ba4d6db7333457Adam Momtaz break; 1015e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu default: 1016e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i)); 1017e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 1018e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 1019e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("]"); 1020e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return builder.toString(); 1021e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 10229ebf91aa923d2424298cb908a79dd03aefbf0a8fGuang Zhu} 1023