UiSelector.java revision 97835f3a7c80b147136c44c175eb9e6a4261fd92
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
22e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/**
23e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * This class provides the mechanism for tests to describe the UI elements they
24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * intend to target. A UI element has many properties associated with it such as
253d50587be8ff021369c90554d814839335b445b0Adam Momtaz * text value, content-description, class name and multiple state information like
263d50587be8ff021369c90554d814839335b445b0Adam Momtaz * selected, enabled, checked etc. Additionally UiSelector allows targeting of UI
273d50587be8ff021369c90554d814839335b445b0Adam Momtaz * elements within a specific display hierarchies to distinguish similar elements
283d50587be8ff021369c90554d814839335b445b0Adam Momtaz * based in the hierarchies they're in.
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;
63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>();
65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
66dbba713661688a285e701a006ce2d199296ac328Guang Zhu    /**
67dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
68dbba713661688a285e701a006ce2d199296ac328Guang Zhu     */
694ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector() {
70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
723d50587be8ff021369c90554d814839335b445b0Adam Momtaz    UiSelector(UiSelector selector) {
733d50587be8ff021369c90554d814839335b445b0Adam Momtaz        mSelectorAttributes = selector.cloneSelector().mSelectorAttributes;
74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
76dbba713661688a285e701a006ce2d199296ac328Guang Zhu    /**
7779693ede92636fe6f3a6ec4dc049a438fd9504ffGuang Zhu     * @since API Level 17
78dbba713661688a285e701a006ce2d199296ac328Guang Zhu     */
793d50587be8ff021369c90554d814839335b445b0Adam Momtaz    protected UiSelector cloneSelector() {
804ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector ret = new UiSelector();
81e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        ret.mSelectorAttributes = mSelectorAttributes.clone();
823d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasChildSelector())
833d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector()));
843d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasParentSelector())
853d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector()));
863d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasPatternSelector())
873d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector()));
88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return ret;
89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
914ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector selector) {
92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(!selector.hasPatternSelector()) {
934ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector().patternSelector(selector);
94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return selector;
96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
97e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
984ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector container, UiSelector pattern) {
994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return new UiSelector(
1004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                new UiSelector().containerSelector(container).patternSelector(pattern));
101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
103a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
104a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the visible text displayed
105a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, the text label to launch an app).
106a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
107a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The text for the widget must match exactly
108a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
109a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * 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    /**
120ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the visible text displayed
121ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, the text label to launch an app).
122ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
123ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * The text for the widget must match exactly
124ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * with the string in your 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) {
131ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_TEXT_REGEX, regex);
132ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
133ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
134ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
135a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Text property is usually the widget's visible text on the display.
136a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
137a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adding this to the search criteria indicates that the search performed
138a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * should match a widget with text value starting with the text parameter.
139a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
140a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The matching will be case-insensitive.
141a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
142a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param text
143a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
144dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
145a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1464ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textStartsWith(String text) {
147e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_TEXT, text);
148e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
149e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
150a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
151a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the visible text displayed
152a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, the text label to launch an app).
153a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
154a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The text for the widget must contain the string in
155a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * your input argument. Matching is case-sensitive.
156a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
157a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param text Value to match
158a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
159dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
160a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1614ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textContains(String text) {
162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_TEXT, text);
163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
164e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
165a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
166a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the class property
167a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, "android.widget.Button").
168a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
169a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param className Value to match
170a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
171dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
172a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1734ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector className(String className) {
174e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLASS, className);
175e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
176e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
177a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
178ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the class property
179ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, "android.widget.Button").
180ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
1811893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
182ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
183dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
184ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
185ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector classNameMatches(String regex) {
186ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_CLASS_REGEX, regex);
187ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
188ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
189ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
190ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the class property
191ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, "android.widget.Button").
192ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
1931893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param type type
194ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
195dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
196ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
197ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public <T> UiSelector className(Class<T> type) {
198ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_CLASS, type.getName());
199ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
200ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
201ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
202a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
203a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
204a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
205a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
206a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
207a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
208a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
209a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must match exactly
210a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
211a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
212a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-sensitive.
213a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
214a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
215a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
216dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
217a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2184ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector description(String desc) {
219e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_DESCRIPTION, desc);
220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
221e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
222a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
223a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
224a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
225a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
226a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
227a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
228a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
229a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
230ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for the widget must match exactly
231ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * with the string in your input argument.
232ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
2331893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
234ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
235dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
236ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
237ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector descriptionMatches(String regex) {
238ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_DESCRIPTION_REGEX, regex);
239ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
240ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
241ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
242ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the content-description
243ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * property for a widget.
244ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
245ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * The content-description is typically used
246ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * by the Android Accessibility framework to
247ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * provide an audio prompt for the widget when
248ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * the widget is selected. The content-description
249a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must start
250a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
251a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
252a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-insensitive.
253a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
254a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
255a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
256dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
257a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionStartsWith(String desc) {
259e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_DESCRIPTION, desc);
260e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
261e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
262a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
263a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
264a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
265a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
266a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
267a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
268a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
269a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
270a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must contain
271a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the string in your input argument.
272a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
273a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-insensitive.
274a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
275a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
276a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
277dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
278a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2794ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionContains(String desc) {
280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
282e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
283a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
284946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz     * Set the search criteria to match the given resource id.
28589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     *
286946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz     * @param id value to match
28789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * @return UiSelector with the specified search criteria
28889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * @since API Level 18
28989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     */
290946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz    public UiSelector resourceId(String id) {
291946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz        return buildSelector(SELECTOR_RESOURCE_ID, id);
29289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    }
29389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov
29489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    /**
295a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the widget by its node
296a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * index in the layout hierarchy.
297a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
298a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The index value must be 0 or greater.
299a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
300a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Using the index can be unreliable and should only
301a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * be used as a last resort for matching. Instead,
302a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * consider using the {@link #instance(int)} method.
303a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
304a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param index Value to match
305a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
306dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
307a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3084ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector index(final int index) {
309e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INDEX, index);
310e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
311e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
312a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
313a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the
314a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * widget by its instance number.
315a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
316a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The instance value must be 0 or greater, where
317a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the first instance is 0.
318a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
319a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * For example, to simulate a user click on
320a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the third image that is enabled in a UI screen, you
321a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * could specify a a search criteria where the instance is
322a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * 2, the {@link #className(String)} matches the image
323a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * widget class, and {@link #enabled(boolean)} is true.
324a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The code would look like this:
325a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * <code>
326a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * new UiSelector().className("android.widget.ImageView")
327a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *    .enabled(true).instance(2);
328a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * </code>
329a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
330a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param instance Value to match
331a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
332dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
333a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3344ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector instance(final int instance) {
335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INSTANCE, instance);
336e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
337e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
338a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
339a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are enabled.
340a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
341a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
342a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
343a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
344a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
345a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
346a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
347a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
348a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
349a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
350a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
351dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
352a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3534ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector enabled(boolean val) {
354e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_ENABLED, val);
355e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
356e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
357a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
358a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that have focus.
359a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
360a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
361a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
362a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
363a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
364a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
365a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
366a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
367a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
368a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
369a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
370dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
371a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3724ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focused(boolean val) {
373e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSED, val);
374e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
375e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
376a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
377a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are focusable.
378a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
379a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
380a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
381a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
382a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
383a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
384a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
385a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
386a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
387a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
388a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
389dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
390a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3914ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focusable(boolean val) {
392e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSABLE, val);
393e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
394e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
395a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
396a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are scrollable.
397a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
398a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
399a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
400a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
401a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
402a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
403a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
404a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
405a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
406a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
407a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
408dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
409a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector scrollable(boolean val) {
411e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SCROLLABLE, val);
412e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
413e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
414a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
415a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that
416a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * are currently selected.
417a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
418a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
419a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
420a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
421a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
422a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
423a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
424a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
425a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
426a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
427a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
428dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
429a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4304ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector selected(boolean val) {
431e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SELECTED, val);
432e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
433e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
434a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
435a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that
436a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * are currently checked (usually for checkboxes).
437a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
438a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
439a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
440a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
441a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
442a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
443a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
444a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
445a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
446a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
447a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
448dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
449a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4504ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector checked(boolean val) {
451e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CHECKED, val);
452e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
453e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
454a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
455a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are clickable.
456a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
457a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
458a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
459a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
460a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
461a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
462a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
463a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
464a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
465a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
466a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
467dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
468a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4694ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector clickable(boolean val) {
470e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLICKABLE, val);
471e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
472e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
473a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
47497835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * Set the search criteria to match widgets that are checkable.
47597835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     *
47697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * Typically, using this search criteria alone is not useful.
47797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * You should also include additional criteria, such as text,
47897835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * content-description, or the class name for a widget.
47997835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     *
48097835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * If no other search criteria is specified, and there is more
48197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * than one matching widget, the first widget in the tree
48297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * is selected.
48397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     *
48497835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * @param val Value to match
48597835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * @return UiSelector with the specified search criteria
48697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     * @since API Level 18
48797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz     */
48897835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz    public UiSelector checkable(boolean val) {
48997835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz        return buildSelector(SELECTOR_CHECKABLE, val);
49097835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz    }
49197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz
49297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz    /**
493336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * Set the search criteria to match widgets that are long-clickable.
494336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
495336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * Typically, using this search criteria alone is not useful.
496336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * You should also include additional criteria, such as text,
497336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * content-description, or the class name for a widget.
498336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
499336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * If no other search criteria is specified, and there is more
500336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * than one matching widget, the first widget in the tree
501336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * is selected.
502336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
503336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * @param val Value to match
504336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * @return UiSelector with the specified search criteria
505dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
506336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     */
507336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    public UiSelector longClickable(boolean val) {
508336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz        return buildSelector(SELECTOR_LONG_CLICKABLE, val);
509336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    }
510336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz
511336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    /**
512a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adds a child UiSelector criteria to this selector.
513a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
514a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Use this selector to narrow the search scope to
515a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * child widgets under a specific parent widget.
516a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
517a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param selector
518a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
519dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
520a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5213d50587be8ff021369c90554d814839335b445b0Adam Momtaz    public UiSelector childSelector(UiSelector selector) {
5223d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_CHILD, selector);
523e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
524e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5253d50587be8ff021369c90554d814839335b445b0Adam Momtaz    private UiSelector patternSelector(UiSelector selector) {
5263d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_PATTERN, selector);
527e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
528e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5293d50587be8ff021369c90554d814839335b445b0Adam Momtaz    private UiSelector containerSelector(UiSelector selector) {
5303d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_CONTAINER, selector);
531e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
532e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
533a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
534a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adds a child UiSelector criteria to this selector which is used to
535a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * start search from the parent widget.
536a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
537a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Use this selector to narrow the search scope to
538a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * sibling widgets as well all child widgets under a parent.
539a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
540a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param selector
541a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
542dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
543a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5443d50587be8ff021369c90554d814839335b445b0Adam Momtaz    public UiSelector fromParent(UiSelector selector) {
5453d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_PARENT, selector);
546e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
547e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
548a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
549a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the package name
550a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * of the application that contains the widget.
551a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
552a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param name Value to match
553a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
554dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
555a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5564ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector packageName(String name) {
557e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_PACKAGE_NAME, name);
558e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
559e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
560e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
561ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the package name
562ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * of the application that contains the widget.
563ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
5641893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
565ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
566dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
567ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
568ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector packageNameMatches(String regex) {
569ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, regex);
570ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
571ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
572ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
5733d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * Building a UiSelector always returns a new UiSelector and never modifies the
5743d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * existing UiSelector being used.
575e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
5764ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector buildSelector(int selectorId, Object selectorValue) {
5773d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector = new UiSelector(this);
578e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT)
5793d50587be8ff021369c90554d814839335b445b0Adam Momtaz            selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue);
580e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        else
5813d50587be8ff021369c90554d814839335b445b0Adam Momtaz            selector.mSelectorAttributes.put(selectorId, selectorValue);
5823d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return selector;
583e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
584e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
585e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
586e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Selectors may have a hierarchy defined by specifying child nodes to be matched.
587e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * It is not necessary that every selector have more than one level. A selector
588e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * can also be a single level referencing only one node. In such cases the return
589e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * it null.
590a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
591e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return a child selector if one exists. Else null if this selector does not
592e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * reference child node.
593e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
5944ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getChildSelector() {
5953d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null);
5963d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
5973d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
598e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
599e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
600e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6014ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getPatternSelector() {
6023d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
6033d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null);
6043d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
6053d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
606e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
607e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
608e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6094ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getContainerSelector() {
6103d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
6113d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null);
6123d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
6133d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
614e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
615e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
616e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getParentSelector() {
6183d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
6193d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null);
6203d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
6213d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
622e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
623e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
624e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
625e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInstance() {
6264ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return getInt(UiSelector.SELECTOR_INSTANCE);
627e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
628e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
629e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String getString(int criterion) {
630e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (String) mSelectorAttributes.get(criterion, null);
631e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
632e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
633e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean getBoolean(int criterion) {
634e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Boolean) mSelectorAttributes.get(criterion, false);
635e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
636e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
637e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInt(int criterion) {
638e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Integer) mSelectorAttributes.get(criterion, 0);
639e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
640e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
641e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isMatchFor(AccessibilityNodeInfo node, int index) {
642e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int size = mSelectorAttributes.size();
643e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for(int x = 0; x < size; x++) {
644e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            CharSequence s = null;
645e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            int criterion = mSelectorAttributes.keyAt(x);
646e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch(criterion) {
6474ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_INDEX:
648e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(index != this.getInt(criterion))
649e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
650e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6514ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CHECKED:
652e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isChecked() != getBoolean(criterion)) {
653e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
654e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
655e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6564ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLASS:
657e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getClassName();
658e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (s == null || !s.toString().contentEquals(getString(criterion))) {
659e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
660e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
661e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
662ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_CLASS_REGEX:
663ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getClassName();
664ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if (s == null || !s.toString().matches(getString(criterion))) {
665ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
666ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
667ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
6684ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLICKABLE:
669e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isClickable() != getBoolean(criterion)) {
670e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
671e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
672e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
67397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz            case UiSelector.SELECTOR_CHECKABLE:
67497835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                if (node.isCheckable() != getBoolean(criterion)) {
67597835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                    return false;
67697835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                }
67797835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                break;
678336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz            case UiSelector.SELECTOR_LONG_CLICKABLE:
679336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                if (node.isLongClickable() != getBoolean(criterion)) {
680336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                    return false;
681336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                }
682336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                break;
6834ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_DESCRIPTION:
684e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
685e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
686e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
687e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
688e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
689e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6904ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_DESCRIPTION:
691e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
692e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
693e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
694e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
695e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
696e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6974ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_DESCRIPTION:
698e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
699e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
700e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
701e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
702e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
703ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_DESCRIPTION_REGEX:
704ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getContentDescription();
705ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
706ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
707ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
708ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
7094ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_TEXT:
710e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
711e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
712e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
713e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
714e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
715e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7164ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_TEXT:
717e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
718e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
719e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
720e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
721e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
722e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7234ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_TEXT:
724e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
725e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
726e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
727e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
728e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
729ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_TEXT_REGEX:
730ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getText();
731ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
732ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
733ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
734ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
7354ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ENABLED:
736e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isEnabled() != getBoolean(criterion)) {
737e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
738e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
739e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7404ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSABLE:
741e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocusable() != getBoolean(criterion)) {
742e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
743e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
744e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7454ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSED:
746e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocused() != getBoolean(criterion)) {
747e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
748e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
749e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7504ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ID:
751e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break; //TODO: do we need this for AccessibilityNodeInfo.id?
7524ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_PACKAGE_NAME:
753e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getPackageName();
754e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
755e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
756e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
757e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
758ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_PACKAGE_NAME_REGEX:
759ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getPackageName();
760ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
761ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
762ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
763ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
7644ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SCROLLABLE:
765e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isScrollable() != getBoolean(criterion)) {
766e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
767e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
768e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7694ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SELECTED:
770e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isSelected() != getBoolean(criterion)) {
771e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
772e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
773e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
774946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz            case UiSelector.SELECTOR_RESOURCE_ID:
77589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                if (node.getViewId() != getString(criterion)) {
77689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                    return false;
77789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                }
77889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                break;
779e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
780e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
781e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return matchOrUpdateInstance();
782e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
783e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
784e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private boolean matchOrUpdateInstance() {
785e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorCounter = 0;
786e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorInstance = 0;
787e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
788e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // matched attributes - now check for matching instance number
7894ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) > 0) {
7904ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorInstance =
7914ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                    (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE);
792e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
793e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
794e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // instance is required. Add count if not already counting
7954ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) > 0) {
7964ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT);
797e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
798e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
799e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Verify
800e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance == currentSelectorCounter) {
801e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
802e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
803e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Update count
804e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance > currentSelectorCounter) {
8054ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter);
806e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
807e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
808e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
809e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
810e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
811e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Leaf selector indicates no more child or parent selectors
812e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * are declared in the this selector.
813e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return true if is leaf.
814e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
815e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isLeaf() {
8164ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 &&
8174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
818e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
819e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
820e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
821e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
822e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
823e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasChildSelector() {
8244ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) {
825e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
826e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
827e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
828e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
829e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
830e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasPatternSelector() {
8314ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) {
832e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
833e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
834e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
835e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
836e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
837e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasContainerSelector() {
8384ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) {
839e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
840e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
841e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
842e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
843e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
844e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasParentSelector() {
8454ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
846e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
847e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
848e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
849e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
850e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
851e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
852e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Returns the deepest selector in the chain of possible sub selectors.
8534ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)}
8544ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of
855e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * a selector.
8563d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * @return last UiSelector in chain
857e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
8584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector getLastSubSelector() {
8594ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) {
8604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD);
861e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(child.getLastSubSelector() == null) {
862e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return child;
863e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
864e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return child.getLastSubSelector();
8654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        } else if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) {
8664ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT);
867e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(parent.getLastSubSelector() == null) {
868e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return parent;
869e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
870e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return parent.getLastSubSelector();
871e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
872e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return this;
873e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
874e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
875e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    @Override
876e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    public String toString() {
877e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return dumpToString(true);
878e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
879e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
880e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String dumpToString(boolean all) {
881e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        StringBuilder builder = new StringBuilder();
8823d50587be8ff021369c90554d814839335b445b0Adam Momtaz        builder.append(UiSelector.class.getSimpleName() + "[");
883e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        final int criterionCount = mSelectorAttributes.size();
884e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for (int i = 0; i < criterionCount; i++) {
885e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if (i > 0) {
886e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append(", ");
887e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
888e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            final int criterion = mSelectorAttributes.keyAt(i);
889e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch (criterion) {
890e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_TEXT:
891e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("TEXT=").append(mSelectorAttributes.valueAt(i));
892e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
893ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_TEXT_REGEX:
894ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i));
895ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
896e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_TEXT:
897e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i));
898e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
899e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_TEXT:
900e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i));
901e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
902e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLASS:
903e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLASS=").append(mSelectorAttributes.valueAt(i));
904e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
905ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_CLASS_REGEX:
906ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i));
907ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
908e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_DESCRIPTION:
909e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
910e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
911ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_DESCRIPTION_REGEX:
912ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i));
913ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
914e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_DESCRIPTION:
915e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
916e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
917e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_DESCRIPTION:
918e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
919e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
920e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INDEX:
921e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INDEX=").append(mSelectorAttributes.valueAt(i));
922e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
923e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INSTANCE:
924e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i));
925e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
926e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ENABLED:
927e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i));
928e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
929e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSED:
930e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i));
931e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
932e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSABLE:
933e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i));
934e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
935e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SCROLLABLE:
936e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i));
937e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
938e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLICKABLE:
939e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i));
940e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
94197835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz            case SELECTOR_CHECKABLE:
94297835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                builder.append("CHECKABLE=").append(mSelectorAttributes.valueAt(i));
94397835f3a7c80b147136c44c175eb9e6a4261fd92Adam Momtaz                break;
944336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz            case SELECTOR_LONG_CLICKABLE:
945336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i));
946336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                break;
947e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHECKED:
948e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i));
949e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
950e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SELECTED:
951e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i));
952e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
953e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ID:
954e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ID=").append(mSelectorAttributes.valueAt(i));
955e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
956e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHILD:
957e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
958e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD=").append(mSelectorAttributes.valueAt(i));
959e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
960e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD[..]");
961e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
962e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PATTERN:
963e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
964e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i));
965e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
966e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN[..]");
967e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
968e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINER:
969e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
970e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i));
971e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
972e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER[..]");
973e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
974e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PARENT:
975e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
976e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT=").append(mSelectorAttributes.valueAt(i));
977e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
978e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT[..]");
979e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
980e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_COUNT:
981e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("COUNT=").append(mSelectorAttributes.valueAt(i));
982e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
983e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PACKAGE_NAME:
984e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i));
985e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
986ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_PACKAGE_NAME_REGEX:
987ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i));
988ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
989946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz            case SELECTOR_RESOURCE_ID:
990946d553eb162ee5ac4eeef2c91c40f36f3db791dAdam Momtaz                builder.append("RESOURCE_ID=").append(mSelectorAttributes.valueAt(i));
99189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                break;
992e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            default:
993e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i));
994e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
995e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
996e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        builder.append("]");
997e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return builder.toString();
998e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
999e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu}
1000