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