1 /*
2  * Copyright (C) 2023 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 
17 package android.app;
18 
19 import static android.view.Display.DEFAULT_DISPLAY;
20 import static android.view.Display.INVALID_DISPLAY;
21 
22 import static com.google.common.truth.Truth.assertWithMessage;
23 
24 import static org.junit.Assert.assertThrows;
25 import static org.mockito.Mockito.when;
26 
27 import android.content.Context;
28 import android.os.Looper;
29 import android.os.UserManager;
30 
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.mockito.Mock;
35 import org.mockito.junit.MockitoJUnitRunner;
36 
37 @RunWith(MockitoJUnitRunner.class)
38 public final class UiAutomationTest {
39 
40     private static final int SECONDARY_DISPLAY_ID = 42;
41     private static final int DISPLAY_ID_ASSIGNED_TO_USER = 108;
42 
43     private final Looper mLooper = Looper.getMainLooper();
44 
45     @Mock
46     private Context mContext;
47     @Mock
48     private UserManager mUserManager;
49     @Mock
50     private IUiAutomationConnection mConnection;
51 
52     @Before
setFixtures()53     public void setFixtures() {
54         when(mContext.getMainLooper()).thenReturn(mLooper);
55         mockSystemService(UserManager.class, mUserManager);
56 
57         // Set default expectations
58         mockVisibleBackgroundUsersSupported(/* supported= */ false);
59         mockUserVisibility(/* visible= */ true);
60         // make sure it's not used, unless explicitly mocked
61         mockDisplayAssignedToUser(INVALID_DISPLAY);
62         mockContextDisplay(DEFAULT_DISPLAY);
63     }
64 
65     @Test
testContextConstructor_nullContext()66     public void testContextConstructor_nullContext() {
67         assertThrows(IllegalArgumentException.class,
68                 () -> new UiAutomation((Context) null, mConnection));
69     }
70 
71     @Test
testContextConstructor_nullConnection()72     public void testContextConstructor_nullConnection() {
73         assertThrows(IllegalArgumentException.class,
74                 () -> new UiAutomation(mContext, (IUiAutomationConnection) null));
75     }
76 
77     @Test
testGetDisplay_contextWithSecondaryDisplayId()78     public void testGetDisplay_contextWithSecondaryDisplayId() {
79         mockContextDisplay(SECONDARY_DISPLAY_ID);
80 
81         UiAutomation uiAutomation = new UiAutomation(mContext, mConnection);
82 
83         // It's always DEFAULT_DISPLAY regardless, unless the device supports visible bg users
84         assertWithMessage("getDisplayId()").that(uiAutomation.getDisplayId())
85                 .isEqualTo(DEFAULT_DISPLAY);
86     }
87 
88     @Test
testGetDisplay_contextWithInvalidDisplayId()89     public void testGetDisplay_contextWithInvalidDisplayId() {
90         mockContextDisplay(INVALID_DISPLAY);
91 
92         UiAutomation uiAutomation = new UiAutomation(mContext, mConnection);
93 
94         assertWithMessage("getDisplayId()").that(uiAutomation.getDisplayId())
95                 .isEqualTo(DEFAULT_DISPLAY);
96     }
97 
98     @Test
testGetDisplay_visibleBgUsers()99     public void testGetDisplay_visibleBgUsers() {
100         mockVisibleBackgroundUsersSupported(/* supported= */ true);
101         mockContextDisplay(SECONDARY_DISPLAY_ID);
102         // Should be using display from context, not from user
103         mockDisplayAssignedToUser(DISPLAY_ID_ASSIGNED_TO_USER);
104 
105         UiAutomation uiAutomation = new UiAutomation(mContext, mConnection);
106 
107         assertWithMessage("getDisplayId()").that(uiAutomation.getDisplayId())
108                 .isEqualTo(SECONDARY_DISPLAY_ID);
109     }
110 
111     @Test
testGetDisplay_visibleBgUsers_contextWithInvalidDisplayId()112     public void testGetDisplay_visibleBgUsers_contextWithInvalidDisplayId() {
113         mockVisibleBackgroundUsersSupported(/* supported= */ true);
114         mockContextDisplay(INVALID_DISPLAY);
115         mockDisplayAssignedToUser(DISPLAY_ID_ASSIGNED_TO_USER);
116 
117         UiAutomation uiAutomation = new UiAutomation(mContext, mConnection);
118 
119         assertWithMessage("getDisplayId()").that(uiAutomation.getDisplayId())
120                 .isEqualTo(DISPLAY_ID_ASSIGNED_TO_USER);
121     }
122 
mockSystemService(Class<T> svcClass, T svc)123     private <T> void mockSystemService(Class<T> svcClass, T svc) {
124         String svcName = svcClass.getName();
125         when(mContext.getSystemServiceName(svcClass)).thenReturn(svcName);
126         when(mContext.getSystemService(svcName)).thenReturn(svc);
127     }
128 
mockVisibleBackgroundUsersSupported(boolean supported)129     private void mockVisibleBackgroundUsersSupported(boolean supported) {
130         when(mUserManager.isVisibleBackgroundUsersSupported()).thenReturn(supported);
131     }
132 
mockContextDisplay(int displayId)133     private void mockContextDisplay(int displayId) {
134         when(mContext.getDisplayId()).thenReturn(displayId);
135     }
136 
mockDisplayAssignedToUser(int displayId)137     private void mockDisplayAssignedToUser(int displayId) {
138         when(mUserManager.getMainDisplayIdAssignedToUser()).thenReturn(displayId);
139     }
140 
mockUserVisibility(boolean visible)141     private void mockUserVisibility(boolean visible) {
142         when(mUserManager.isUserVisible()).thenReturn(visible);
143     }
144 }
145