1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.car.rotary;
17 
18 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD;
19 import static android.view.accessibility.AccessibilityNodeInfo.FOCUS_INPUT;
20 
21 import static com.android.car.rotary.Utils.FOCUS_AREA_CLASS_NAME;
22 import static com.android.car.rotary.Utils.FOCUS_PARKING_VIEW_CLASS_NAME;
23 import static com.android.car.rotary.Utils.GENERIC_FOCUS_PARKING_VIEW_CLASS_NAME;
24 import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_BOTTOM_BOUND_OFFSET;
25 import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_LEFT_BOUND_OFFSET;
26 import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_RIGHT_BOUND_OFFSET;
27 import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_TOP_BOUND_OFFSET;
28 import static com.android.car.ui.utils.RotaryConstants.ROTARY_CONTAINER;
29 import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
30 
31 import static com.google.common.truth.Truth.assertThat;
32 
33 import android.graphics.Rect;
34 import android.os.Bundle;
35 import android.view.accessibility.AccessibilityNodeInfo;
36 import android.view.accessibility.AccessibilityWindowInfo;
37 
38 import androidx.test.ext.junit.runners.AndroidJUnit4;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.ArrayList;
45 
46 @RunWith(AndroidJUnit4.class)
47 public class NodeBuilderTest {
48     private static final String PACKAGE_NAME = "package_name";
49     private static final String CLASS_NAME = "class_name";
50     private static final String CONTENT_DESCRIPTION = "content_description";
51     private static final String STATE_DESCRIPTION = "state_description";
52     private NodeBuilder mNodeBuilder;
53 
54     @Before
setUp()55     public void setUp() {
56         mNodeBuilder = new NodeBuilder(new ArrayList<>());
57     }
58 
59     @Test
testBuildDefaultNode()60     public void testBuildDefaultNode() {
61         AccessibilityNodeInfo node = mNodeBuilder.build();
62         assertThat(node.isFocusable()).isTrue();
63         assertThat(node.isFocused()).isFalse();
64         assertThat(node.isVisibleToUser()).isTrue();
65         assertThat(node.refresh()).isTrue();
66         assertThat(node.isEnabled()).isTrue();
67         assertThat(node.isScrollable()).isFalse();
68         Rect boundsInParent = new Rect();
69         node.getBoundsInParent(boundsInParent);
70         assertThat(boundsInParent.isEmpty()).isFalse();
71         Rect boundsInScreen = new Rect();
72         node.getBoundsInScreen(boundsInScreen);
73         assertThat(boundsInScreen).isEqualTo(NodeBuilder.DEFAULT_BOUNDS);
74         assertThat(node.getBoundsInScreen()).isEqualTo(NodeBuilder.DEFAULT_BOUNDS);
75         assertThat(node.isCheckable()).isFalse();
76     }
77 
78     @Test
testSetFocusable()79     public void testSetFocusable() {
80         AccessibilityNodeInfo node = mNodeBuilder.setFocusable(false).build();
81         assertThat(node.isFocusable()).isFalse();
82     }
83 
84     @Test
testSetFocused()85     public void testSetFocused() {
86         AccessibilityNodeInfo node = mNodeBuilder.setFocused(true).build();
87         assertThat(node.isFocused()).isTrue();
88     }
89 
90     @Test
testSetVisibleToUser()91     public void testSetVisibleToUser() {
92         AccessibilityNodeInfo node = mNodeBuilder.setVisibleToUser(false).build();
93         assertThat(node.isVisibleToUser()).isFalse();
94     }
95 
96     @Test
testSetInViewTree()97     public void testSetInViewTree() {
98         AccessibilityNodeInfo node = mNodeBuilder.setInViewTree(false).build();
99         assertThat(node.refresh()).isFalse();
100     }
101 
102     @Test
testSetScrollable()103     public void testSetScrollable() {
104         AccessibilityNodeInfo node = mNodeBuilder.setScrollable(true).build();
105         assertThat(node.isScrollable()).isTrue();
106     }
107 
108     @Test
testSetEnabled()109     public void testSetEnabled() {
110         AccessibilityNodeInfo node = mNodeBuilder.setEnabled(false).build();
111         assertThat(node.isEnabled()).isFalse();
112     }
113 
114     @Test
testSetWindow()115     public void testSetWindow() {
116         AccessibilityWindowInfo window = new WindowBuilder().build();
117         AccessibilityNodeInfo node = mNodeBuilder.setWindow(window).build();
118         assertThat(node.getWindow()).isEqualTo(window);
119     }
120 
121     @Test
testSetBoundsInParent()122     public void testSetBoundsInParent() {
123         Rect setBounds = new Rect(100, 200, 300, 400);
124         AccessibilityNodeInfo node = mNodeBuilder.setBoundsInParent(setBounds).build();
125         Rect retrievedBounds = new Rect();
126         node.getBoundsInParent(retrievedBounds);
127         assertThat(retrievedBounds).isEqualTo(setBounds);
128     }
129 
130     @Test
testSetBoundsInScreen()131     public void testSetBoundsInScreen() {
132         Rect setBounds = new Rect(100, 200, 300, 400);
133         AccessibilityNodeInfo node = mNodeBuilder.setBoundsInScreen(setBounds).build();
134         Rect retrievedBounds = new Rect();
135         node.getBoundsInScreen(retrievedBounds);
136         assertThat(retrievedBounds).isEqualTo(setBounds);
137     }
138 
139     @Test
testSetPackageName()140     public void testSetPackageName() {
141         AccessibilityNodeInfo node = mNodeBuilder.setPackageName(PACKAGE_NAME).build();
142         assertThat(node.getPackageName().toString()).isEqualTo(PACKAGE_NAME);
143     }
144 
145     @Test
testSetClassName()146     public void testSetClassName() {
147         AccessibilityNodeInfo node = mNodeBuilder.setClassName(CLASS_NAME).build();
148         assertThat(node.getClassName().toString()).isEqualTo(CLASS_NAME);
149     }
150 
151     @Test
testSetContentDescription()152     public void testSetContentDescription() {
153         AccessibilityNodeInfo node =
154                 mNodeBuilder.setContentDescription(CONTENT_DESCRIPTION).build();
155         assertThat(node.getContentDescription().toString()).isEqualTo(CONTENT_DESCRIPTION);
156     }
157 
158     @Test
testSetStateDescription()159     public void testSetStateDescription() {
160         AccessibilityNodeInfo node =
161                 mNodeBuilder.setStateDescription(STATE_DESCRIPTION).build();
162         assertThat(node.getStateDescription().toString()).isEqualTo(STATE_DESCRIPTION);
163     }
164 
165     @Test
testSetParent()166     public void testSetParent() {
167         AccessibilityNodeInfo parent = mNodeBuilder.build();
168         AccessibilityNodeInfo child1 = mNodeBuilder.setParent(parent).build();
169         AccessibilityNodeInfo child2 = mNodeBuilder.setParent(parent).build();
170         assertThat(child1.getParent()).isEqualTo(parent);
171         assertThat(parent.getChildCount()).isEqualTo(2);
172         assertThat(parent.getChild(0)).isEqualTo(child1);
173         assertThat(parent.getChild(1)).isEqualTo(child2);
174         assertThat(parent.getChild(2)).isNull();
175     }
176 
177     @Test
testFindInputFocus_succeeded()178     public void testFindInputFocus_succeeded() {
179         AccessibilityNodeInfo root = mNodeBuilder.build();
180         AccessibilityNodeInfo parent1 = mNodeBuilder.setParent(root).build();
181         AccessibilityNodeInfo parent2 = mNodeBuilder.setParent(root).build();
182         AccessibilityNodeInfo child1 = mNodeBuilder.setParent(parent1).build();
183         AccessibilityNodeInfo child2 = mNodeBuilder.setParent(parent1).build();
184         AccessibilityNodeInfo child3 = mNodeBuilder.setParent(parent2).setFocused(true).build();
185         AccessibilityNodeInfo child4 = mNodeBuilder.setParent(parent2).build();
186 
187         assertThat(root.findFocus(FOCUS_INPUT)).isEqualTo(child3);
188     }
189 
190     @Test
testFindInputFocus_failed()191     public void testFindInputFocus_failed() {
192         AccessibilityNodeInfo parent = mNodeBuilder.build();
193         AccessibilityNodeInfo child = mNodeBuilder.setParent(parent).build();
194         assertThat(parent.findFocus(FOCUS_INPUT)).isNull();
195     }
196 
197     @Test
testSetActions()198     public void testSetActions() {
199         AccessibilityNodeInfo node = mNodeBuilder.setActions(ACTION_SCROLL_FORWARD).build();
200         assertThat(node.getActionList()).containsExactly(ACTION_SCROLL_FORWARD);
201     }
202 
203     @Test
testSetFocusArea()204     public void testSetFocusArea() {
205         AccessibilityNodeInfo node = mNodeBuilder.setFocusArea().build();
206         assertThat(node.getClassName().toString()).isEqualTo(FOCUS_AREA_CLASS_NAME);
207         assertThat(node.isFocusable()).isFalse();
208     }
209 
210     @Test
testSetFocusAreaBoundsOffset()211     public void testSetFocusAreaBoundsOffset() {
212         int left = 10;
213         int top = 20;
214         int right = 30;
215         int bottom = 40;
216         AccessibilityNodeInfo node = mNodeBuilder
217                 .setFocusAreaBoundsOffset(left, top, right, bottom)
218                 .build();
219         Bundle extras = node.getExtras();
220         assertThat(extras.getInt(FOCUS_AREA_LEFT_BOUND_OFFSET)).isEqualTo(left);
221         assertThat(extras.getInt(FOCUS_AREA_TOP_BOUND_OFFSET)).isEqualTo(top);
222         assertThat(extras.getInt(FOCUS_AREA_RIGHT_BOUND_OFFSET)).isEqualTo(right);
223         assertThat(extras.getInt(FOCUS_AREA_BOTTOM_BOUND_OFFSET)).isEqualTo(bottom);
224     }
225 
226     @Test
testSetFpv()227     public void testSetFpv() {
228         AccessibilityNodeInfo node = mNodeBuilder.setFpv().build();
229         assertThat(node.getClassName().toString()).isEqualTo(FOCUS_PARKING_VIEW_CLASS_NAME);
230     }
231 
232     @Test
testSetGenericFpv()233     public void testSetGenericFpv() {
234         AccessibilityNodeInfo node = mNodeBuilder.setGenericFpv().build();
235         assertThat(node.getClassName().toString()).isEqualTo(GENERIC_FOCUS_PARKING_VIEW_CLASS_NAME);
236     }
237 
238     @Test
testSetScrollableContainer()239     public void testSetScrollableContainer() {
240         AccessibilityNodeInfo node = mNodeBuilder.setScrollableContainer().build();
241         assertThat(node.getContentDescription().toString()).isEqualTo(ROTARY_VERTICALLY_SCROLLABLE);
242     }
243 
244     @Test
testSetRotaryContainer()245     public void testSetRotaryContainer() {
246         AccessibilityNodeInfo node = mNodeBuilder.setRotaryContainer().build();
247         assertThat(node.getContentDescription().toString()).isEqualTo(ROTARY_CONTAINER);
248     }
249 
250     @Test
testSetCheckable()251     public void testSetCheckable() {
252         AccessibilityNodeInfo node = mNodeBuilder.setCheckable(true).build();
253         assertThat(node.isCheckable()).isTrue();
254     }
255 }
256