18643aa0179e598e78d938c59035389054535a229Svetoslav Ganov/**
28643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Copyright (C) 2011 The Android Open Source Project
38643aa0179e598e78d938c59035389054535a229Svetoslav Ganov *
48643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
58643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * in compliance with the License. You may obtain a copy of the License at
68643aa0179e598e78d938c59035389054535a229Svetoslav Ganov *
78643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0
88643aa0179e598e78d938c59035389054535a229Svetoslav Ganov *
98643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software distributed under the
108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
118643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * express or implied. See the License for the specific language governing permissions and
128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * limitations under the License.
138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */
148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
158643aa0179e598e78d938c59035389054535a229Svetoslav Ganovpackage android.accessibilityservice;
168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
178643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
1879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganovimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
198643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
2079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganovimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
228643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.graphics.Rect;
238643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.os.SystemClock;
248643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.test.ActivityInstrumentationTestCase2;
258643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.test.suitebuilder.annotation.LargeTest;
26eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganovimport android.util.Log;
278643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
288643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
30b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganovimport com.android.frameworks.coretests.R;
3179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganovimport com.android.internal.util.Predicate;
32b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov
338643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.ArrayList;
348643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.LinkedList;
358643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.List;
368643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.Queue;
378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
388643aa0179e598e78d938c59035389054535a229Svetoslav Ganov/**
398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Activity for testing the accessibility APIs for "interrogation" of
408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * the screen content. These APIs allow exploring the screen and
418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * requesting an action to be performed on a given view from an
428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * AccessiiblityService.
438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */
448643aa0179e598e78d938c59035389054535a229Svetoslav Ganovpublic class InterrogationActivityTest
458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        extends ActivityInstrumentationTestCase2<InterrogationActivity> {
4679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    private static final boolean DEBUG = false;
47eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov
48eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov    private static String LOG_TAG = "InterrogationActivityTest";
498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
50d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    // Timeout for the accessibility state of an Activity to be fully initialized.
5179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    private static final int TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS = 5000;
52d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
530d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    // Timeout for which non getting accessibility events considers the app idle.
540d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    private static final long IDLE_EVENT_TIME_DELTA_MILLIS = 200;
550d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov
560d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    // Timeout in which to wait for idle device.
570d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    private static final long GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS = 1000;
580d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov
598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    // Handle to a connection to the AccessibilityManagerService
6079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    private UiTestAutomationBridge mUiTestAutomationBridge;
618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public InterrogationActivityTest() {
638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        super(InterrogationActivity.class);
648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
658643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
66d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    @Override
67d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    public void setUp() throws Exception {
6879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        super.setUp();
6979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        mUiTestAutomationBridge = new UiTestAutomationBridge();
7079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        mUiTestAutomationBridge.connect();
710d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov        mUiTestAutomationBridge.waitForIdle(IDLE_EVENT_TIME_DELTA_MILLIS,
720d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov                GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS);
7379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        mUiTestAutomationBridge.executeCommandAndWaitForAccessibilityEvent(new Runnable() {
7479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                // wait for the first accessibility event
7579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                @Override
7679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                public void run() {
7779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    // bring up the activity
7879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    getActivity();
7979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                }
8079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            },
8179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            new Predicate<AccessibilityEvent>() {
8279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                @Override
8379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                public boolean apply(AccessibilityEvent event) {
8479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    return (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
8579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                            && event.getPackageName().equals(getActivity().getPackageName()));
8679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                }
8779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            },
8879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
8979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    }
9079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
9179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    @Override
9279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    public void tearDown() throws Exception {
9379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        mUiTestAutomationBridge.disconnect();
9479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        super.tearDown();
95d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    }
96d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testFindAccessibilityNodeInfoByViewId() throws Exception {
99eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
1008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
10179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
10279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
1038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertNotNull(button);
1048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(0, button.getChildCount());
1058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // bounds
1078643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Rect bounds = new Rect();
108eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            button.getBoundsInParent(bounds);
1098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(0, bounds.left);
1108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(0, bounds.top);
1118bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            assertEquals(160, bounds.right);
1128bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            assertEquals(100, bounds.bottom);
1138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // char sequence attributes
1158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals("com.android.frameworks.coretests", button.getPackageName());
1168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals("android.widget.Button", button.getClassName());
1178643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals("Button5", button.getText());
1188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertNull(button.getContentDescription());
1198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // boolean attributes
1218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isFocusable());
1228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isClickable());
1238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isEnabled());
1248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isFocused());
1258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isClickable());
1268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isPassword());
1278643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isSelected());
1288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isCheckable());
1298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isChecked());
1308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // actions
1328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(ACTION_FOCUS | ACTION_SELECT | ACTION_CLEAR_SELECTION,
1338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                button.getActions());
1348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
135eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
136eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
137eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewId: "
138eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                        + elapsedTimeMillis + "ms");
139eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
1408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
1418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
1428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
1448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testFindAccessibilityNodeInfoByViewText() throws Exception {
145eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
1468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
1478643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view by text
14879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
14979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfosByTextInActiveWindow("butto");
1508643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(9, buttons.size());
1518643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
152eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
153eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
154eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewText: "
155eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                        + elapsedTimeMillis + "ms");
156eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
1578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
1588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
1598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
161ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov    public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
162ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
163ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov        try {
164ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov            // find a view by text
16579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
16679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfosByTextInActiveWindow("contentDescription");
167ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov            assertEquals(1, buttons.size());
168ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov        } finally {
169ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov            if (DEBUG) {
170ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
171ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: "
172ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov                        + elapsedTimeMillis + "ms");
173ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov            }
174ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov        }
175ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov    }
176ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov
177ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov    @LargeTest
1788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testTraverseAllViews() throws Exception {
179eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
1808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
1818643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // make list of expected nodes
1828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            List<String> classNameAndTextList = new ArrayList<String>();
1838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.LinearLayout");
1848643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.LinearLayout");
1858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.LinearLayout");
1868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.LinearLayout");
1878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton1");
1888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton2");
1898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton3");
1908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton4");
1918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton5");
1928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton6");
1938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton7");
1948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton8");
1958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            classNameAndTextList.add("android.widget.ButtonButton9");
1968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
19779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo root = mUiTestAutomationBridge
19879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
1998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertNotNull("We must find the existing root.", root);
2008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
2028643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            fringe.add(root);
2038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // do a BFS traversal and check nodes
2058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            while (!fringe.isEmpty()) {
2068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                AccessibilityNodeInfo current = fringe.poll();
2078643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2088643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                CharSequence className = current.getClassName();
2098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                CharSequence text = current.getText();
2108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                String receivedClassNameAndText = className.toString()
2118643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                   + ((text != null) ? text.toString() : "");
2128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                String expectedClassNameAndText = classNameAndTextList.remove(0);
2138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                assertEquals("Did not get the expected node info",
2158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                        expectedClassNameAndText, receivedClassNameAndText);
2168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2178643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                final int childCount = current.getChildCount();
2188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                for (int i = 0; i < childCount; i++) {
2198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                    AccessibilityNodeInfo child = current.getChild(i);
2208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                    fringe.add(child);
2218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
2228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
2238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
224eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
225eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
226eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testTraverseAllViews: " + elapsedTimeMillis + "ms");
227eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
2288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
2298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
2308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
2328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testPerformAccessibilityActionFocus() throws Exception {
233eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
2348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
2358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view and make sure it is not focused
23679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
23779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2388643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isFocused());
2398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // focus the view
2418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_FOCUS));
2428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is focused
24479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
24579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isFocused());
2478643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
248eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
249eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
250eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testPerformAccessibilityActionFocus: " + elapsedTimeMillis + "ms");
251eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
2528643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
2538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
2548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
2568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testPerformAccessibilityActionClearFocus() throws Exception {
257eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
2588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
2598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view and make sure it is not focused
26079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
26179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isFocused());
2638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // focus the view
2658643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_FOCUS));
2668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is focused
26879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
26979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2708643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isFocused());
2718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // unfocus the view
2738643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
2748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is not focused
27679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
27779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isFocused());
2798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
280eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
281eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
282eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testPerformAccessibilityActionClearFocus: "
283eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                        + elapsedTimeMillis + "ms");
284eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
2858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
2868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
2878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
2898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testPerformAccessibilityActionSelect() throws Exception {
290eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
2918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
2928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view and make sure it is not selected
29379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
29479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
2958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isSelected());
2968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // select the view
2988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_SELECT));
2998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is selected
30179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
30279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
3038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isSelected());
3048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
305eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
306eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
307eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testPerformAccessibilityActionSelect: " + elapsedTimeMillis + "ms");
308eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
3098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
3108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
3118643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
3138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testPerformAccessibilityActionClearSelection() throws Exception {
314eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
3158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
3168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view and make sure it is not selected
31779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
31879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
3198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isSelected());
3208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // select the view
3228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_SELECT));
3238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is selected
32579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
32679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
3278643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.isSelected());
3288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // unselect the view
3308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
3318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find the view again and make sure it is not selected
33379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            button = mUiTestAutomationBridge
33479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
3358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertFalse(button.isSelected());
3368643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
337eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
338eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
339eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testPerformAccessibilityActionClearSelection: "
340eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                        + elapsedTimeMillis + "ms");
341eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
3428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
3438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
3448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @LargeTest
3468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void testAccessibilityEventGetSource() throws Exception {
347eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
3488643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
3498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // find a view and make sure it is not focused
35079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            final AccessibilityNodeInfo button = mUiTestAutomationBridge
35179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
35279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            assertFalse(button.isFocused());
353601ad8061cb8dcf3ab7385fa9e9dd13f15dc8eceSvetoslav Ganov
35479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityEvent event = mUiTestAutomationBridge
35579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
35679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                @Override
35779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                public void run() {
35879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    // focus the view
35979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    assertTrue(button.performAction(ACTION_FOCUS));
360601ad8061cb8dcf3ab7385fa9e9dd13f15dc8eceSvetoslav Ganov                }
36179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            },
36279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            new Predicate<AccessibilityEvent>() {
36379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                @Override
36479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                public boolean apply(AccessibilityEvent event) {
36579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED
36679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                            && event.getPackageName().equals(getActivity().getPackageName())
36779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                            && event.getText().get(0).equals(button.getText()));
36879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                }
36979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            },
37079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
37179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
37279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            // check the last event
37379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            assertNotNull(event);
3748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // check that last event source
37679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo source = event.getSource();
3778643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertNotNull(source);
3788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // bounds
3808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Rect buttonBounds = new Rect();
381eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            button.getBoundsInParent(buttonBounds);
3828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Rect sourceBounds = new Rect();
383eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            source.getBoundsInParent(sourceBounds);
3848643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(buttonBounds.left, sourceBounds.left);
3868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(buttonBounds.right, sourceBounds.right);
3878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(buttonBounds.top, sourceBounds.top);
3888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(buttonBounds.bottom, sourceBounds.bottom);
3898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // char sequence attributes
3918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(button.getPackageName(), source.getPackageName());
3928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(button.getClassName(), source.getClassName());
3938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertEquals(button.getText(), source.getText());
3948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.getContentDescription(), source.getContentDescription());
3958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            // boolean attributes
3978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isFocusable(), source.isFocusable());
3988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isClickable(), source.isClickable());
3998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isEnabled(), source.isEnabled());
4008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertNotSame(button.isFocused(), source.isFocused());
4018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isLongClickable(), source.isLongClickable());
4028643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isPassword(), source.isPassword());
4038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isSelected(), source.isSelected());
4048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isCheckable(), source.isCheckable());
4058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            assertSame(button.isChecked(), source.isChecked());
4068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } finally {
407eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
408eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
409eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testAccessibilityEventGetSource: " + elapsedTimeMillis + "ms");
410eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
411eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        }
412eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov    }
413eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov
414eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov    @LargeTest
415eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov    public void testObjectContract() throws Exception {
416eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
417eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        try {
418eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            // find a view and make sure it is not focused
41979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityNodeInfo button = mUiTestAutomationBridge
42079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
42179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            assertNotNull(button);
422eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            AccessibilityNodeInfo parent = button.getParent();
423eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            final int childCount = parent.getChildCount();
424eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            for (int i = 0; i < childCount; i++) {
425eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                AccessibilityNodeInfo child = parent.getChild(i);
426eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                assertNotNull(child);
427eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                if (child.equals(button)) {
428eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                    assertEquals("Equal objects must have same hasCode.", button.hashCode(),
429eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                            child.hashCode());
430eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                    return;
431eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                }
432eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
433eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            fail("Parent's children do not have the info whose parent is the parent.");
434eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        } finally {
435eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            if (DEBUG) {
436eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
437eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                Log.i(LOG_TAG, "testObjectContract: " + elapsedTimeMillis + "ms");
438eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
4398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
4408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
441b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov
442b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov    @LargeTest
443b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov    public void testGetRootAccessibilityNodeInfoInActiveWindow() throws Exception {
444b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov        final long startTimeMillis = SystemClock.uptimeMillis();
445b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov        try {
446b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            // get the root via the designated API
447b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            AccessibilityNodeInfo fetched = mUiTestAutomationBridge
448b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                    .getRootAccessibilityNodeInfoInActiveWindow();
449b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            assertNotNull(fetched);
450b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov
451b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            // get the root via traversal
452b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            AccessibilityNodeInfo expected = mUiTestAutomationBridge
453b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                    .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
454b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            while (true) {
455b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                AccessibilityNodeInfo parent = expected.getParent();
456b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                if (parent == null) {
457b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                    break;
458b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                }
459b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                expected = parent;
460b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            }
461b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            assertNotNull(expected);
462b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov
463b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            assertEquals("The node with id \"root\" should be the root.", expected, fetched);
464b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov        } finally {
465b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            if (DEBUG) {
466b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
467b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                Log.i(LOG_TAG, "testGetRootAccessibilityNodeInfoInActiveWindow: "
468b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov                        + elapsedTimeMillis + "ms");
469b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov            }
470b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov        }
471b765db590ff824fb5827fb773b14ac4286ae2774Svetoslav Ganov    }
4728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov}
473