1ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu/*
2ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * Copyright (C) 2012 The Android Open Source Project
3ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu *
4ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License");
5ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * you may not use this file except in compliance with the License.
6ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * You may obtain a copy of the License at
7ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu *
8ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu *      http://www.apache.org/licenses/LICENSE-2.0
9ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu *
10ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * Unless required by applicable law or agreed to in writing, software
11ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS,
12ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * See the License for the specific language governing permissions and
14ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu * limitations under the License.
15ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu */
16ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhupackage com.android.uiautomator.core;
17ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
18ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu/**
19fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz * Used to enumerate a container's UI elements for the purpose of counting,
20fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz * or targeting a sub elements by a child's text or description.
21d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu * @since API Level 16
22ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu */
23ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhupublic class UiCollection extends UiObject {
24ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
25d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu    /**
26d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * Constructs an instance as described by the selector
27d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     *
28d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @param selector
29d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @since API Level 16
30d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     */
31dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz    public UiCollection(UiSelector selector) {
32ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        super(selector);
33ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    }
34ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
35ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    /**
36dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
37fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * selector.
38fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     *
39fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * It looks for any child matching the <code>childPattern</code> argument that has
40ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * a child UI element anywhere within its sub hierarchy that has content-description text.
41ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * The returned UiObject will point at the <code>childPattern</code> instance that matched the
42ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * search and not at the identifying child element that matched the content description.</p>
43f38e3f7321e4999bf92ddd6db5d5009f2e9801a2Adam Momtaz     *
44dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
45ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @param text String of the identifying child contents of of the <code>childPattern</code>
46ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
47ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @throws UiObjectNotFoundException
48d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @since API Level 16
49ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     */
50dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz    public UiObject getChildByDescription(UiSelector childPattern, String text)
51ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            throws UiObjectNotFoundException {
52b04f3c526835516b098227342e741b7ce944c2f3Maxim Siniavine        Tracer.trace(childPattern, text);
53ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        if (text != null) {
54ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            int count = getChildCount(childPattern);
55ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            for (int x = 0; x < count; x++) {
56ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                UiObject row = getChildByInstance(childPattern, x);
57ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                String nodeDesc = row.getContentDescription();
58ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                if(nodeDesc != null && nodeDesc.contains(text)) {
59ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                    return row;
60ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                }
61dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz                UiObject item = row.getChild(new UiSelector().descriptionContains(text));
62ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                if (item.exists()) {
63ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                    return row;
64ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                }
65ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            }
66ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        }
67ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        throw new UiObjectNotFoundException("for description= \"" + text + "\"");
68ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    }
69ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
70ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    /**
71dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
72fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * selector.
73fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     *
74fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * It looks for any child matching the <code>childPattern</code> argument that has
75ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * a child UI element anywhere within its sub hierarchy that is at the <code>instance</code>
76ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * specified. The operation is performed only on the visible items and no scrolling is performed
77ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * in this case.
78f38e3f7321e4999bf92ddd6db5d5009f2e9801a2Adam Momtaz     *
79dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
80ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @param instance int the desired matched instance of this <code>childPattern</code>
81ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
82d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @since API Level 16
83ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     */
84dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz    public UiObject getChildByInstance(UiSelector childPattern, int instance)
85ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            throws UiObjectNotFoundException {
86b04f3c526835516b098227342e741b7ce944c2f3Maxim Siniavine        Tracer.trace(childPattern, instance);
87dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz        UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
88dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz                UiSelector.patternBuilder(childPattern).instance(instance));
89ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        return new UiObject(patternSelector);
90ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    }
91ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
92ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    /**
93dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
94fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * selector.
95fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     *
96fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * It looks for any child matching the <code>childPattern</code> argument that has
97ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * a child UI element anywhere within its sub hierarchy that has text attribute =
98ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * <code>text</code>. The returned UiObject will point at the <code>childPattern</code>
99ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * instance that matched the search and not at the identifying child element that matched the
100ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * text attribute.</p>
101f38e3f7321e4999bf92ddd6db5d5009f2e9801a2Adam Momtaz     *
102dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
103ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @param text String of the identifying child contents of of the <code>childPattern</code>
104ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
105ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @throws UiObjectNotFoundException
106d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @since API Level 16
107ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     */
108dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz    public UiObject getChildByText(UiSelector childPattern, String text)
109ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            throws UiObjectNotFoundException {
110b04f3c526835516b098227342e741b7ce944c2f3Maxim Siniavine        Tracer.trace(childPattern, text);
111ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        if (text != null) {
112ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            int count = getChildCount(childPattern);
113ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            for (int x = 0; x < count; x++) {
114ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                UiObject row = getChildByInstance(childPattern, x);
115ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                String nodeText = row.getText();
116ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                if(text.equals(nodeText)) {
117ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                    return row;
118ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                }
119dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz                UiObject item = row.getChild(new UiSelector().text(text));
120ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                if (item.exists()) {
121ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                    return row;
122ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu                }
123ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu            }
124ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        }
125ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        throw new UiObjectNotFoundException("for text= \"" + text + "\"");
126ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    }
127ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu
128ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    /**
129fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * Counts child UI element instances matching the <code>childPattern</code>
130fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * argument. The method returns the number of matching UI elements that are
131fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * currently visible.  The count does not include items of a scrollable list
132fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * that are off-screen.
133f38e3f7321e4999bf92ddd6db5d5009f2e9801a2Adam Momtaz     *
134fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * @param childPattern a {@link UiSelector} that represents the matching child UI
135fbcc9c7c6df14a11e92f5c2553069e3333710896Adam Momtaz     * elements to count
136ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     * @return the number of matched childPattern under the current {@link UiCollection}
137d6b7eab5d1cf65a31aeebacc4a842e836ba5817cGuang Zhu     * @since API Level 16
138ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu     */
139dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz    public int getChildCount(UiSelector childPattern) {
140b04f3c526835516b098227342e741b7ce944c2f3Maxim Siniavine        Tracer.trace(childPattern);
141dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz        UiSelector patternSelector =
142dc45c6d0e77da06314f5454211d2e683a32b3b24Adam Momtaz                UiSelector.patternBuilder(getSelector(), UiSelector.patternBuilder(childPattern));
143ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu        return getQueryController().getPatternCount(patternSelector);
144ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu    }
145ff763316cdb1986d8668ca3011cbb892b43aab93Guang Zhu}
146