UiSelector.java revision 4ab790eccf6d5c27f542056b87d26d38f7caeeb3
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
25e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * text values, a content-description field, class name and multiple state
26e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * information like isSelected, isEnabled or isChecked. Additionally a UI element
27e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * may also be associated with a specific layout hierarchy that the test wishes
284ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * to use to unambiguously target one UI element distinguishing it from other
294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * similar elements.
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;
56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>();
58e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    public static final String LOG_TAG = "ByClass";
59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector() {
61e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
62e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
634ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    protected UiSelector(UiSelector by) {
64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        mSelectorAttributes = by.cloneSelectors().mSelectorAttributes;
65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
66e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
674ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    protected UiSelector cloneSelectors() {
684ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector ret = new UiSelector();
69e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        ret.mSelectorAttributes = mSelectorAttributes.clone();
70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return ret;
71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
734ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector selector) {
74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(!selector.hasPatternSelector()) {
754ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector().patternSelector(selector);
76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
77e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return selector;
78e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
79e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
804ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    static UiSelector patternBuilder(UiSelector container, UiSelector pattern) {
814ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return new UiSelector(
824ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                new UiSelector().containerSelector(container).patternSelector(pattern));
83e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
84e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
854ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector text(String text) {
86e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_TEXT, text);
87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
894ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textStartsWith(String text) {
90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_TEXT, text);
91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
934ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector textContains(String text) {
94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_TEXT, text);
95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
974ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector className(String className) {
98e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLASS, className);
99e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1014ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector description(String desc) {
102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_DESCRIPTION, desc);
103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
104e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1054ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionStartsWith(String desc) {
106e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_START_DESCRIPTION, desc);
107e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
108e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1094ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector descriptionContains(String desc) {
110e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
111e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
112e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1134ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector index(final int index) {
114e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INDEX, index);
115e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector instance(final int instance) {
118e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_INSTANCE, instance);
119e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
120e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1214ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector enabled(boolean val) {
122e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_ENABLED, val);
123e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
124e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1254ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focused(boolean val) {
126e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSED, val);
127e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
128e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector focusable(boolean val) {
130e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_FOCUSABLE, val);
131e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
132e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector scrollable(boolean val) {
134e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SCROLLABLE, val);
135e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
136e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1374ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector selected(boolean val) {
138e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_SELECTED, val);
139e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
140e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1414ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector checked(boolean val) {
142e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CHECKED, val);
143e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
144e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1454ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector clickable(boolean val) {
146e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CLICKABLE, val);
147e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
148e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector childSelector(UiSelector by) {
150e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CHILD, by);
151e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
152e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1534ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector patternSelector(UiSelector by) {
154e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_PATTERN, by);
155e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
156e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1574ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector containerSelector(UiSelector by) {
158e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_CONTAINER, by);
159e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
160e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1614ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector fromParent(UiSelector by) {
162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_PARENT, by);
163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
164e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    public UiSelector packageName(String name) {
166e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return buildSelector(SELECTOR_PACKAGE_NAME, name);
167e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
168e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
169e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
170e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Building a By selector always returns a new By selector and never modifies the
171e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * existing By selector being used. For example a test library have predefined
172e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * By selectors SA, SB, SC etc. The test may decide that it needs a By selector SX in the
173e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * context of SB. It can use SX = SB.critereon(x) to generate SX without modifying the
174e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * state of SB which is expected to be something else. For this we will return a new
175e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * By selector every time.
176e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
1774ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector buildSelector(int selectorId, Object selectorValue) {
1784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector by = new UiSelector(this);
179e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT)
180e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            by.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue);
181e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        else
182e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            by.mSelectorAttributes.put(selectorId, selectorValue);
183e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return by;
184e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
185e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
186e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
187e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Selectors may have a hierarchy defined by specifying child nodes to be matched.
188e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * It is not necessary that every selector have more than one level. A selector
189e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * can also be a single level referencing only one node. In such cases the return
190e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * it null.
191e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return a child selector if one exists. Else null if this selector does not
192e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * reference child node.
193e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
194e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
1954ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getChildSelector() {
1964ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector by = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null);
197e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(by != null)
1984ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector(by);
199e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
200e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
201e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
2024ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getPatternSelector() {
2034ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector by = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null);
204e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(by != null)
2054ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector(by);
206e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
207e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
208e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
2094ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getContainerSelector() {
2104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector by = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null);
211e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(by != null)
2124ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector(by);
213e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
214e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
215e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
2164ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    UiSelector getParentSelector() {
2174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        UiSelector by = (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null);
218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if(by != null)
2194ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            return new UiSelector(by);
220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return null;
221e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
222e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
223e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInstance() {
2244ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        return getInt(UiSelector.SELECTOR_INSTANCE);
225e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
226e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
227e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String getString(int criterion) {
228e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (String) mSelectorAttributes.get(criterion, null);
229e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
230e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
231e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean getBoolean(int criterion) {
232e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Boolean) mSelectorAttributes.get(criterion, false);
233e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
234e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
235e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    int getInt(int criterion) {
236e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return (Integer) mSelectorAttributes.get(criterion, 0);
237e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
238e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
239e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isMatchFor(AccessibilityNodeInfo node, int index) {
240e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int size = mSelectorAttributes.size();
241e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for(int x = 0; x < size; x++) {
242e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            CharSequence s = null;
243e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            int criterion = mSelectorAttributes.keyAt(x);
244e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch(criterion) {
2454ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_INDEX:
246e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(index != this.getInt(criterion))
247e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
248e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CHECKED:
250e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isChecked() != getBoolean(criterion)) {
251e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
252e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
253e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2544ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLASS:
255e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getClassName();
256e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (s == null || !s.toString().contentEquals(getString(criterion))) {
257e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
258e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
259e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CLICKABLE:
261e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if (node.isClickable() != getBoolean(criterion)) {
262e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
263e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
264e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_DESCRIPTION:
266e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
267e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
268e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
269e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
270e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
271e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2724ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_DESCRIPTION:
273e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
274e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
275e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
276e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
277e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
278e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2794ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_DESCRIPTION:
280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getContentDescription();
281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
282e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
283e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
284e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2854ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_CONTAINS_TEXT:
286e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
287e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
288e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .contains(getString(criterion).toLowerCase())) {
289e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
290e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
291e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2924ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_START_TEXT:
293e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
294e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().toLowerCase()
295e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                        .startsWith(getString(criterion).toLowerCase())) {
296e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
297e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
298e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
2994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_TEXT:
300e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getText();
301e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
302e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
303e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
304e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3054ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ENABLED:
306e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isEnabled() != getBoolean(criterion)) {
307e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
308e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
309e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSABLE:
311e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocusable() != getBoolean(criterion)) {
312e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
313e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
314e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_FOCUSED:
316e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isFocused() != getBoolean(criterion)) {
317e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
318e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
319e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3204ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_ID:
321e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break; //TODO: do we need this for AccessibilityNodeInfo.id?
3224ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_PACKAGE_NAME:
323e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                s = node.getPackageName();
324e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(s == null || !s.toString().contentEquals(getString(criterion))) {
325e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
326e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
327e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3284ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SCROLLABLE:
329e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isScrollable() != getBoolean(criterion)) {
330e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
331e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
332e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
3334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            case UiSelector.SELECTOR_SELECTED:
334e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(node.isSelected() != getBoolean(criterion)) {
335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    return false;
336e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
337e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
338e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
339e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
340e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return matchOrUpdateInstance();
341e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
342e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
343e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private boolean matchOrUpdateInstance() {
344e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorCounter = 0;
345e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        int currentSelectorInstance = 0;
346e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
347e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // matched attributes - now check for matching instance number
3484ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) > 0) {
3494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorInstance =
3504ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                    (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE);
351e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
352e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
353e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // instance is required. Add count if not already counting
3544ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) > 0) {
3554ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT);
356e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
357e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
358e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Verify
359e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance == currentSelectorCounter) {
360e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
361e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
362e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        // Update count
363e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        if (currentSelectorInstance > currentSelectorCounter) {
3644ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter);
365e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
366e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
367e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
368e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
369e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
370e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Leaf selector indicates no more child or parent selectors
371e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * are declared in the this selector.
372e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return true if is leaf.
373e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
374e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean isLeaf() {
3754ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 &&
3764ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz                mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
377e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return true;
378e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
379e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return false;
380e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
381e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
382e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasChildSelector() {
3834ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) {
384e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
385e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
386e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
387e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
388e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
389e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasPatternSelector() {
3904ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) {
391e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
392e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
393e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
394e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
395e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
396e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasContainerSelector() {
3974ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) {
398e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
399e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
400e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
401e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
402e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
403e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    boolean hasParentSelector() {
4044ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
405e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return false;
406e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
407e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return true;
408e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
409e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
410e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    /**
411e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * Returns the deepest selector in the chain of possible sub selectors.
4124ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)}
4134ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz     * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of
414e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * a selector.
415e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     * @return last By selector in chain
416e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu     */
4174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz    private UiSelector getLastSubSelector() {
4184ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) {
4194ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD);
420e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(child.getLastSubSelector() == null) {
421e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return child;
422e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
423e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return child.getLastSubSelector();
4244ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz        } else if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) {
4254ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz            UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT);
426e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if(parent.getLastSubSelector() == null) {
427e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                return parent;
428e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
429e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            return parent.getLastSubSelector();
430e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
431e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return this;
432e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
433e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
434e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    @Override
435e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    public String toString() {
436e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return dumpToString(true);
437e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
438e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
439e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    String dumpToString(boolean all) {
440e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        StringBuilder builder = new StringBuilder();
441e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        builder.append("By[");
442e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        final int criterionCount = mSelectorAttributes.size();
443e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        for (int i = 0; i < criterionCount; i++) {
444e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            if (i > 0) {
445e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append(", ");
446e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
447e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            final int criterion = mSelectorAttributes.keyAt(i);
448e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            switch (criterion) {
449e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_TEXT:
450e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("TEXT=").append(mSelectorAttributes.valueAt(i));
451e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
452e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_TEXT:
453e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i));
454e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
455e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_TEXT:
456e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i));
457e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
458e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLASS:
459e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLASS=").append(mSelectorAttributes.valueAt(i));
460e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
461e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_DESCRIPTION:
462e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
463e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
464e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_START_DESCRIPTION:
465e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
466e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
467e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINS_DESCRIPTION:
468e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
469e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
470e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INDEX:
471e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INDEX=").append(mSelectorAttributes.valueAt(i));
472e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
473e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_INSTANCE:
474e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i));
475e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
476e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ENABLED:
477e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i));
478e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
479e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSED:
480e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i));
481e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
482e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_FOCUSABLE:
483e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i));
484e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
485e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SCROLLABLE:
486e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i));
487e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
488e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CLICKABLE:
489e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i));
490e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
491e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHECKED:
492e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i));
493e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
494e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_SELECTED:
495e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i));
496e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
497e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_ID:
498e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("ID=").append(mSelectorAttributes.valueAt(i));
499e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
500e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CHILD:
501e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
502e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD=").append(mSelectorAttributes.valueAt(i));
503e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
504e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CHILD[..]");
505e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
506e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PATTERN:
507e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
508e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i));
509e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
510e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PATTERN[..]");
511e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
512e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_CONTAINER:
513e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
514e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i));
515e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
516e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("CONTAINER[..]");
517e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
518e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PARENT:
519e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                if(all)
520e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT=").append(mSelectorAttributes.valueAt(i));
521e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                else
522e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                    builder.append("PARENT[..]");
523e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
524e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_COUNT:
525e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("COUNT=").append(mSelectorAttributes.valueAt(i));
526e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
527e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            case SELECTOR_PACKAGE_NAME:
528e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i));
529e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                break;
530e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            default:
531e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i));
532e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
533e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
534e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        builder.append("]");
535e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return builder.toString();
536e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
537e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu}
538