UiSelector.java revision 89f6117cb1fbeab3770106cf54e05af1f597be81
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;
6189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    static final int SELECTOR_VIEW_ID = 29;
62e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>();
64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
65dbba713661688a285e701a006ce2d199296ac328Guang Zhu    /**
66dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
67dbba713661688a285e701a006ce2d199296ac328Guang Zhu     */
684ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector() {
69e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
713d50587be8ff021369c90554d814839335b445b0Adam Momtaz    UiSelector(UiSelector selector) {
723d50587be8ff021369c90554d814839335b445b0Adam Momtaz        mSelectorAttributes = selector.cloneSelector().mSelectorAttributes;
73e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
75dbba713661688a285e701a006ce2d199296ac328Guang Zhu    /**
7679693ede92636fe6f3a6ec4dc049a438fd9504ffGuang Zhu     * @since API Level 17
77dbba713661688a285e701a006ce2d199296ac328Guang Zhu     */
783d50587be8ff021369c90554d814839335b445b0Adam Momtaz    protected UiSelector cloneSelector() {
794ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector ret = new UiSelector();
80e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        ret.mSelectorAttributes = mSelectorAttributes.clone();
813d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasChildSelector())
823d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector()));
833d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasParentSelector())
843d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector()));
853d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(hasPatternSelector())
863d50587be8ff021369c90554d814839335b445b0Adam Momtaz            ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector()));
87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return ret;
88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
904ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector selector) {
91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(!selector.hasPatternSelector()) {
924ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector().patternSelector(selector);
93e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return selector;
95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
974ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector container, UiSelector pattern) {
984ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return new UiSelector(
994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                new UiSelector().containerSelector(container).patternSelector(pattern));
100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
102a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
103a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the visible text displayed
104a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, the text label to launch an app).
105a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
106a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The text for the widget must match exactly
107a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
108a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-sensitive.
109a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
110a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param text Value to match
111a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
112dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
113a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1144ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector text(String text) {
115e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_TEXT, text);
116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
117e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
118a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
119ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the visible text displayed
120ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, the text label to launch an app).
121ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
122ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * The text for the widget must match exactly
123ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * with the string in your input argument.
124ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
1251893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
126ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
127dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
128ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
129ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector textMatches(String regex) {
130ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_TEXT_REGEX, regex);
131ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
132ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
133ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
134a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Text property is usually the widget's visible text on the display.
135a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
136a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adding this to the search criteria indicates that the search performed
137a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * should match a widget with text value starting with the text parameter.
138a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
139a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The matching will be case-insensitive.
140a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
141a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param text
142a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
143dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
144a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1454ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textStartsWith(String text) {
146e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_TEXT, text);
147e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
148e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
149a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
150a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the visible text displayed
151a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, the text label to launch an app).
152a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
153a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The text for the widget must contain the string in
154a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * your input argument. Matching is case-sensitive.
155a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
156a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param text Value to match
157a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
158dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
159a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textContains(String text) {
161e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_TEXT, text);
162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
164a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
165a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the class property
166a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for a widget (for example, "android.widget.Button").
167a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
168a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param className Value to match
169a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
170dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
171a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
1724ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector className(String className) {
173e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLASS, className);
174e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
175e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
176a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
177ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the class property
178ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, "android.widget.Button").
179ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
1801893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
181ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
182dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
183ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
184ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector classNameMatches(String regex) {
185ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_CLASS_REGEX, regex);
186ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
187ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
188ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
189ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the class property
190ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for a widget (for example, "android.widget.Button").
191ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
1921893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param type type
193ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
194dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
195ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
196ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public <T> UiSelector className(Class<T> type) {
197ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_CLASS, type.getName());
198ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
199ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
200ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
201a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
202a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
203a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
204a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
205a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
206a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
207a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
208a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must match exactly
209a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
210a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
211a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-sensitive.
212a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
213a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
214a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
215dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
216a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector description(String desc) {
218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_DESCRIPTION, desc);
219e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
221a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
222a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
223a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
224a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
225a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
226a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
227a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
228a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
229ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * for the widget must match exactly
230ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * with the string in your input argument.
231ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
2321893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
233ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
234dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
235ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
236ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector descriptionMatches(String regex) {
237ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_DESCRIPTION_REGEX, regex);
238ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
239ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
240ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
241ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the content-description
242ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * property for a widget.
243ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
244ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * The content-description is typically used
245ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * by the Android Accessibility framework to
246ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * provide an audio prompt for the widget when
247ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * the widget is selected. The content-description
248a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must start
249a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * with the string in your input argument.
250a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
251a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-insensitive.
252a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
253a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
254a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
255dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
256a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2574ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionStartsWith(String desc) {
258e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_DESCRIPTION, desc);
259e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
260e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
261a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
262a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the content-description
263a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * property for a widget.
264a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
265a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The content-description is typically used
266a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * by the Android Accessibility framework to
267a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * provide an audio prompt for the widget when
268a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the widget is selected. The content-description
269a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * for the widget must contain
270a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the string in your input argument.
271a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
272a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Matching is case-insensitive.
273a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
274a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param desc Value to match
275a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
276dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
277a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
2784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionContains(String desc) {
279e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
282a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
28389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * Set the search criteria to match the given view id.
28489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     *
28589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * @param desc Value to match
28689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * @return UiSelector with the specified search criteria
28789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     * @since API Level 18
28889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov     */
28989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public UiSelector viewId(String viewId) {
29089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return buildSelector(SELECTOR_VIEW_ID, viewId);
29189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    }
29289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov
29389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    /**
294a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the widget by its node
295a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * index in the layout hierarchy.
296a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
297a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The index value must be 0 or greater.
298a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
299a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Using the index can be unreliable and should only
300a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * be used as a last resort for matching. Instead,
301a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * consider using the {@link #instance(int)} method.
302a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
303a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param index Value to match
304a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
305dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
306a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3074ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector index(final int index) {
308e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INDEX, index);
309e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
310e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
311a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
312a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the
313a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * widget by its instance number.
314a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
315a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The instance value must be 0 or greater, where
316a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the first instance is 0.
317a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
318a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * For example, to simulate a user click on
319a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * the third image that is enabled in a UI screen, you
320a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * could specify a a search criteria where the instance is
321a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * 2, the {@link #className(String)} matches the image
322a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * widget class, and {@link #enabled(boolean)} is true.
323a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * The code would look like this:
324a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * <code>
325a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * new UiSelector().className("android.widget.ImageView")
326a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *    .enabled(true).instance(2);
327a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * </code>
328a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
329a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param instance Value to match
330a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
331dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
332a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector instance(final int instance) {
334e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INSTANCE, instance);
335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
336e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
337a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
338a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are enabled.
339a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
340a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
341a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
342a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
343a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
344a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
345a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
346a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
347a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
348a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
349a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
350dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
351a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3524ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector enabled(boolean val) {
353e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_ENABLED, val);
354e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
355e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
356a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
357a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that have focus.
358a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
359a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
360a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
361a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
362a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
363a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
364a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
365a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
366a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
367a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
368a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
369dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
370a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3714ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focused(boolean val) {
372e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSED, val);
373e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
374e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
375a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
376a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are focusable.
377a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
378a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
379a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
380a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
381a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
382a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
383a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
384a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
385a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
386a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
387a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
388dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
389a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
3904ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focusable(boolean val) {
391e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSABLE, val);
392e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
393e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
394a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
395a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are scrollable.
396a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
397a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
398a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
399a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
400a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
401a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
402a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
403a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
404a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
405a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
406a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
407dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
408a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4094ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector scrollable(boolean val) {
410e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SCROLLABLE, val);
411e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
412e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
413a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
414a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that
415a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * are currently selected.
416a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
417a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
418a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
419a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
420a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
421a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
422a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
423a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
424a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
425a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
426a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
427dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
428a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector selected(boolean val) {
430e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SELECTED, val);
431e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
432e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
433a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
434a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that
435a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * are currently checked (usually for checkboxes).
436a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
437a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
438a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
439a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
440a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
441a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
442a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
443a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
444a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
445a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
446a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
447dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
448a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector checked(boolean val) {
450e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CHECKED, val);
451e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
452e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
453a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
454a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match widgets that are clickable.
455a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
456a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Typically, using this search criteria alone is not useful.
457a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * You should also include additional criteria, such as text,
458a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * content-description, or the class name for a widget.
459a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
460a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * If no other search criteria is specified, and there is more
461a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * than one matching widget, the first widget in the tree
462a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * is selected.
463a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
464a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param val Value to match
465a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
466dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
467a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
4684ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector clickable(boolean val) {
469e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLICKABLE, val);
470e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
471e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
472a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
473336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * Set the search criteria to match widgets that are long-clickable.
474336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
475336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * Typically, using this search criteria alone is not useful.
476336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * You should also include additional criteria, such as text,
477336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * content-description, or the class name for a widget.
478336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
479336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * If no other search criteria is specified, and there is more
480336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * than one matching widget, the first widget in the tree
481336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * is selected.
482336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     *
483336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * @param val Value to match
484336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     * @return UiSelector with the specified search criteria
485dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
486336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz     */
487336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    public UiSelector longClickable(boolean val) {
488336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz        return buildSelector(SELECTOR_LONG_CLICKABLE, val);
489336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    }
490336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz
491336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz    /**
492a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adds a child UiSelector criteria to this selector.
493a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
494a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Use this selector to narrow the search scope to
495a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * child widgets under a specific parent widget.
496a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
497a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param selector
498a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
499dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
500a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5013d50587be8ff021369c90554d814839335b445b0Adam Momtaz    public UiSelector childSelector(UiSelector selector) {
5023d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_CHILD, selector);
503e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
504e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5053d50587be8ff021369c90554d814839335b445b0Adam Momtaz    private UiSelector patternSelector(UiSelector selector) {
5063d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_PATTERN, selector);
507e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
508e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5093d50587be8ff021369c90554d814839335b445b0Adam Momtaz    private UiSelector containerSelector(UiSelector selector) {
5103d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_CONTAINER, selector);
511e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
512e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
513a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
514a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Adds a child UiSelector criteria to this selector which is used to
515a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * start search from the parent widget.
516a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
517a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Use this selector to narrow the search scope to
518a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * sibling widgets as well all child widgets under a parent.
519a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
520a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param selector
521a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with this added search criterion
522dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
523a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5243d50587be8ff021369c90554d814839335b445b0Adam Momtaz    public UiSelector fromParent(UiSelector selector) {
5253d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return buildSelector(SELECTOR_PARENT, selector);
526e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
527e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
528a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz    /**
529a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * Set the search criteria to match the package name
530a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * of the application that contains the widget.
531a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
532a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @param name Value to match
533a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     * @return UiSelector with the specified search criteria
534dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 16
535a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     */
5364ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector packageName(String name) {
537e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_PACKAGE_NAME, name);
538e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
539e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
540e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
541ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * Set the search criteria to match the package name
542ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * of the application that contains the widget.
543ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     *
5441893caed0ad4e73b0676f206282d490c2d345316Thanh Le     * @param regex a regular expression
545ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     * @return UiSelector with the specified search criteria
546dbba713661688a285e701a006ce2d199296ac328Guang Zhu     * @since API Level 17
547ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz     */
548ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    public UiSelector packageNameMatches(String regex) {
549ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz        return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, regex);
550ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    }
551ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz
552ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz    /**
5533d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * Building a UiSelector always returns a new UiSelector and never modifies the
5543d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * existing UiSelector being used.
555e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
5564ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector buildSelector(int selectorId, Object selectorValue) {
5573d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector = new UiSelector(this);
558e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT)
5593d50587be8ff021369c90554d814839335b445b0Adam Momtaz            selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue);
560e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        else
5613d50587be8ff021369c90554d814839335b445b0Adam Momtaz            selector.mSelectorAttributes.put(selectorId, selectorValue);
5623d50587be8ff021369c90554d814839335b445b0Adam Momtaz        return selector;
563e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
564e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
565e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
566e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Selectors may have a hierarchy defined by specifying child nodes to be matched.
567e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * It is not necessary that every selector have more than one level. A selector
568e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * can also be a single level referencing only one node. In such cases the return
569e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * it null.
570a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz     *
571e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return a child selector if one exists. Else null if this selector does not
572e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * reference child node.
573e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
5744ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getChildSelector() {
5753d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null);
5763d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
5773d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
578e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
579e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
580e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5814ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getPatternSelector() {
5823d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
5833d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null);
5843d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
5853d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
586e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
587e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
588e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5894ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getContainerSelector() {
5903d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
5913d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null);
5923d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
5933d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
594e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
595e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
596e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
5974ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getParentSelector() {
5983d50587be8ff021369c90554d814839335b445b0Adam Momtaz        UiSelector selector =
5993d50587be8ff021369c90554d814839335b445b0Adam Momtaz                (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null);
6003d50587be8ff021369c90554d814839335b445b0Adam Momtaz        if(selector != null)
6013d50587be8ff021369c90554d814839335b445b0Adam Momtaz            return new UiSelector(selector);
602e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
603e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
604e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
605e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInstance() {
6064ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return getInt(UiSelector.SELECTOR_INSTANCE);
607e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
608e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
609e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String getString(int criterion) {
610e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (String) mSelectorAttributes.get(criterion, null);
611e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
612e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
613e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean getBoolean(int criterion) {
614e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Boolean) mSelectorAttributes.get(criterion, false);
615e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
616e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
617e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInt(int criterion) {
618e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Integer) mSelectorAttributes.get(criterion, 0);
619e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
620e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
621e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isMatchFor(AccessibilityNodeInfo node, int index) {
622e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int size = mSelectorAttributes.size();
623e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for(int x = 0; x < size; x++) {
624e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            CharSequence s = null;
625e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            int criterion = mSelectorAttributes.keyAt(x);
626e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch(criterion) {
6274ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_INDEX:
628e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(index != this.getInt(criterion))
629e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
630e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6314ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CHECKED:
632e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isChecked() != getBoolean(criterion)) {
633e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
634e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
635e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6364ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLASS:
637e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getClassName();
638e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (s == null || !s.toString().contentEquals(getString(criterion))) {
639e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
640e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
641e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
642ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_CLASS_REGEX:
643ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getClassName();
644ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if (s == null || !s.toString().matches(getString(criterion))) {
645ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
646ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
647ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
6484ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLICKABLE:
649e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isClickable() != getBoolean(criterion)) {
650e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
651e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
652e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
653336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz            case UiSelector.SELECTOR_LONG_CLICKABLE:
654336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                if (node.isLongClickable() != getBoolean(criterion)) {
655336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                    return false;
656336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                }
657336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                break;
6584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_DESCRIPTION:
659e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
660e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
661e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
662e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
663e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
664e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_DESCRIPTION:
666e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
667e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
668e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
669e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
670e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
671e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6724ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_DESCRIPTION:
673e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
674e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
675e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
676e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
677e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
678ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_DESCRIPTION_REGEX:
679ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getContentDescription();
680ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
681ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
682ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
683ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
6844ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_TEXT:
685e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
686e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
687e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
688e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
689e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
690e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6914ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_TEXT:
692e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
693e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
694e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
695e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
696e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
697e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
6984ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_TEXT:
699e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
700e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
701e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
702e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
703e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
704ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_TEXT_REGEX:
705ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getText();
706ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
707ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
708ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
709ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
7104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ENABLED:
711e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isEnabled() != getBoolean(criterion)) {
712e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
713e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
714e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSABLE:
716e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocusable() != getBoolean(criterion)) {
717e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
718e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
719e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7204ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSED:
721e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocused() != getBoolean(criterion)) {
722e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
723e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
724e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7254ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ID:
726e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break; //TODO: do we need this for AccessibilityNodeInfo.id?
7274ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_PACKAGE_NAME:
728e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getPackageName();
729e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
730e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
731e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
732e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
733ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case UiSelector.SELECTOR_PACKAGE_NAME_REGEX:
734ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                s = node.getPackageName();
735ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                if(s == null || !s.toString().matches(getString(criterion))) {
736ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                    return false;
737ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                }
738ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
7394ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SCROLLABLE:
740e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isScrollable() != getBoolean(criterion)) {
741e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
742e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
743e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
7444ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SELECTED:
745e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isSelected() != getBoolean(criterion)) {
746e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
747e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
748e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
74989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            case UiSelector.SELECTOR_VIEW_ID:
75089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                if (node.getViewId() != getString(criterion)) {
75189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                    return false;
75289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                }
75389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                break;
754e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
755e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
756e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return matchOrUpdateInstance();
757e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
758e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
759e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private boolean matchOrUpdateInstance() {
760e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorCounter = 0;
761e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorInstance = 0;
762e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
763e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // matched attributes - now check for matching instance number
7644ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) > 0) {
7654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorInstance =
7664ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                    (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE);
767e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
768e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
769e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // instance is required. Add count if not already counting
7704ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) > 0) {
7714ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT);
772e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
773e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
774e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Verify
775e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance == currentSelectorCounter) {
776e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
777e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
778e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Update count
779e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance > currentSelectorCounter) {
7804ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter);
781e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
782e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
783e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
784e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
785e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
786e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Leaf selector indicates no more child or parent selectors
787e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * are declared in the this selector.
788e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return true if is leaf.
789e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
790e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isLeaf() {
7914ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 &&
7924ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
793e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
794e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
795e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
796e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
797e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
798e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasChildSelector() {
7994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) {
800e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
801e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
802e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
803e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
804e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
805e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasPatternSelector() {
8064ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) {
807e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
808e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
809e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
810e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
811e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
812e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasContainerSelector() {
8134ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) {
814e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
815e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
816e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
817e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
818e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
819e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasParentSelector() {
8204ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
821e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
822e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
823e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
824e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
825e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
826e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
827e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Returns the deepest selector in the chain of possible sub selectors.
8284ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)}
8294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of
830e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * a selector.
8313d50587be8ff021369c90554d814839335b445b0Adam Momtaz     * @return last UiSelector in chain
832e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
8334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector getLastSubSelector() {
8344ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) {
8354ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD);
836e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(child.getLastSubSelector() == null) {
837e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return child;
838e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
839e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return child.getLastSubSelector();
8404ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        } else if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) {
8414ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT);
842e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(parent.getLastSubSelector() == null) {
843e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return parent;
844e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
845e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return parent.getLastSubSelector();
846e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
847e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return this;
848e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
849e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
850e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    @Override
851e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    public String toString() {
852e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return dumpToString(true);
853e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
854e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
855e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String dumpToString(boolean all) {
856e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        StringBuilder builder = new StringBuilder();
8573d50587be8ff021369c90554d814839335b445b0Adam Momtaz        builder.append(UiSelector.class.getSimpleName() + "[");
858e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        final int criterionCount = mSelectorAttributes.size();
859e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for (int i = 0; i < criterionCount; i++) {
860e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if (i > 0) {
861e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append(", ");
862e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
863e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            final int criterion = mSelectorAttributes.keyAt(i);
864e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch (criterion) {
865e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_TEXT:
866e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("TEXT=").append(mSelectorAttributes.valueAt(i));
867e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
868ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_TEXT_REGEX:
869ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i));
870ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
871e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_TEXT:
872e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i));
873e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
874e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_TEXT:
875e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i));
876e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
877e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLASS:
878e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLASS=").append(mSelectorAttributes.valueAt(i));
879e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
880ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_CLASS_REGEX:
881ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i));
882ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
883e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_DESCRIPTION:
884e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
885e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
886ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_DESCRIPTION_REGEX:
887ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i));
888ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
889e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_DESCRIPTION:
890e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
891e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
892e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_DESCRIPTION:
893e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
894e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
895e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INDEX:
896e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INDEX=").append(mSelectorAttributes.valueAt(i));
897e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
898e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INSTANCE:
899e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i));
900e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
901e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ENABLED:
902e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i));
903e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
904e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSED:
905e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i));
906e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
907e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSABLE:
908e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i));
909e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
910e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SCROLLABLE:
911e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i));
912e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
913e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLICKABLE:
914e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i));
915e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
916336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz            case SELECTOR_LONG_CLICKABLE:
917336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i));
918336d1a84909be8ec12af8bc27c65825b13ad9909Adam Momtaz                break;
919e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHECKED:
920e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i));
921e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
922e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SELECTED:
923e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i));
924e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
925e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ID:
926e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ID=").append(mSelectorAttributes.valueAt(i));
927e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
928e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHILD:
929e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
930e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD=").append(mSelectorAttributes.valueAt(i));
931e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
932e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD[..]");
933e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
934e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PATTERN:
935e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
936e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i));
937e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
938e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN[..]");
939e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
940e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINER:
941e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
942e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i));
943e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
944e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER[..]");
945e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
946e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PARENT:
947e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
948e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT=").append(mSelectorAttributes.valueAt(i));
949e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
950e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT[..]");
951e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
952e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_COUNT:
953e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("COUNT=").append(mSelectorAttributes.valueAt(i));
954e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
955e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PACKAGE_NAME:
956e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i));
957e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
958ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz            case SELECTOR_PACKAGE_NAME_REGEX:
959ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i));
960ee4b48cd50f6e4e24ba7f538b8a77c839c1087f5Adam Momtaz                break;
96189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            case SELECTOR_VIEW_ID:
96289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                builder.append("VIEW_ID=").append(mSelectorAttributes.valueAt(i));
96389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                break;
964e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            default:
965e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i));
966e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
967e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
968e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        builder.append("]");
969e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return builder.toString();
970e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
971e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu}
972