1 /*
2  * Copyright (C) 2016 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.shell;
17 
18 import static com.android.shell.BugreportProgressService.findSendToAccount;
19 
20 import static junit.framework.Assert.assertEquals;
21 import static junit.framework.Assert.assertNull;
22 
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Mockito.when;
25 
26 import android.accounts.Account;
27 import android.accounts.AccountManager;
28 import android.content.Context;
29 import android.os.UserHandle;
30 import android.os.UserManager;
31 import android.test.mock.MockContext;
32 import android.util.Pair;
33 
34 import androidx.test.filters.SmallTest;
35 import androidx.test.runner.AndroidJUnit4;
36 
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.mockito.Mock;
40 import org.mockito.MockitoAnnotations;
41 
42 import java.util.Arrays;
43 import java.util.List;
44 
45 /**
46  * Test for {@link BugreportProgressServiceTest}.
47  *
48  * Usage:
49    adb shell am instrument -w \
50      -e class com.android.shell.BugreportProgressServiceTest \
51      com.android.shell.tests
52  */
53 @SmallTest
54 @RunWith(AndroidJUnit4.class)
55 public class BugreportProgressServiceTest {
56     private static class MyContext extends MockContext {
57         @Mock
58         public UserManager userManager;
59 
60         @Mock
61         public AccountManager accountManager;
62 
MyContext()63         public MyContext() {
64             MockitoAnnotations.initMocks(this);
65         }
66 
67         @Override
getSystemService(String name)68         public Object getSystemService(String name) {
69             switch (name) {
70                 case Context.USER_SERVICE:
71                     return userManager;
72                 case Context.ACCOUNT_SERVICE:
73                     return accountManager;
74                 default:
75                     return super.getSystemService(name);
76             }
77         }
78 
79         @Override
getSystemServiceName(Class<?> serviceClass)80         public String getSystemServiceName(Class<?> serviceClass) {
81             if (UserManager.class.equals(serviceClass)) {
82                 return Context.USER_SERVICE;
83             }
84             if (AccountManager.class.equals(serviceClass)) {
85                 return Context.ACCOUNT_SERVICE;
86             }
87             return super.getSystemServiceName(serviceClass);
88         }
89     }
90 
91     private final MyContext mTestContext = new MyContext();
92 
list(T... array)93     private static <T> List<T> list(T... array) {
94         return Arrays.asList(array);
95     }
96 
array(T... array)97     private static <T> T[] array(T... array) {
98         return array;
99     }
100 
account(String email)101     private Account account(String email) {
102         return new Account(email, "test.com");
103     }
104 
checkFindSendToAccount( int expectedUserId, String expectedEmail, String preferredDomain)105     private void checkFindSendToAccount(
106             int expectedUserId, String expectedEmail, String preferredDomain) {
107         final Pair<UserHandle, Account> actual = findSendToAccount(mTestContext, preferredDomain);
108         assertEquals(UserHandle.of(expectedUserId), actual.first);
109         assertEquals(account(expectedEmail), actual.second);
110     }
111 
112     @Test
findSendToAccount_noWorkProfile()113     public void findSendToAccount_noWorkProfile() {
114         when(mTestContext.userManager.getUserProfiles()).thenReturn(
115                 list(UserHandle.of(UserHandle.USER_SYSTEM)));
116 
117         // No accounts.
118         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
119                 array());
120 
121         assertNull(findSendToAccount(mTestContext, null));
122         assertNull(findSendToAccount(mTestContext, ""));
123         assertNull(findSendToAccount(mTestContext, "android.com"));
124         assertNull(findSendToAccount(mTestContext, "@android.com"));
125 
126         // 1 account
127         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
128                 array(account("abc@gmail.com")));
129 
130         checkFindSendToAccount(0, "abc@gmail.com", null);
131         checkFindSendToAccount(0, "abc@gmail.com", "");
132         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
133         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
134         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
135         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
136 
137         // 2 accounts, same domain
138         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
139                 array(account("abc@gmail.com"), account("def@gmail.com")));
140 
141         checkFindSendToAccount(0, "abc@gmail.com", null);
142         checkFindSendToAccount(0, "abc@gmail.com", "");
143         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
144         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
145         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
146         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
147 
148         // 2 accounts, different domains
149         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
150                 array(account("abc@gmail.com"), account("def@android.com")));
151 
152         checkFindSendToAccount(0, "abc@gmail.com", null);
153         checkFindSendToAccount(0, "abc@gmail.com", "");
154         checkFindSendToAccount(0, "def@android.com", "android.com");
155         checkFindSendToAccount(0, "def@android.com", "@android.com");
156         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
157         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
158 
159         // Plut an account that doesn't look like an email address.
160         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
161                 array(account("notemail"), account("abc@gmail.com"), account("def@android.com")));
162 
163         checkFindSendToAccount(0, "abc@gmail.com", null);
164         checkFindSendToAccount(0, "abc@gmail.com", "");
165         checkFindSendToAccount(0, "def@android.com", "android.com");
166         checkFindSendToAccount(0, "def@android.com", "@android.com");
167         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
168         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
169     }
170 
171     /**
172      * Same as {@link #findSendToAccount_noWorkProfile()}, but with work profile, which has no
173      * accounts.  The expected results are the same as the original.
174      */
175     @Test
findSendToAccount_withWorkProfile_noAccounts()176     public void findSendToAccount_withWorkProfile_noAccounts() {
177         when(mTestContext.userManager.getUserProfiles()).thenReturn(
178                 list(UserHandle.of(UserHandle.USER_SYSTEM), UserHandle.of(10)));
179 
180         // Work profile has no accounts
181         when(mTestContext.accountManager.getAccountsAsUser(eq(10))).thenReturn(
182                 array());
183 
184         // No accounts.
185         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
186                 array());
187 
188         assertNull(findSendToAccount(mTestContext, null));
189         assertNull(findSendToAccount(mTestContext, ""));
190         assertNull(findSendToAccount(mTestContext, "android.com"));
191         assertNull(findSendToAccount(mTestContext, "@android.com"));
192 
193         // 1 account
194         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
195                 array(account("abc@gmail.com")));
196 
197         checkFindSendToAccount(0, "abc@gmail.com", null);
198         checkFindSendToAccount(0, "abc@gmail.com", "");
199         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
200         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
201         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
202         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
203 
204         // 2 accounts, same domain
205         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
206                 array(account("abc@gmail.com"), account("def@gmail.com")));
207 
208         checkFindSendToAccount(0, "abc@gmail.com", null);
209         checkFindSendToAccount(0, "abc@gmail.com", "");
210         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
211         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
212         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
213         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
214 
215         // 2 accounts, different domains
216         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
217                 array(account("abc@gmail.com"), account("def@android.com")));
218 
219         checkFindSendToAccount(0, "abc@gmail.com", null);
220         checkFindSendToAccount(0, "abc@gmail.com", "");
221         checkFindSendToAccount(0, "def@android.com", "android.com");
222         checkFindSendToAccount(0, "def@android.com", "@android.com");
223         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
224         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
225 
226         // Plut an account that doesn't look like an email address.
227         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
228                 array(account("notemail"), account("abc@gmail.com"), account("def@android.com")));
229 
230         checkFindSendToAccount(0, "abc@gmail.com", null);
231         checkFindSendToAccount(0, "abc@gmail.com", "");
232         checkFindSendToAccount(0, "def@android.com", "android.com");
233         checkFindSendToAccount(0, "def@android.com", "@android.com");
234         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
235         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
236     }
237 
238     /**
239      * Same as {@link #findSendToAccount_noWorkProfile()}, but with work profile, which has
240      * 1 account.  The expected results are the same as the original, expect for the "no accounts
241      * on the primary profile" case.
242      */
243     @Test
findSendToAccount_withWorkProfile_1account()244     public void findSendToAccount_withWorkProfile_1account() {
245         when(mTestContext.userManager.getUserProfiles()).thenReturn(
246                 list(UserHandle.of(UserHandle.USER_SYSTEM), UserHandle.of(10)));
247 
248         // Work profile has no accounts
249         when(mTestContext.accountManager.getAccountsAsUser(eq(10))).thenReturn(
250                 array(account("xyz@gmail.com")));
251 
252         // No accounts.
253         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
254                 array());
255 
256         checkFindSendToAccount(10, "xyz@gmail.com", null);
257         checkFindSendToAccount(10, "xyz@gmail.com", "");
258         checkFindSendToAccount(10, "xyz@gmail.com", "android.com");
259         checkFindSendToAccount(10, "xyz@gmail.com", "@android.com");
260 
261         // 1 account
262         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
263                 array(account("abc@gmail.com")));
264 
265         checkFindSendToAccount(0, "abc@gmail.com", null);
266         checkFindSendToAccount(0, "abc@gmail.com", "");
267         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
268         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
269         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
270         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
271 
272         // 2 accounts, same domain
273         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
274                 array(account("abc@gmail.com"), account("def@gmail.com")));
275 
276         checkFindSendToAccount(0, "abc@gmail.com", null);
277         checkFindSendToAccount(0, "abc@gmail.com", "");
278         checkFindSendToAccount(0, "abc@gmail.com", "android.com");
279         checkFindSendToAccount(0, "abc@gmail.com", "@android.com");
280         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
281         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
282 
283         // 2 accounts, different domains
284         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
285                 array(account("abc@gmail.com"), account("def@android.com")));
286 
287         checkFindSendToAccount(0, "abc@gmail.com", null);
288         checkFindSendToAccount(0, "abc@gmail.com", "");
289         checkFindSendToAccount(0, "def@android.com", "android.com");
290         checkFindSendToAccount(0, "def@android.com", "@android.com");
291         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
292         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
293 
294         // Plut an account that doesn't look like an email address.
295         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
296                 array(account("notemail"), account("abc@gmail.com"), account("def@android.com")));
297 
298         checkFindSendToAccount(0, "abc@gmail.com", null);
299         checkFindSendToAccount(0, "abc@gmail.com", "");
300         checkFindSendToAccount(0, "def@android.com", "android.com");
301         checkFindSendToAccount(0, "def@android.com", "@android.com");
302         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
303         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
304     }
305 
306     /**
307      * Same as {@link #findSendToAccount_noWorkProfile()}, but with work profile, with mixed
308      * domains.
309      */
310     @Test
findSendToAccount_withWorkProfile_mixedDomains()311     public void findSendToAccount_withWorkProfile_mixedDomains() {
312         when(mTestContext.userManager.getUserProfiles()).thenReturn(
313                 list(UserHandle.of(UserHandle.USER_SYSTEM), UserHandle.of(10)));
314 
315         // Work profile has no accounts
316         when(mTestContext.accountManager.getAccountsAsUser(eq(10))).thenReturn(
317                 array(account("xyz@android.com")));
318 
319         // No accounts.
320         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
321                 array());
322 
323         checkFindSendToAccount(10, "xyz@android.com", null);
324         checkFindSendToAccount(10, "xyz@android.com", "");
325         checkFindSendToAccount(10, "xyz@android.com", "android.com");
326         checkFindSendToAccount(10, "xyz@android.com", "@android.com");
327 
328         // 1 account
329         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
330                 array(account("abc@gmail.com")));
331 
332         checkFindSendToAccount(0, "abc@gmail.com", null);
333         checkFindSendToAccount(0, "abc@gmail.com", "");
334         checkFindSendToAccount(10, "xyz@android.com", "android.com");
335         checkFindSendToAccount(10, "xyz@android.com", "@android.com");
336         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
337         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
338 
339         // more accounts.
340         when(mTestContext.accountManager.getAccountsAsUser(eq(UserHandle.USER_SYSTEM))).thenReturn(
341                 array(account("abc@gmail.com"), account("def@gmail.com")));
342 
343         checkFindSendToAccount(0, "abc@gmail.com", null);
344         checkFindSendToAccount(0, "abc@gmail.com", "");
345         checkFindSendToAccount(10, "xyz@android.com", "android.com");
346         checkFindSendToAccount(10, "xyz@android.com", "@android.com");
347         checkFindSendToAccount(0, "abc@gmail.com", "gmail.com");
348         checkFindSendToAccount(0, "abc@gmail.com", "@gmail.com");
349     }
350 }
351