1 /*
2  * Copyright (C) 2009 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 com.android.server.accounts;
18 
19 import static android.database.sqlite.SQLiteDatabase.deleteDatabase;
20 
21 import static org.mockito.ArgumentMatchers.contains;
22 import static org.mockito.Matchers.any;
23 import static org.mockito.Matchers.anyBoolean;
24 import static org.mockito.Matchers.anyInt;
25 import static org.mockito.Matchers.anyString;
26 import static org.mockito.Matchers.eq;
27 import static org.mockito.Mockito.atLeast;
28 import static org.mockito.Mockito.doAnswer;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.nullable;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.accounts.AbstractAccountAuthenticator;
36 import android.accounts.Account;
37 import android.accounts.AccountManager;
38 import android.accounts.AccountManagerInternal;
39 import android.accounts.CantAddAccountActivity;
40 import android.accounts.IAccountManagerResponse;
41 import android.app.AppOpsManager;
42 import android.app.BroadcastOptions;
43 import android.app.INotificationManager;
44 import android.app.PropertyInvalidatedCache;
45 import android.app.admin.DevicePolicyManager;
46 import android.app.admin.DevicePolicyManagerInternal;
47 import android.content.BroadcastReceiver;
48 import android.content.Context;
49 import android.content.Intent;
50 import android.content.IntentFilter;
51 import android.content.ServiceConnection;
52 import android.content.pm.ActivityInfo;
53 import android.content.pm.ApplicationInfo;
54 import android.content.pm.PackageInfo;
55 import android.content.pm.PackageManager;
56 import android.content.pm.PackageManagerInternal;
57 import android.content.pm.ResolveInfo;
58 import android.content.pm.Signature;
59 import android.content.pm.UserInfo;
60 import android.database.Cursor;
61 import android.database.DatabaseErrorHandler;
62 import android.database.sqlite.SQLiteDatabase;
63 import android.os.Bundle;
64 import android.os.Handler;
65 import android.os.IBinder;
66 import android.os.Looper;
67 import android.os.RemoteException;
68 import android.os.SystemClock;
69 import android.os.UserHandle;
70 import android.os.UserManager;
71 import android.test.AndroidTestCase;
72 import android.test.mock.MockContext;
73 import android.test.suitebuilder.annotation.SmallTest;
74 import android.util.Log;
75 
76 import com.android.server.LocalServices;
77 
78 import org.mockito.ArgumentCaptor;
79 import org.mockito.Captor;
80 import org.mockito.Mock;
81 import org.mockito.MockitoAnnotations;
82 
83 import java.io.File;
84 import java.security.GeneralSecurityException;
85 import java.util.ArrayList;
86 import java.util.Arrays;
87 import java.util.Collections;
88 import java.util.Comparator;
89 import java.util.HashMap;
90 import java.util.List;
91 import java.util.concurrent.CountDownLatch;
92 import java.util.concurrent.CyclicBarrier;
93 import java.util.concurrent.ExecutorService;
94 import java.util.concurrent.Executors;
95 import java.util.concurrent.TimeUnit;
96 import java.util.concurrent.atomic.AtomicLong;
97 
98 /**
99  * Tests for {@link AccountManagerService}.
100  * <p>Run with:<pre>
101  * mmma -j40 frameworks/base/services/tests/servicestests
102  * adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
103  * adb shell am instrument -w -e package com.android.server.accounts \
104  * com.android.frameworks.servicestests\
105  * /androidx.test.runner.AndroidJUnitRunner
106  * </pre>
107  */
108 public class AccountManagerServiceTest extends AndroidTestCase {
109     private static final String TAG = AccountManagerServiceTest.class.getSimpleName();
110     private static final long ONE_DAY_IN_MILLISECOND = 86400000;
111 
112     @Mock private Context mMockContext;
113     @Mock private AppOpsManager mMockAppOpsManager;
114     @Mock private UserManager mMockUserManager;
115     @Mock private PackageManager mMockPackageManager;
116     @Mock private DevicePolicyManagerInternal mMockDevicePolicyManagerInternal;
117     @Mock private DevicePolicyManager mMockDevicePolicyManager;
118     @Mock private IAccountManagerResponse mMockAccountManagerResponse;
119     @Mock private IBinder mMockBinder;
120     @Mock private INotificationManager mMockNotificationManager;
121     @Mock private PackageManagerInternal mMockPackageManagerInternal;
122 
123     @Captor private ArgumentCaptor<Intent> mIntentCaptor;
124     @Captor private ArgumentCaptor<Bundle> mBundleCaptor;
125     private int mVisibleAccountsChangedBroadcasts;
126     private int mLoginAccountsChangedBroadcasts;
127     private int mAccountRemovedBroadcasts;
128 
129     private static final int LATCH_TIMEOUT_MS = 500;
130     private static final String PREN_DB = "pren.db";
131     private static final String DE_DB = "de.db";
132     private static final String CE_DB = "ce.db";
133     private PackageInfo mPackageInfo;
134     private AccountManagerService mAms;
135     private TestInjector mTestInjector;
136 
137     @Override
setUp()138     protected void setUp() throws Exception {
139         MockitoAnnotations.initMocks(this);
140 
141         PropertyInvalidatedCache.disableForTestMode();
142 
143         when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
144                     .thenReturn(PackageManager.SIGNATURE_MATCH);
145         final UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, "user0", 0);
146         when(mMockUserManager.getUserInfo(eq(ui.id))).thenReturn(ui);
147         when(mMockContext.createPackageContextAsUser(
148                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
149         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
150 
151         mPackageInfo = new PackageInfo();
152         mPackageInfo.signatures = new Signature[1];
153         mPackageInfo.signatures[0] = new Signature(new byte[] {'a', 'b', 'c', 'd'});
154         mPackageInfo.applicationInfo = new ApplicationInfo();
155         mPackageInfo.applicationInfo.privateFlags = ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
156         when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
157         when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
158         when(mMockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
159         when(mMockContext.getSystemServiceName(AppOpsManager.class)).thenReturn(
160                 Context.APP_OPS_SERVICE);
161         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
162                 PackageManager.PERMISSION_GRANTED);
163         Bundle bundle = new Bundle();
164         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
165         when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
166                 mMockDevicePolicyManager);
167         when(mMockAccountManagerResponse.asBinder()).thenReturn(mMockBinder);
168         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
169                 .thenReturn(true);
170         LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
171 
172         Context realTestContext = getContext();
173         MyMockContext mockContext = new MyMockContext(realTestContext, mMockContext);
174         setContext(mockContext);
175         mTestInjector = new TestInjector(realTestContext, mockContext, mMockNotificationManager);
176         mAms = new AccountManagerService(mTestInjector);
177         doAnswer(invocation -> {
178             final Intent intent = invocation.getArgument(0);
179             final Bundle options = invocation.getArgument(3);
180             if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.endsWith(intent.getAction())) {
181                 final BroadcastOptions bOptions = new BroadcastOptions(options);
182                 assertEquals(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT,
183                         bOptions.getDeliveryGroupPolicy());
184             }
185             return null;
186         }).when(mMockContext).sendBroadcastAsUser(any(), any(), any(), any());
187     }
188 
189     @Override
tearDown()190     protected void tearDown() throws Exception {
191         // Let async logging tasks finish, otherwise they may crash due to db being removed
192         CountDownLatch cdl = new CountDownLatch(1);
193         mAms.mHandler.post(() -> {
194             deleteDatabase(new File(mTestInjector.getCeDatabaseName(UserHandle.USER_SYSTEM)));
195             deleteDatabase(new File(mTestInjector.getDeDatabaseName(UserHandle.USER_SYSTEM)));
196             deleteDatabase(new File(mTestInjector.getPreNDatabaseName(UserHandle.USER_SYSTEM)));
197             cdl.countDown();
198         });
199         cdl.await(1, TimeUnit.SECONDS);
200         LocalServices.removeServiceForTest(PackageManagerInternal.class);
201         super.tearDown();
202     }
203 
204     class AccountSorter implements Comparator<Account> {
compare(Account object1, Account object2)205         public int compare(Account object1, Account object2) {
206             if (object1 == object2) return 0;
207             if (object1 == null) return 1;
208             if (object2 == null) return -1;
209             int result = object1.type.compareTo(object2.type);
210             if (result != 0) return result;
211             return object1.name.compareTo(object2.name);
212         }
213     }
214 
215     @SmallTest
testCheckAddAccount()216     public void testCheckAddAccount() throws Exception {
217         unlockSystemUser();
218         Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
219         Account a21 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
220         Account a31 = new Account("account3", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
221         Account a12 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
222         Account a22 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
223         Account a32 = new Account("account3", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
224         mAms.addAccountExplicitly(
225                 a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null);
226         mAms.addAccountExplicitly(
227                 a12, /* password= */ "p12", /* extras= */ null, /* callerPackage= */ null);
228         mAms.addAccountExplicitly(
229                 a21, /* password= */ "p21", /* extras= */ null, /* callerPackage= */ null);
230         mAms.addAccountExplicitly(
231                 a22, /* password= */ "p22", /* extras= */ null, /* callerPackage= */ null);
232         mAms.addAccountExplicitly(
233                 a31, /* password= */ "p31", /* extras= */ null, /* callerPackage= */ null);
234         mAms.addAccountExplicitly(
235                 a32, /* password= */ "p32", /* extras= */ null, /* callerPackage= */ null);
236 
237         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
238         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
239         Account[] accounts = mAms.getAccountsAsUser(null,
240                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
241         Arrays.sort(accounts, new AccountSorter());
242         assertEquals(6, accounts.length);
243         assertEquals(a11, accounts[0]);
244         assertEquals(a21, accounts[1]);
245         assertEquals(a31, accounts[2]);
246         assertEquals(a12, accounts[3]);
247         assertEquals(a22, accounts[4]);
248         assertEquals(a32, accounts[5]);
249 
250         accounts = mAms.getAccountsAsUser(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
251                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
252         Arrays.sort(accounts, new AccountSorter());
253         assertEquals(3, accounts.length);
254         assertEquals(a11, accounts[0]);
255         assertEquals(a21, accounts[1]);
256         assertEquals(a31, accounts[2]);
257 
258         mAms.removeAccountInternal(a21);
259 
260         accounts = mAms.getAccountsAsUser(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
261                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
262         Arrays.sort(accounts, new AccountSorter());
263         assertEquals(2, accounts.length);
264         assertEquals(a11, accounts[0]);
265         assertEquals(a31, accounts[1]);
266     }
267 
268     @SmallTest
testCheckAddAccountLongName()269     public void testCheckAddAccountLongName() throws Exception {
270         unlockSystemUser();
271         String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
272                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
273                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
274                 + "aaaaa";
275         Account a11 = new Account(longString, AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
276 
277         mAms.addAccountExplicitly(
278                 a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null);
279 
280         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
281         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
282         Account[] accounts = mAms.getAccountsAsUser(null,
283                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
284         assertEquals(0, accounts.length);
285     }
286 
287 
288     @SmallTest
testPasswords()289     public void testPasswords() throws Exception {
290         unlockSystemUser();
291         Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
292         Account a12 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
293         mAms.addAccountExplicitly(
294                 a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null);
295         mAms.addAccountExplicitly(
296                 a12, /* password= */ "p12", /* extras= */ null, /* callerPackage= */ null);
297 
298         assertEquals("p11", mAms.getPassword(a11));
299         assertEquals("p12", mAms.getPassword(a12));
300 
301         mAms.setPassword(a11, "p11b");
302 
303         assertEquals("p11b", mAms.getPassword(a11));
304         assertEquals("p12", mAms.getPassword(a12));
305     }
306 
307     @SmallTest
testUserdata()308     public void testUserdata() throws Exception {
309         unlockSystemUser();
310         Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
311         Bundle u11 = new Bundle();
312         u11.putString("a", "a_a11");
313         u11.putString("b", "b_a11");
314         u11.putString("c", "c_a11");
315         Account a12 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
316         Bundle u12 = new Bundle();
317         u12.putString("a", "a_a12");
318         u12.putString("b", "b_a12");
319         u12.putString("c", "c_a12");
320         mAms.addAccountExplicitly(a11, /* password= */ "p11", u11, /* callerPackage= */ null);
321         mAms.addAccountExplicitly(a12, /* password= */ "p12", u12, /* callerPackage= */ null);
322 
323         assertEquals("a_a11", mAms.getUserData(a11, "a"));
324         assertEquals("b_a11", mAms.getUserData(a11, "b"));
325         assertEquals("c_a11", mAms.getUserData(a11, "c"));
326         assertEquals("a_a12", mAms.getUserData(a12, "a"));
327         assertEquals("b_a12", mAms.getUserData(a12, "b"));
328         assertEquals("c_a12", mAms.getUserData(a12, "c"));
329 
330         mAms.setUserData(a11, "b", "b_a11b");
331         mAms.setUserData(a12, "c", null);
332 
333         assertEquals("a_a11", mAms.getUserData(a11, "a"));
334         assertEquals("b_a11b", mAms.getUserData(a11, "b"));
335         assertEquals("c_a11", mAms.getUserData(a11, "c"));
336         assertEquals("a_a12", mAms.getUserData(a12, "a"));
337         assertEquals("b_a12", mAms.getUserData(a12, "b"));
338         assertNull(mAms.getUserData(a12, "c"));
339     }
340 
341     @SmallTest
testAuthtokens()342     public void testAuthtokens() throws Exception {
343         unlockSystemUser();
344         Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
345         Account a12 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
346         mAms.addAccountExplicitly(
347                 a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null);
348         mAms.addAccountExplicitly(
349                 a12, /* password= */ "p12", /* extras= */ null, /* callerPackage= */ null);
350 
351         mAms.setAuthToken(a11, "att1", "a11_att1");
352         mAms.setAuthToken(a11, "att2", "a11_att2");
353         mAms.setAuthToken(a11, "att3", "a11_att3");
354         mAms.setAuthToken(a12, "att1", "a12_att1");
355         mAms.setAuthToken(a12, "att2", "a12_att2");
356         mAms.setAuthToken(a12, "att3", "a12_att3");
357 
358         assertEquals("a11_att1", mAms.peekAuthToken(a11, "att1"));
359         assertEquals("a11_att2", mAms.peekAuthToken(a11, "att2"));
360         assertEquals("a11_att3", mAms.peekAuthToken(a11, "att3"));
361         assertEquals("a12_att1", mAms.peekAuthToken(a12, "att1"));
362         assertEquals("a12_att2", mAms.peekAuthToken(a12, "att2"));
363         assertEquals("a12_att3", mAms.peekAuthToken(a12, "att3"));
364 
365         mAms.setAuthToken(a11, "att3", "a11_att3b");
366         mAms.invalidateAuthToken(a12.type, "a12_att2");
367 
368         assertEquals("a11_att1", mAms.peekAuthToken(a11, "att1"));
369         assertEquals("a11_att2", mAms.peekAuthToken(a11, "att2"));
370         assertEquals("a11_att3b", mAms.peekAuthToken(a11, "att3"));
371         assertEquals("a12_att1", mAms.peekAuthToken(a12, "att1"));
372         assertNull(mAms.peekAuthToken(a12, "att2"));
373         assertEquals("a12_att3", mAms.peekAuthToken(a12, "att3"));
374 
375         assertNull(mAms.peekAuthToken(a12, "att2"));
376     }
377 
378     @SmallTest
testRemovedAccountSync()379     public void testRemovedAccountSync() throws Exception {
380         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
381         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
382         unlockSystemUser();
383         Account a1 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
384         Account a2 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
385         mAms.addAccountExplicitly(
386                 a1, /* password= */ "p1", /* extras= */ null, /* callerPackage= */ null);
387         mAms.addAccountExplicitly(
388                 a2, /* password= */ "p2", /* extras= */ null, /* callerPackage= */ null);
389 
390         Context originalContext = ((MyMockContext)getContext()).mTestContext;
391         // create a separate instance of AMS. It initially assumes that user0 is locked
392         AccountManagerService ams2 = new AccountManagerService(mTestInjector);
393 
394         // Verify that account can be removed when user is locked
395         ams2.removeAccountInternal(a1);
396         Account[] accounts = ams2.getAccounts(UserHandle.USER_SYSTEM, mContext.getOpPackageName());
397         assertEquals(1, accounts.length);
398         assertEquals("Only a2 should be returned", a2, accounts[0]);
399 
400         // Verify that CE db file is unchanged and still has 2 accounts
401         String ceDatabaseName = mTestInjector.getCeDatabaseName(UserHandle.USER_SYSTEM);
402         int accountsNumber = readNumberOfAccountsFromDbFile(originalContext, ceDatabaseName);
403         assertEquals("CE database should still have 2 accounts", 2, accountsNumber);
404 
405         // Unlock the user and verify that db has been updated
406         ams2.onUserUnlocked(newIntentForUser(UserHandle.USER_SYSTEM));
407         accounts = ams2.getAccounts(UserHandle.USER_SYSTEM, mContext.getOpPackageName());
408         assertEquals(1, accounts.length);
409         assertEquals("Only a2 should be returned", a2, accounts[0]);
410         accountsNumber = readNumberOfAccountsFromDbFile(originalContext, ceDatabaseName);
411         assertEquals("CE database should now have 1 account", 1, accountsNumber);
412     }
413 
414     @SmallTest
testPreNDatabaseMigration()415     public void testPreNDatabaseMigration() throws Exception {
416         String preNDatabaseName = mTestInjector.getPreNDatabaseName(UserHandle.USER_SYSTEM);
417         Context originalContext = ((MyMockContext) getContext()).mTestContext;
418         PreNTestDatabaseHelper.createV4Database(originalContext, preNDatabaseName);
419         // Assert that database was created with 1 account
420         int n = readNumberOfAccountsFromDbFile(originalContext, preNDatabaseName);
421         assertEquals("pre-N database should have 1 account", 1, n);
422 
423         // Start testing
424         unlockSystemUser();
425         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
426         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
427         Account[] accounts = mAms.getAccountsAsUser(null, UserHandle.getCallingUserId(),
428                 mContext.getOpPackageName());
429         assertEquals("1 account should be migrated", 1, accounts.length);
430         assertEquals(PreNTestDatabaseHelper.ACCOUNT_NAME, accounts[0].name);
431         assertEquals(PreNTestDatabaseHelper.ACCOUNT_PASSWORD, mAms.getPassword(accounts[0]));
432         assertEquals("Authtoken should be migrated",
433                 PreNTestDatabaseHelper.TOKEN_STRING,
434                 mAms.peekAuthToken(accounts[0], PreNTestDatabaseHelper.TOKEN_TYPE));
435 
436         assertFalse("pre-N database file should be removed but was found at " + preNDatabaseName,
437                 new File(preNDatabaseName).exists());
438 
439         // Verify that ce/de files are present
440         String deDatabaseName = mTestInjector.getDeDatabaseName(UserHandle.USER_SYSTEM);
441         String ceDatabaseName = mTestInjector.getCeDatabaseName(UserHandle.USER_SYSTEM);
442         assertTrue("DE database file should be created at " + deDatabaseName,
443                 new File(deDatabaseName).exists());
444         assertTrue("CE database file should be created at " + ceDatabaseName,
445                 new File(ceDatabaseName).exists());
446     }
447 
448     @SmallTest
testStartAddAccountSessionWithNullResponse()449     public void testStartAddAccountSessionWithNullResponse() throws Exception {
450         unlockSystemUser();
451         try {
452             mAms.startAddAccountSession(
453                 null, // response
454                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
455                 "authTokenType",
456                 null, // requiredFeatures
457                 true, // expectActivityLaunch
458                 null); // optionsIn
459             fail("IllegalArgumentException expected. But no exception was thrown.");
460         } catch (IllegalArgumentException e) {
461             // IllegalArgumentException is expected.
462         }
463     }
464 
465     @SmallTest
testStartAddAccountSessionWithNullAccountType()466     public void testStartAddAccountSessionWithNullAccountType() throws Exception {
467         unlockSystemUser();
468         try {
469             mAms.startAddAccountSession(
470                     mMockAccountManagerResponse, // response
471                     null, // accountType
472                     "authTokenType",
473                     null, // requiredFeatures
474                     true, // expectActivityLaunch
475                     null); // optionsIn
476             fail("IllegalArgumentException expected. But no exception was thrown.");
477         } catch (IllegalArgumentException e) {
478             // IllegalArgumentException is expected.
479         }
480     }
481 
482     @SmallTest
testStartAddAccountSessionUserCannotModifyAccountNoDPM()483     public void testStartAddAccountSessionUserCannotModifyAccountNoDPM() throws Exception {
484         unlockSystemUser();
485         Bundle bundle = new Bundle();
486         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
487         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
488         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
489 
490         mAms.startAddAccountSession(
491                 mMockAccountManagerResponse, // response
492                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
493                 "authTokenType",
494                 null, // requiredFeatures
495                 true, // expectActivityLaunch
496                 null); // optionsIn
497         verify(mMockAccountManagerResponse).onError(
498                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
499         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
500 
501         // verify the intent for default CantAddAccountActivity is sent.
502         Intent intent = mIntentCaptor.getValue();
503         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
504         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
505                 AccountManager.ERROR_CODE_USER_RESTRICTED);
506     }
507 
508     @SmallTest
testStartAddAccountSessionUserCannotModifyAccountWithDPM()509     public void testStartAddAccountSessionUserCannotModifyAccountWithDPM() throws Exception {
510         unlockSystemUser();
511         Bundle bundle = new Bundle();
512         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
513         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
514         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
515         LocalServices.addService(
516                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
517         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
518                 anyInt(), anyString())).thenReturn(new Intent());
519         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
520                 anyInt(), anyBoolean())).thenReturn(new Intent());
521 
522         mAms.startAddAccountSession(
523                 mMockAccountManagerResponse, // response
524                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
525                 "authTokenType",
526                 null, // requiredFeatures
527                 true, // expectActivityLaunch
528                 null); // optionsIn
529 
530         verify(mMockAccountManagerResponse).onError(
531                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
532         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
533         verify(mMockDevicePolicyManagerInternal).createUserRestrictionSupportIntent(
534                 anyInt(), anyString());
535     }
536 
537     @SmallTest
testStartAddAccountSessionUserCannotModifyAccountForTypeNoDPM()538     public void testStartAddAccountSessionUserCannotModifyAccountForTypeNoDPM() throws Exception {
539         unlockSystemUser();
540         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
541                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
542         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
543 
544         mAms.startAddAccountSession(
545                 mMockAccountManagerResponse, // response
546                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
547                 "authTokenType",
548                 null, // requiredFeatures
549                 true, // expectActivityLaunch
550                 null); // optionsIn
551 
552         verify(mMockAccountManagerResponse).onError(
553                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
554         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
555 
556         // verify the intent for default CantAddAccountActivity is sent.
557         Intent intent = mIntentCaptor.getValue();
558         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
559         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
560                 AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE);
561     }
562 
563     @SmallTest
testStartAddAccountSessionUserCannotModifyAccountForTypeWithDPM()564     public void testStartAddAccountSessionUserCannotModifyAccountForTypeWithDPM() throws Exception {
565         unlockSystemUser();
566         when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
567                 mMockDevicePolicyManager);
568         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
569                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
570 
571         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
572         LocalServices.addService(
573                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
574         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
575                 anyInt(), anyString())).thenReturn(new Intent());
576         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
577                 anyInt(), anyBoolean())).thenReturn(new Intent());
578 
579         mAms.startAddAccountSession(
580                 mMockAccountManagerResponse, // response
581                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
582                 "authTokenType",
583                 null, // requiredFeatures
584                 true, // expectActivityLaunch
585                 null); // optionsIn
586 
587         verify(mMockAccountManagerResponse).onError(
588                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
589         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
590         verify(mMockDevicePolicyManagerInternal).createShowAdminSupportIntent(
591                 anyInt(), anyBoolean());
592     }
593 
594     @SmallTest
testStartAddAccountSessionSuccessWithoutPasswordForwarding()595     public void testStartAddAccountSessionSuccessWithoutPasswordForwarding() throws Exception {
596         unlockSystemUser();
597         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
598                 PackageManager.PERMISSION_DENIED);
599 
600         final CountDownLatch latch = new CountDownLatch(1);
601         Response response = new Response(latch, mMockAccountManagerResponse);
602         Bundle options = createOptionsWithAccountName(
603                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
604         mAms.startAddAccountSession(
605                 response, // response
606                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
607                 "authTokenType",
608                 null, // requiredFeatures
609                 false, // expectActivityLaunch
610                 options); // optionsIn
611         waitForLatch(latch);
612         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
613         Bundle result = mBundleCaptor.getValue();
614         Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
615         assertNotNull(sessionBundle);
616         // Assert that session bundle is encrypted and hence data not visible.
617         assertNull(sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
618         // Assert password is not returned
619         assertNull(result.getString(AccountManager.KEY_PASSWORD));
620         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
621         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN,
622                 result.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN));
623     }
624 
625     @SmallTest
testStartAddAccountSessionSuccessWithPasswordForwarding()626     public void testStartAddAccountSessionSuccessWithPasswordForwarding() throws Exception {
627         unlockSystemUser();
628         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
629                 PackageManager.PERMISSION_GRANTED);
630 
631         final CountDownLatch latch = new CountDownLatch(1);
632         Response response = new Response(latch, mMockAccountManagerResponse);
633         Bundle options = createOptionsWithAccountName(
634                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
635         mAms.startAddAccountSession(
636                 response, // response
637                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
638                 "authTokenType",
639                 null, // requiredFeatures
640                 false, // expectActivityLaunch
641                 options); // optionsIn
642 
643         waitForLatch(latch);
644         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
645         Bundle result = mBundleCaptor.getValue();
646         Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
647         assertNotNull(sessionBundle);
648         // Assert that session bundle is encrypted and hence data not visible.
649         assertNull(sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
650         // Assert password is returned
651         assertEquals(result.getString(AccountManager.KEY_PASSWORD),
652                 AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD);
653         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN));
654         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN,
655                 result.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN));
656     }
657 
658     @SmallTest
testStartAddAccountSessionReturnWithInvalidIntent()659     public void testStartAddAccountSessionReturnWithInvalidIntent() throws Exception {
660         unlockSystemUser();
661         ResolveInfo resolveInfo = new ResolveInfo();
662         resolveInfo.activityInfo = new ActivityInfo();
663         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
664         when(mMockPackageManager.resolveActivityAsUser(
665                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
666         when(mMockPackageManager.checkSignatures(
667                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
668         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
669                 .thenReturn(false);
670 
671         final CountDownLatch latch = new CountDownLatch(1);
672         Response response = new Response(latch, mMockAccountManagerResponse);
673         Bundle options = createOptionsWithAccountName(
674                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
675 
676         mAms.startAddAccountSession(
677                 response, // response
678                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
679                 "authTokenType",
680                 null, // requiredFeatures
681                 true, // expectActivityLaunch
682                 options); // optionsIn
683         waitForLatch(latch);
684         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
685         verify(mMockAccountManagerResponse).onError(
686                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
687     }
688 
689     @SmallTest
testStartAddAccountSessionReturnWithValidIntent()690     public void testStartAddAccountSessionReturnWithValidIntent() throws Exception {
691         unlockSystemUser();
692         ResolveInfo resolveInfo = new ResolveInfo();
693         resolveInfo.activityInfo = new ActivityInfo();
694         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
695         when(mMockPackageManager.resolveActivityAsUser(
696                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
697         when(mMockPackageManager.checkSignatures(
698                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
699 
700         final CountDownLatch latch = new CountDownLatch(1);
701         Response response = new Response(latch, mMockAccountManagerResponse);
702         Bundle options = createOptionsWithAccountName(
703                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
704 
705         mAms.startAddAccountSession(
706                 response, // response
707                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
708                 "authTokenType",
709                 null, // requiredFeatures
710                 true, // expectActivityLaunch
711                 options); // optionsIn
712         waitForLatch(latch);
713 
714         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
715         Bundle result = mBundleCaptor.getValue();
716         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
717         assertNotNull(intent);
718         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
719         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
720     }
721 
722     @SmallTest
testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()723     public void testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()
724             throws Exception {
725         unlockSystemUser();
726         ResolveInfo resolveInfo = new ResolveInfo();
727         resolveInfo.activityInfo = new ActivityInfo();
728         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
729         when(mMockPackageManager.resolveActivityAsUser(
730                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
731         when(mMockPackageManager.checkSignatures(
732                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
733 
734         final CountDownLatch latch = new CountDownLatch(1);
735         Response response = new Response(latch, mMockAccountManagerResponse);
736         Bundle options = createOptionsWithAccountName(
737                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
738         int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
739                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
740                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
741                 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
742         options.putInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, prohibitedFlags);
743 
744         mAms.startAddAccountSession(
745                 response, // response
746                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
747                 "authTokenType",
748                 null, // requiredFeatures
749                 true, // expectActivityLaunch
750                 options); // optionsIn
751         waitForLatch(latch);
752 
753         verify(mMockAccountManagerResponse).onError(
754                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), contains("invalid intent"));
755     }
756 
757     @SmallTest
testStartAddAccountSessionError()758     public void testStartAddAccountSessionError() throws Exception {
759         unlockSystemUser();
760         Bundle options = createOptionsWithAccountName(
761                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_ERROR);
762         options.putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_INVALID_RESPONSE);
763         options.putString(AccountManager.KEY_ERROR_MESSAGE,
764                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
765 
766         final CountDownLatch latch = new CountDownLatch(1);
767         Response response = new Response(latch, mMockAccountManagerResponse);
768         mAms.startAddAccountSession(
769                 response, // response
770                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
771                 "authTokenType",
772                 null, // requiredFeatures
773                 false, // expectActivityLaunch
774                 options); // optionsIn
775 
776         waitForLatch(latch);
777         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
778                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
779         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
780     }
781 
782     @SmallTest
testStartUpdateCredentialsSessionWithNullResponse()783     public void testStartUpdateCredentialsSessionWithNullResponse() throws Exception {
784         unlockSystemUser();
785         try {
786             mAms.startUpdateCredentialsSession(
787                 null, // response
788                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
789                 "authTokenType",
790                 true, // expectActivityLaunch
791                 null); // optionsIn
792             fail("IllegalArgumentException expected. But no exception was thrown.");
793         } catch (IllegalArgumentException e) {
794             // IllegalArgumentException is expected.
795         }
796     }
797 
798     @SmallTest
testStartUpdateCredentialsSessionWithNullAccount()799     public void testStartUpdateCredentialsSessionWithNullAccount() throws Exception {
800         unlockSystemUser();
801         try {
802             mAms.startUpdateCredentialsSession(
803                 mMockAccountManagerResponse, // response
804                 null,
805                 "authTokenType",
806                 true, // expectActivityLaunch
807                 null); // optionsIn
808             fail("IllegalArgumentException expected. But no exception was thrown.");
809         } catch (IllegalArgumentException e) {
810             // IllegalArgumentException is expected.
811         }
812     }
813 
814     @SmallTest
testStartUpdateCredentialsSessionSuccessWithoutPasswordForwarding()815     public void testStartUpdateCredentialsSessionSuccessWithoutPasswordForwarding()
816             throws Exception {
817         unlockSystemUser();
818         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
819                 PackageManager.PERMISSION_DENIED);
820 
821         final CountDownLatch latch = new CountDownLatch(1);
822         Response response = new Response(latch, mMockAccountManagerResponse);
823         Bundle options = createOptionsWithAccountName(
824             AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
825         mAms.startUpdateCredentialsSession(
826                 response, // response
827                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
828                 "authTokenType",
829                 false, // expectActivityLaunch
830                 options); // optionsIn
831         waitForLatch(latch);
832         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
833         Bundle result = mBundleCaptor.getValue();
834         Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
835         assertNotNull(sessionBundle);
836         // Assert that session bundle is encrypted and hence data not visible.
837         assertNull(sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
838         // Assert password is not returned
839         assertNull(result.getString(AccountManager.KEY_PASSWORD));
840         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
841         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN,
842                 result.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN));
843     }
844 
845     @SmallTest
testStartUpdateCredentialsSessionSuccessWithPasswordForwarding()846     public void testStartUpdateCredentialsSessionSuccessWithPasswordForwarding() throws Exception {
847         unlockSystemUser();
848         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
849                 PackageManager.PERMISSION_GRANTED);
850 
851         final CountDownLatch latch = new CountDownLatch(1);
852         Response response = new Response(latch, mMockAccountManagerResponse);
853         Bundle options = createOptionsWithAccountName(
854             AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
855         mAms.startUpdateCredentialsSession(
856                 response, // response
857                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
858                 "authTokenType",
859                 false, // expectActivityLaunch
860                 options); // optionsIn
861 
862         waitForLatch(latch);
863         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
864         Bundle result = mBundleCaptor.getValue();
865         Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
866         assertNotNull(sessionBundle);
867         // Assert that session bundle is encrypted and hence data not visible.
868         assertNull(sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
869         // Assert password is returned
870         assertEquals(result.getString(AccountManager.KEY_PASSWORD),
871                 AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD);
872         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN));
873         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN,
874                 result.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN));
875     }
876 
877     @SmallTest
testStartUpdateCredentialsSessionReturnWithInvalidIntent()878     public void testStartUpdateCredentialsSessionReturnWithInvalidIntent() throws Exception {
879         unlockSystemUser();
880         ResolveInfo resolveInfo = new ResolveInfo();
881         resolveInfo.activityInfo = new ActivityInfo();
882         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
883         when(mMockPackageManager.resolveActivityAsUser(
884                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
885         when(mMockPackageManager.checkSignatures(
886                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
887         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
888                 .thenReturn(false);
889 
890         final CountDownLatch latch = new CountDownLatch(1);
891         Response response = new Response(latch, mMockAccountManagerResponse);
892         Bundle options = createOptionsWithAccountName(
893                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
894 
895         mAms.startUpdateCredentialsSession(
896                 response, // response
897                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
898                 "authTokenType",
899                 true,  // expectActivityLaunch
900                 options); // optionsIn
901 
902         waitForLatch(latch);
903         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
904         verify(mMockAccountManagerResponse).onError(
905                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
906     }
907 
908     @SmallTest
testStartUpdateCredentialsSessionReturnWithValidIntent()909     public void testStartUpdateCredentialsSessionReturnWithValidIntent() throws Exception {
910         unlockSystemUser();
911         ResolveInfo resolveInfo = new ResolveInfo();
912         resolveInfo.activityInfo = new ActivityInfo();
913         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
914         when(mMockPackageManager.resolveActivityAsUser(
915                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
916         when(mMockPackageManager.checkSignatures(
917                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
918 
919         final CountDownLatch latch = new CountDownLatch(1);
920         Response response = new Response(latch, mMockAccountManagerResponse);
921         Bundle options = createOptionsWithAccountName(
922                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
923 
924         mAms.startUpdateCredentialsSession(
925                 response, // response
926                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
927                 "authTokenType",
928                 true,  // expectActivityLaunch
929                 options); // optionsIn
930 
931         waitForLatch(latch);
932 
933         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
934         Bundle result = mBundleCaptor.getValue();
935         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
936         assertNotNull(intent);
937         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
938         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
939     }
940 
941     @SmallTest
testStartUpdateCredentialsSessionError()942     public void testStartUpdateCredentialsSessionError() throws Exception {
943         unlockSystemUser();
944         Bundle options = createOptionsWithAccountName(
945                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_ERROR);
946         options.putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_INVALID_RESPONSE);
947         options.putString(AccountManager.KEY_ERROR_MESSAGE,
948                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
949 
950         final CountDownLatch latch = new CountDownLatch(1);
951         Response response = new Response(latch, mMockAccountManagerResponse);
952 
953         mAms.startUpdateCredentialsSession(
954                 response, // response
955                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
956                 "authTokenType",
957                 true,  // expectActivityLaunch
958                 options); // optionsIn
959 
960         waitForLatch(latch);
961         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
962                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
963         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
964     }
965 
966     @SmallTest
testFinishSessionAsUserWithNullResponse()967     public void testFinishSessionAsUserWithNullResponse() throws Exception {
968         unlockSystemUser();
969         try {
970             mAms.finishSessionAsUser(
971                 null, // response
972                 createEncryptedSessionBundle(
973                         AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
974                 false, // expectActivityLaunch
975                 createAppBundle(), // appInfo
976                 UserHandle.USER_SYSTEM);
977             fail("IllegalArgumentException expected. But no exception was thrown.");
978         } catch (IllegalArgumentException e) {
979             // IllegalArgumentException is expected.
980         }
981     }
982 
983     @SmallTest
testFinishSessionAsUserWithNullSessionBundle()984     public void testFinishSessionAsUserWithNullSessionBundle() throws Exception {
985         unlockSystemUser();
986         try {
987             mAms.finishSessionAsUser(
988                 mMockAccountManagerResponse, // response
989                 null, // sessionBundle
990                 false, // expectActivityLaunch
991                 createAppBundle(), // appInfo
992                 UserHandle.USER_SYSTEM);
993             fail("IllegalArgumentException expected. But no exception was thrown.");
994         } catch (IllegalArgumentException e) {
995             // IllegalArgumentException is expected.
996         }
997     }
998 
999     @SmallTest
testFinishSessionAsUserUserCannotModifyAccountNoDPM()1000     public void testFinishSessionAsUserUserCannotModifyAccountNoDPM() throws Exception {
1001         unlockSystemUser();
1002         Bundle bundle = new Bundle();
1003         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1004         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1005         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1006 
1007         mAms.finishSessionAsUser(
1008             mMockAccountManagerResponse, // response
1009             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1010             false, // expectActivityLaunch
1011             createAppBundle(), // appInfo
1012             2); // fake user id
1013 
1014         verify(mMockAccountManagerResponse).onError(
1015                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1016         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.of(2)));
1017 
1018         // verify the intent for default CantAddAccountActivity is sent.
1019         Intent intent = mIntentCaptor.getValue();
1020         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
1021         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
1022                 AccountManager.ERROR_CODE_USER_RESTRICTED);
1023     }
1024 
1025     @SmallTest
testFinishSessionAsUserUserCannotModifyAccountWithDPM()1026     public void testFinishSessionAsUserUserCannotModifyAccountWithDPM() throws Exception {
1027         unlockSystemUser();
1028         Bundle bundle = new Bundle();
1029         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1030         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1031         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1032         LocalServices.addService(
1033                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
1034         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
1035                 anyInt(), anyString())).thenReturn(new Intent());
1036         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
1037                 anyInt(), anyBoolean())).thenReturn(new Intent());
1038 
1039         mAms.finishSessionAsUser(
1040             mMockAccountManagerResponse, // response
1041             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1042             false, // expectActivityLaunch
1043             createAppBundle(), // appInfo
1044             2); // fake user id
1045 
1046         verify(mMockAccountManagerResponse).onError(
1047                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1048         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.of(2)));
1049         verify(mMockDevicePolicyManagerInternal).createUserRestrictionSupportIntent(
1050                 anyInt(), anyString());
1051     }
1052 
1053     @SmallTest
testFinishSessionAsUserWithBadSessionBundle()1054     public void testFinishSessionAsUserWithBadSessionBundle() throws Exception {
1055         unlockSystemUser();
1056 
1057         Bundle badSessionBundle = new Bundle();
1058         badSessionBundle.putString("any", "any");
1059         mAms.finishSessionAsUser(
1060             mMockAccountManagerResponse, // response
1061             badSessionBundle, // sessionBundle
1062             false, // expectActivityLaunch
1063             createAppBundle(), // appInfo
1064             2); // fake user id
1065 
1066         verify(mMockAccountManagerResponse).onError(
1067                 eq(AccountManager.ERROR_CODE_BAD_REQUEST), anyString());
1068     }
1069 
1070     @SmallTest
testFinishSessionAsUserWithBadAccountType()1071     public void testFinishSessionAsUserWithBadAccountType() throws Exception {
1072         unlockSystemUser();
1073 
1074         mAms.finishSessionAsUser(
1075             mMockAccountManagerResponse, // response
1076             createEncryptedSessionBundleWithNoAccountType(
1077                     AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1078             false, // expectActivityLaunch
1079             createAppBundle(), // appInfo
1080             2); // fake user id
1081 
1082         verify(mMockAccountManagerResponse).onError(
1083                 eq(AccountManager.ERROR_CODE_BAD_ARGUMENTS), anyString());
1084     }
1085 
1086     @SmallTest
testFinishSessionAsUserUserCannotModifyAccountForTypeNoDPM()1087     public void testFinishSessionAsUserUserCannotModifyAccountForTypeNoDPM() throws Exception {
1088         unlockSystemUser();
1089         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
1090                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
1091         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1092 
1093         mAms.finishSessionAsUser(
1094             mMockAccountManagerResponse, // response
1095             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1096             false, // expectActivityLaunch
1097             createAppBundle(), // appInfo
1098             2); // fake user id
1099 
1100         verify(mMockAccountManagerResponse).onError(
1101                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
1102         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.of(2)));
1103 
1104         // verify the intent for default CantAddAccountActivity is sent.
1105         Intent intent = mIntentCaptor.getValue();
1106         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
1107         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
1108                 AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE);
1109     }
1110 
1111     @SmallTest
testFinishSessionAsUserUserCannotModifyAccountForTypeWithDPM()1112     public void testFinishSessionAsUserUserCannotModifyAccountForTypeWithDPM() throws Exception {
1113         unlockSystemUser();
1114         when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
1115                 mMockDevicePolicyManager);
1116         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
1117                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
1118 
1119         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1120         LocalServices.addService(
1121                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
1122         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
1123                 anyInt(), anyString())).thenReturn(new Intent());
1124         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
1125                 anyInt(), anyBoolean())).thenReturn(new Intent());
1126 
1127         mAms.finishSessionAsUser(
1128             mMockAccountManagerResponse, // response
1129             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1130             false, // expectActivityLaunch
1131             createAppBundle(), // appInfo
1132             2); // fake user id
1133 
1134         verify(mMockAccountManagerResponse).onError(
1135                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
1136         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.of(2)));
1137         verify(mMockDevicePolicyManagerInternal).createShowAdminSupportIntent(
1138                 anyInt(), anyBoolean());
1139     }
1140 
1141     @SmallTest
testFinishSessionAsUserSuccess()1142     public void testFinishSessionAsUserSuccess() throws Exception {
1143         unlockSystemUser();
1144         final CountDownLatch latch = new CountDownLatch(1);
1145         Response response = new Response(latch, mMockAccountManagerResponse);
1146         mAms.finishSessionAsUser(
1147             response, // response
1148             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1149             false, // expectActivityLaunch
1150             createAppBundle(), // appInfo
1151             UserHandle.USER_SYSTEM);
1152 
1153         waitForLatch(latch);
1154         // Verify notification is cancelled
1155         verify(mMockNotificationManager).cancelNotificationWithTag(anyString(),
1156                 anyString(), nullable(String.class), anyInt(), anyInt());
1157 
1158         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1159         Bundle result = mBundleCaptor.getValue();
1160         Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
1161         assertNotNull(sessionBundle);
1162         // Assert that session bundle is decrypted and hence data is visible.
1163         assertEquals(AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1,
1164                 sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
1165         // Assert finishSessionAsUser added calling uid and pid into the sessionBundle
1166         assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID));
1167         assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID));
1168         assertEquals(sessionBundle.getString(
1169                 AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package");
1170 
1171         // Verify response data
1172         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
1173         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME,
1174                 result.getString(AccountManager.KEY_ACCOUNT_NAME));
1175         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
1176                 result.getString(AccountManager.KEY_ACCOUNT_TYPE));
1177     }
1178 
1179     @SmallTest
testFinishSessionAsUserReturnWithInvalidIntent()1180     public void testFinishSessionAsUserReturnWithInvalidIntent() throws Exception {
1181         unlockSystemUser();
1182         ResolveInfo resolveInfo = new ResolveInfo();
1183         resolveInfo.activityInfo = new ActivityInfo();
1184         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1185         when(mMockPackageManager.resolveActivityAsUser(
1186                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1187         when(mMockPackageManager.checkSignatures(
1188                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
1189         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
1190                 .thenReturn(false);
1191 
1192         final CountDownLatch latch = new CountDownLatch(1);
1193         Response response = new Response(latch, mMockAccountManagerResponse);
1194 
1195         mAms.finishSessionAsUser(
1196             response, // response
1197             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
1198             true, // expectActivityLaunch
1199             createAppBundle(), // appInfo
1200             UserHandle.USER_SYSTEM);
1201 
1202         waitForLatch(latch);
1203         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1204         verify(mMockAccountManagerResponse).onError(
1205                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
1206     }
1207 
1208     @SmallTest
testFinishSessionAsUserReturnWithValidIntent()1209     public void testFinishSessionAsUserReturnWithValidIntent() throws Exception {
1210         unlockSystemUser();
1211         ResolveInfo resolveInfo = new ResolveInfo();
1212         resolveInfo.activityInfo = new ActivityInfo();
1213         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1214         when(mMockPackageManager.resolveActivityAsUser(
1215                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1216         when(mMockPackageManager.checkSignatures(
1217                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
1218 
1219         final CountDownLatch latch = new CountDownLatch(1);
1220         Response response = new Response(latch, mMockAccountManagerResponse);
1221 
1222         mAms.finishSessionAsUser(
1223             response, // response
1224             createEncryptedSessionBundle(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
1225             true, // expectActivityLaunch
1226             createAppBundle(), // appInfo
1227             UserHandle.USER_SYSTEM);
1228 
1229         waitForLatch(latch);
1230 
1231         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1232         Bundle result = mBundleCaptor.getValue();
1233         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
1234         assertNotNull(intent);
1235         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
1236         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
1237     }
1238 
1239     @SmallTest
testFinishSessionAsUserError()1240     public void testFinishSessionAsUserError() throws Exception {
1241         unlockSystemUser();
1242         Bundle sessionBundle = createEncryptedSessionBundleWithError(
1243                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_ERROR);
1244 
1245         final CountDownLatch latch = new CountDownLatch(1);
1246         Response response = new Response(latch, mMockAccountManagerResponse);
1247 
1248         mAms.finishSessionAsUser(
1249             response, // response
1250             sessionBundle,
1251             false, // expectActivityLaunch
1252             createAppBundle(), // appInfo
1253             UserHandle.USER_SYSTEM);
1254 
1255         waitForLatch(latch);
1256         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
1257                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
1258         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1259     }
1260 
1261     @SmallTest
testIsCredentialsUpdatedSuggestedWithNullResponse()1262     public void testIsCredentialsUpdatedSuggestedWithNullResponse() throws Exception {
1263         unlockSystemUser();
1264         try {
1265             mAms.isCredentialsUpdateSuggested(
1266                 null, // response
1267                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1268                 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN);
1269             fail("IllegalArgumentException expected. But no exception was thrown.");
1270         } catch (IllegalArgumentException e) {
1271             // IllegalArgumentException is expected.
1272         }
1273     }
1274 
1275     @SmallTest
testIsCredentialsUpdatedSuggestedWithNullAccount()1276     public void testIsCredentialsUpdatedSuggestedWithNullAccount() throws Exception {
1277         unlockSystemUser();
1278         try {
1279             mAms.isCredentialsUpdateSuggested(
1280                 mMockAccountManagerResponse,
1281                 null, // account
1282                 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN);
1283             fail("IllegalArgumentException expected. But no exception was thrown.");
1284         } catch (IllegalArgumentException e) {
1285             // IllegalArgumentException is expected.
1286         }
1287     }
1288 
1289     @SmallTest
testIsCredentialsUpdatedSuggestedWithEmptyStatusToken()1290     public void testIsCredentialsUpdatedSuggestedWithEmptyStatusToken() throws Exception {
1291         unlockSystemUser();
1292         try {
1293             mAms.isCredentialsUpdateSuggested(
1294                 mMockAccountManagerResponse,
1295                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1296                 null);
1297             fail("IllegalArgumentException expected. But no exception was thrown.");
1298         } catch (IllegalArgumentException e) {
1299             // IllegalArgumentException is expected.
1300         }
1301     }
1302 
1303     @SmallTest
testIsCredentialsUpdatedSuggestedError()1304     public void testIsCredentialsUpdatedSuggestedError() throws Exception {
1305         unlockSystemUser();
1306         final CountDownLatch latch = new CountDownLatch(1);
1307         Response response = new Response(latch, mMockAccountManagerResponse);
1308 
1309         mAms.isCredentialsUpdateSuggested(
1310             response,
1311             AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
1312             AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN);
1313 
1314         waitForLatch(latch);
1315         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
1316                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
1317         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1318     }
1319 
1320     @SmallTest
testIsCredentialsUpdatedSuggestedSuccess()1321     public void testIsCredentialsUpdatedSuggestedSuccess() throws Exception {
1322         unlockSystemUser();
1323         final CountDownLatch latch = new CountDownLatch(1);
1324         Response response = new Response(latch, mMockAccountManagerResponse);
1325 
1326         mAms.isCredentialsUpdateSuggested(
1327             response,
1328             AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1329             AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN);
1330 
1331         waitForLatch(latch);
1332         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1333         Bundle result = mBundleCaptor.getValue();
1334         boolean needUpdate = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
1335         assertTrue(needUpdate);
1336     }
1337 
1338     @SmallTest
testHasFeaturesWithNullResponse()1339     public void testHasFeaturesWithNullResponse() throws Exception {
1340         unlockSystemUser();
1341         try {
1342             mAms.hasFeatures(
1343                     null, // response
1344                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1345                     new String[] {"feature1", "feature2"}, // features
1346                     0, // userId
1347                     "testPackage"); // opPackageName
1348             fail("IllegalArgumentException expected. But no exception was thrown.");
1349         } catch (IllegalArgumentException e) {
1350             // IllegalArgumentException is expected.
1351         }
1352     }
1353 
1354     @SmallTest
testHasFeaturesWithNullAccount()1355     public void testHasFeaturesWithNullAccount() throws Exception {
1356         unlockSystemUser();
1357         try {
1358             mAms.hasFeatures(
1359                     mMockAccountManagerResponse, // response
1360                     null, // account
1361                     new String[] {"feature1", "feature2"}, // features
1362                     0, // userId
1363                     "testPackage"); // opPackageName
1364             fail("IllegalArgumentException expected. But no exception was thrown.");
1365         } catch (IllegalArgumentException e) {
1366             // IllegalArgumentException is expected.
1367         }
1368     }
1369 
1370     @SmallTest
testHasFeaturesWithNullFeature()1371     public void testHasFeaturesWithNullFeature() throws Exception {
1372         unlockSystemUser();
1373         try {
1374             mAms.hasFeatures(
1375                     mMockAccountManagerResponse, // response
1376                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, // account
1377                     null, // features
1378                     0, // userId
1379                     "testPackage"); // opPackageName
1380             fail("IllegalArgumentException expected. But no exception was thrown.");
1381         } catch (IllegalArgumentException e) {
1382             // IllegalArgumentException is expected.
1383         }
1384     }
1385 
1386     @SmallTest
testHasFeaturesReturnNullResult()1387     public void testHasFeaturesReturnNullResult() throws Exception {
1388         unlockSystemUser();
1389         final CountDownLatch latch = new CountDownLatch(1);
1390         Response response = new Response(latch, mMockAccountManagerResponse);
1391         mAms.hasFeatures(
1392                 response, // response
1393                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR, // account
1394                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES, // features
1395                 0, // userId
1396                 "testPackage"); // opPackageName
1397         waitForLatch(latch);
1398         verify(mMockAccountManagerResponse).onError(
1399                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
1400         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1401     }
1402 
1403     @SmallTest
testHasFeaturesSuccess()1404     public void testHasFeaturesSuccess() throws Exception {
1405         unlockSystemUser();
1406         final CountDownLatch latch = new CountDownLatch(1);
1407         Response response = new Response(latch, mMockAccountManagerResponse);
1408         mAms.hasFeatures(
1409                 response, // response
1410                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, // account
1411                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES, // features
1412                 0, // userId
1413                 "testPackage"); // opPackageName
1414         waitForLatch(latch);
1415         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1416         Bundle result = mBundleCaptor.getValue();
1417         boolean hasFeatures = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
1418         assertTrue(hasFeatures);
1419     }
1420 
1421     @SmallTest
testRemoveAccountAsUserWithNullResponse()1422     public void testRemoveAccountAsUserWithNullResponse() throws Exception {
1423         unlockSystemUser();
1424         try {
1425             mAms.removeAccountAsUser(
1426                 null, // response
1427                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1428                 true, // expectActivityLaunch
1429                 UserHandle.USER_SYSTEM);
1430             fail("IllegalArgumentException expected. But no exception was thrown.");
1431         } catch (IllegalArgumentException e) {
1432             // IllegalArgumentException is expected.
1433         }
1434     }
1435 
1436     @SmallTest
testRemoveAccountAsUserWithNullAccount()1437     public void testRemoveAccountAsUserWithNullAccount() throws Exception {
1438         unlockSystemUser();
1439         try {
1440             mAms.removeAccountAsUser(
1441                 mMockAccountManagerResponse, // response
1442                 null, // account
1443                 true, // expectActivityLaunch
1444                 UserHandle.USER_SYSTEM);
1445             fail("IllegalArgumentException expected. But no exception was thrown.");
1446         } catch (IllegalArgumentException e) {
1447             // IllegalArgumentException is expected.
1448         }
1449     }
1450 
1451     @SmallTest
testRemoveAccountAsUserAccountNotManagedByCaller()1452     public void testRemoveAccountAsUserAccountNotManagedByCaller() throws Exception {
1453         unlockSystemUser();
1454         when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
1455                     .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
1456         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
1457                 .thenReturn(false);
1458         try {
1459             mAms.removeAccountAsUser(
1460                 mMockAccountManagerResponse, // response
1461                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1462                 true, // expectActivityLaunch
1463                 UserHandle.USER_SYSTEM);
1464             fail("SecurityException expected. But no exception was thrown.");
1465         } catch (SecurityException e) {
1466             // SecurityException is expected.
1467         }
1468     }
1469 
1470     @SmallTest
testRemoveAccountAsUserUserCannotModifyAccount()1471     public void testRemoveAccountAsUserUserCannotModifyAccount() throws Exception {
1472         unlockSystemUser();
1473         Bundle bundle = new Bundle();
1474         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1475         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1476 
1477         final CountDownLatch latch = new CountDownLatch(1);
1478         Response response = new Response(latch, mMockAccountManagerResponse);
1479 
1480         mAms.removeAccountAsUser(
1481                 response, // response
1482                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1483                 true, // expectActivityLaunch
1484                 UserHandle.USER_SYSTEM);
1485         waitForLatch(latch);
1486         verify(mMockAccountManagerResponse).onError(
1487                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1488         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1489     }
1490 
1491     @SmallTest
testRemoveAccountAsUserUserCannotModifyAccountType()1492     public void testRemoveAccountAsUserUserCannotModifyAccountType() throws Exception {
1493         unlockSystemUser();
1494         when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
1495                 mMockDevicePolicyManager);
1496         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
1497                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
1498 
1499         final CountDownLatch latch = new CountDownLatch(1);
1500         Response response = new Response(latch, mMockAccountManagerResponse);
1501 
1502         mAms.removeAccountAsUser(
1503                 response, // response
1504                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1505                 true, // expectActivityLaunch
1506                 UserHandle.USER_SYSTEM);
1507         waitForLatch(latch);
1508         verify(mMockAccountManagerResponse).onError(
1509                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
1510         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1511     }
1512 
1513     @SmallTest
testRemoveAccountAsUserRemovalAllowed()1514     public void testRemoveAccountAsUserRemovalAllowed() throws Exception {
1515         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1516         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1517 
1518         unlockSystemUser();
1519         mAms.addAccountExplicitly(
1520                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1521                 /* password= */ "p1",
1522                 /* extras= */ null,
1523                 /* callerPackage= */ null);
1524         Account[] addedAccounts =
1525                 mAms.getAccounts(UserHandle.USER_SYSTEM, mContext.getOpPackageName());
1526         assertEquals(1, addedAccounts.length);
1527 
1528         final CountDownLatch latch = new CountDownLatch(1);
1529         Response response = new Response(latch, mMockAccountManagerResponse);
1530 
1531         mAms.removeAccountAsUser(
1532                 response, // response
1533                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1534                 true, // expectActivityLaunch
1535                 UserHandle.USER_SYSTEM);
1536         waitForLatch(latch);
1537 
1538         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1539         Bundle result = mBundleCaptor.getValue();
1540         boolean allowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
1541         assertTrue(allowed);
1542         Account[] accounts = mAms.getAccounts(UserHandle.USER_SYSTEM, mContext.getOpPackageName());
1543         assertEquals(0, accounts.length);
1544     }
1545 
1546     @SmallTest
testRemoveAccountAsUserRemovalNotAllowed()1547     public void testRemoveAccountAsUserRemovalNotAllowed() throws Exception {
1548         unlockSystemUser();
1549 
1550         final CountDownLatch latch = new CountDownLatch(1);
1551         Response response = new Response(latch, mMockAccountManagerResponse);
1552 
1553         mAms.removeAccountAsUser(
1554                 response, // response
1555                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
1556                 true, // expectActivityLaunch
1557                 UserHandle.USER_SYSTEM);
1558         waitForLatch(latch);
1559 
1560         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1561         Bundle result = mBundleCaptor.getValue();
1562         boolean allowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
1563         assertFalse(allowed);
1564     }
1565 
1566     @SmallTest
testRemoveAccountAsUserReturnWithValidIntent()1567     public void testRemoveAccountAsUserReturnWithValidIntent() throws Exception {
1568         unlockSystemUser();
1569         ResolveInfo resolveInfo = new ResolveInfo();
1570         resolveInfo.activityInfo = new ActivityInfo();
1571         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1572         when(mMockPackageManager.resolveActivityAsUser(
1573                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1574         when(mMockPackageManager.checkSignatures(
1575                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
1576 
1577         final CountDownLatch latch = new CountDownLatch(1);
1578         Response response = new Response(latch, mMockAccountManagerResponse);
1579 
1580         mAms.removeAccountAsUser(
1581                 response, // response
1582                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1583                 true, // expectActivityLaunch
1584                 UserHandle.USER_SYSTEM);
1585         waitForLatch(latch);
1586 
1587         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1588         Bundle result = mBundleCaptor.getValue();
1589         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
1590         assertNotNull(intent);
1591     }
1592 
1593     @SmallTest
testGetAccountsByTypeForPackageWhenTypeIsNull()1594     public void testGetAccountsByTypeForPackageWhenTypeIsNull() throws Exception {
1595         unlockSystemUser();
1596         HashMap<String, Integer> visibility1 = new HashMap<>();
1597         visibility1.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
1598             AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
1599 
1600         HashMap<String, Integer> visibility2 = new HashMap<>();
1601         visibility2.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
1602             AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
1603 
1604         mAms.addAccountExplicitlyWithVisibility(
1605                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1606                 /* password= */ "P11",
1607                 /* extras= */ null,
1608                 visibility1,
1609                 /* callerPackage= */ null);
1610         mAms.addAccountExplicitlyWithVisibility(
1611                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1612                 /* password= */ "P12",
1613                 /* extras= */ null,
1614                 visibility2,
1615                 /* callerPackage= */ null);
1616 
1617         Account[] accounts = mAms.getAccountsByTypeForPackage(
1618             null, "otherPackageName",
1619             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
1620         // Only get the USER_MANAGED_NOT_VISIBLE account.
1621         assertEquals(1, accounts.length);
1622         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accounts[0].name);
1623         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accounts[0].type);
1624     }
1625 
1626     @SmallTest
testGetAuthTokenLabelWithNullAccountType()1627     public void testGetAuthTokenLabelWithNullAccountType() throws Exception {
1628         unlockSystemUser();
1629         try {
1630             mAms.getAuthTokenLabel(
1631                 mMockAccountManagerResponse, // response
1632                 null, // accountType
1633                 "authTokenType");
1634             fail("IllegalArgumentException expected. But no exception was thrown.");
1635         } catch (IllegalArgumentException e) {
1636             // IllegalArgumentException is expected.
1637         }
1638     }
1639 
1640     @SmallTest
testGetAuthTokenLabelWithNullAuthTokenType()1641     public void testGetAuthTokenLabelWithNullAuthTokenType() throws Exception {
1642         unlockSystemUser();
1643         try {
1644             mAms.getAuthTokenLabel(
1645                 mMockAccountManagerResponse, // response
1646                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1647                 null); // authTokenType
1648             fail("IllegalArgumentException expected. But no exception was thrown.");
1649         } catch (IllegalArgumentException e) {
1650             // IllegalArgumentException is expected.
1651         }
1652     }
1653 
1654     @SmallTest
testGetAuthTokenWithNullResponse()1655     public void testGetAuthTokenWithNullResponse() throws Exception {
1656         unlockSystemUser();
1657         try {
1658             mAms.getAuthToken(
1659                     null, // response
1660                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1661                     "authTokenType", // authTokenType
1662                     true, // notifyOnAuthFailure
1663                     true, // expectActivityLaunch
1664                     createGetAuthTokenOptions());
1665             fail("IllegalArgumentException expected. But no exception was thrown.");
1666         } catch (IllegalArgumentException e) {
1667             // IllegalArgumentException is expected.
1668         }
1669     }
1670 
1671     @SmallTest
testGetAuthTokenWithNullAccount()1672     public void testGetAuthTokenWithNullAccount() throws Exception {
1673         unlockSystemUser();
1674         final CountDownLatch latch = new CountDownLatch(1);
1675         Response response = new Response(latch, mMockAccountManagerResponse);
1676         mAms.getAuthToken(
1677                     response, // response
1678                     null, // account
1679                     "authTokenType", // authTokenType
1680                     true, // notifyOnAuthFailure
1681                     true, // expectActivityLaunch
1682                     createGetAuthTokenOptions());
1683         waitForLatch(latch);
1684 
1685         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1686         verify(mMockAccountManagerResponse).onError(
1687                 eq(AccountManager.ERROR_CODE_BAD_ARGUMENTS), anyString());
1688     }
1689 
1690     @SmallTest
testGetAuthTokenWithNullAuthTokenType()1691     public void testGetAuthTokenWithNullAuthTokenType() throws Exception {
1692         unlockSystemUser();
1693         final CountDownLatch latch = new CountDownLatch(1);
1694         Response response = new Response(latch, mMockAccountManagerResponse);
1695         mAms.getAuthToken(
1696                     response, // response
1697                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1698                     null, // authTokenType
1699                     true, // notifyOnAuthFailure
1700                     true, // expectActivityLaunch
1701                     createGetAuthTokenOptions());
1702         waitForLatch(latch);
1703 
1704         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1705         verify(mMockAccountManagerResponse).onError(
1706                 eq(AccountManager.ERROR_CODE_BAD_ARGUMENTS), anyString());
1707     }
1708 
1709     @SmallTest
testGetAuthTokenWithInvalidPackage()1710     public void testGetAuthTokenWithInvalidPackage() throws Exception {
1711         unlockSystemUser();
1712         String[] list = new String[]{"test"};
1713         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1714         try {
1715             mAms.getAuthToken(
1716                     mMockAccountManagerResponse, // response
1717                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1718                     "authTokenType", // authTokenType
1719                     true, // notifyOnAuthFailure
1720                     true, // expectActivityLaunch
1721                     createGetAuthTokenOptions());
1722             fail("SecurityException expected. But no exception was thrown.");
1723         } catch (SecurityException e) {
1724             // SecurityException is expected.
1725         }
1726     }
1727 
1728     @SmallTest
testGetAuthTokenFromInternal()1729     public void testGetAuthTokenFromInternal() throws Exception {
1730         unlockSystemUser();
1731         when(mMockContext.createPackageContextAsUser(
1732                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1733         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1734         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1735         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1736         mAms.addAccountExplicitly(
1737                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1738                 /* password= */ "p11",
1739                 /* extras= */ null,
1740                 /* callerPackage= */ null);
1741 
1742         mAms.setAuthToken(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1743                 "authTokenType", AccountManagerServiceTestFixtures.AUTH_TOKEN);
1744         final CountDownLatch latch = new CountDownLatch(1);
1745         Response response = new Response(latch, mMockAccountManagerResponse);
1746         mAms.getAuthToken(
1747                     response, // response
1748                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1749                     "authTokenType", // authTokenType
1750                     true, // notifyOnAuthFailure
1751                     true, // expectActivityLaunch
1752                     createGetAuthTokenOptions());
1753         waitForLatch(latch);
1754 
1755         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1756         Bundle result = mBundleCaptor.getValue();
1757         assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN),
1758                 AccountManagerServiceTestFixtures.AUTH_TOKEN);
1759         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME),
1760                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
1761         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE),
1762                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
1763     }
1764 
1765     @SmallTest
testGetAuthTokenSuccess()1766     public void testGetAuthTokenSuccess() throws Exception {
1767         unlockSystemUser();
1768         when(mMockContext.createPackageContextAsUser(
1769                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1770         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1771         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1772         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1773 
1774         final CountDownLatch latch = new CountDownLatch(1);
1775         Response response = new Response(latch, mMockAccountManagerResponse);
1776         long expiryEpochTimeInMillis = System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND;
1777         mAms.getAuthToken(
1778                     response, // response
1779                     AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1780                     "authTokenType", // authTokenType
1781                     true, // notifyOnAuthFailure
1782                     false, // expectActivityLaunch
1783                 createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis));
1784         waitForLatch(latch);
1785 
1786         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1787         Bundle result = mBundleCaptor.getValue();
1788         assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN),
1789                 AccountManagerServiceTestFixtures.AUTH_TOKEN);
1790         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME),
1791                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
1792         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE),
1793                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
1794         assertEquals(result.getLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY),
1795                 expiryEpochTimeInMillis);
1796     }
1797 
1798     @SmallTest
testGetAuthTokenCachedSuccess()1799     public void testGetAuthTokenCachedSuccess() throws Exception {
1800         unlockSystemUser();
1801         when(mMockContext.createPackageContextAsUser(
1802                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1803         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1804         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1805         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1806 
1807         final CountDownLatch latch = new CountDownLatch(1);
1808         Response response = new Response(latch, mMockAccountManagerResponse);
1809         long expiryEpochTimeInMillis = System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND;
1810         mAms.getAuthToken(
1811                 response, // response
1812                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1813                 "authTokenType", // authTokenType
1814                 true, // notifyOnAuthFailure
1815                 false, // expectActivityLaunch
1816                 createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis));
1817         waitForLatch(latch);
1818 
1819         // Make call for cached token.
1820         mAms.getAuthToken(
1821                 response, // response
1822                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1823                 "authTokenType", // authTokenType
1824                 true, // notifyOnAuthFailure
1825                 false, // expectActivityLaunch
1826                 createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis + 10));
1827         waitForLatch(latch);
1828 
1829         verify(mMockAccountManagerResponse, times(2)).onResult(mBundleCaptor.capture());
1830         List<Bundle> result = mBundleCaptor.getAllValues();
1831         assertGetTokenResponse(result.get(0), expiryEpochTimeInMillis);
1832         // cached token was returned with the same expiration time as first token.
1833         assertGetTokenResponse(result.get(1), expiryEpochTimeInMillis);
1834     }
1835 
assertGetTokenResponse(Bundle result, long expiryEpochTimeInMillis)1836     private void assertGetTokenResponse(Bundle result, long expiryEpochTimeInMillis) {
1837         assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN),
1838                 AccountManagerServiceTestFixtures.AUTH_TOKEN);
1839         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME),
1840                 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
1841         assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE),
1842                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
1843         assertEquals(result.getLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY),
1844                 expiryEpochTimeInMillis);
1845 
1846     }
1847 
1848     @SmallTest
testGetAuthTokenReturnWithInvalidIntent()1849     public void testGetAuthTokenReturnWithInvalidIntent() throws Exception {
1850         unlockSystemUser();
1851         when(mMockContext.createPackageContextAsUser(
1852                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1853         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1854         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1855         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1856         ResolveInfo resolveInfo = new ResolveInfo();
1857         resolveInfo.activityInfo = new ActivityInfo();
1858         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1859         when(mMockPackageManager.resolveActivityAsUser(
1860                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1861         when(mMockPackageManager.checkSignatures(
1862                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
1863         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
1864                 .thenReturn(false);
1865 
1866         final CountDownLatch latch = new CountDownLatch(1);
1867         Response response = new Response(latch, mMockAccountManagerResponse);
1868         mAms.getAuthToken(
1869                     response, // response
1870                     AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1871                     "authTokenType", // authTokenType
1872                     true, // notifyOnAuthFailure
1873                     false, // expectActivityLaunch
1874                     createGetAuthTokenOptions());
1875         waitForLatch(latch);
1876         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1877         verify(mMockAccountManagerResponse).onError(
1878                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
1879     }
1880 
1881     @SmallTest
testGetAuthTokenReturnWithValidIntent()1882     public void testGetAuthTokenReturnWithValidIntent() throws Exception {
1883         unlockSystemUser();
1884         when(mMockContext.createPackageContextAsUser(
1885                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1886         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1887         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1888         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1889 
1890         ResolveInfo resolveInfo = new ResolveInfo();
1891         resolveInfo.activityInfo = new ActivityInfo();
1892         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1893         when(mMockPackageManager.resolveActivityAsUser(
1894                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1895         when(mMockPackageManager.checkSignatures(
1896                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
1897 
1898         final CountDownLatch latch = new CountDownLatch(1);
1899         Response response = new Response(latch, mMockAccountManagerResponse);
1900         mAms.getAuthToken(
1901                     response, // response
1902                     AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1903                     "authTokenType", // authTokenType
1904                     false, // notifyOnAuthFailure
1905                     true, // expectActivityLaunch
1906                     createGetAuthTokenOptions());
1907         waitForLatch(latch);
1908         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1909         Bundle result = mBundleCaptor.getValue();
1910         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
1911         assertNotNull(intent);
1912         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
1913         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
1914     }
1915 
1916     @SmallTest
testGetAuthTokenError()1917     public void testGetAuthTokenError() throws Exception {
1918         unlockSystemUser();
1919         when(mMockContext.createPackageContextAsUser(
1920                  anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1921         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1922         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1923         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1924         final CountDownLatch latch = new CountDownLatch(1);
1925         Response response = new Response(latch, mMockAccountManagerResponse);
1926         mAms.getAuthToken(
1927                     response, // response
1928                     AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
1929                     "authTokenType", // authTokenType
1930                     true, // notifyOnAuthFailure
1931                     false, // expectActivityLaunch
1932                     createGetAuthTokenOptions());
1933         waitForLatch(latch);
1934         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
1935                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
1936         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1937 
1938     }
1939 
1940     @SmallTest
testAddAccountAsUserWithNullResponse()1941     public void testAddAccountAsUserWithNullResponse() throws Exception {
1942         unlockSystemUser();
1943         try {
1944             mAms.addAccountAsUser(
1945                 null, // response
1946                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
1947                 "authTokenType",
1948                 null, // requiredFeatures
1949                 true, // expectActivityLaunch
1950                 null, // optionsIn
1951                 UserHandle.USER_SYSTEM);
1952             fail("IllegalArgumentException expected. But no exception was thrown.");
1953         } catch (IllegalArgumentException e) {
1954             // IllegalArgumentException is expected.
1955         }
1956     }
1957 
1958     @SmallTest
testAddAccountAsUserWithNullAccountType()1959     public void testAddAccountAsUserWithNullAccountType() throws Exception {
1960         unlockSystemUser();
1961         try {
1962             mAms.addAccountAsUser(
1963                 mMockAccountManagerResponse, // response
1964                 null, // accountType
1965                 "authTokenType",
1966                 null, // requiredFeatures
1967                 true, // expectActivityLaunch
1968                 null, // optionsIn
1969                 UserHandle.USER_SYSTEM);
1970             fail("IllegalArgumentException expected. But no exception was thrown.");
1971         } catch (IllegalArgumentException e) {
1972             // IllegalArgumentException is expected.
1973         }
1974     }
1975 
1976     @SmallTest
testAddAccountAsUserUserCannotModifyAccountNoDPM()1977     public void testAddAccountAsUserUserCannotModifyAccountNoDPM() throws Exception {
1978         unlockSystemUser();
1979         Bundle bundle = new Bundle();
1980         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1981         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1982         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1983 
1984         mAms.addAccountAsUser(
1985                 mMockAccountManagerResponse, // response
1986                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1987                 "authTokenType",
1988                 null, // requiredFeatures
1989                 true, // expectActivityLaunch
1990                 null, // optionsIn
1991                 UserHandle.USER_SYSTEM);
1992         verify(mMockAccountManagerResponse).onError(
1993                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1994         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
1995 
1996         // verify the intent for default CantAddAccountActivity is sent.
1997         Intent intent = mIntentCaptor.getValue();
1998         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
1999         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
2000                 AccountManager.ERROR_CODE_USER_RESTRICTED);
2001     }
2002 
2003     @SmallTest
testAddAccountAsUserUserCannotModifyAccountWithDPM()2004     public void testAddAccountAsUserUserCannotModifyAccountWithDPM() throws Exception {
2005         unlockSystemUser();
2006         Bundle bundle = new Bundle();
2007         bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
2008         when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
2009         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
2010         LocalServices.addService(
2011                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
2012         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
2013                 anyInt(), anyString())).thenReturn(new Intent());
2014         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
2015                 anyInt(), anyBoolean())).thenReturn(new Intent());
2016 
2017         mAms.addAccountAsUser(
2018                 mMockAccountManagerResponse, // response
2019                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2020                 "authTokenType",
2021                 null, // requiredFeatures
2022                 true, // expectActivityLaunch
2023                 null, // optionsIn
2024                 UserHandle.USER_SYSTEM);
2025 
2026         verify(mMockAccountManagerResponse).onError(
2027                 eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
2028         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
2029         verify(mMockDevicePolicyManagerInternal).createUserRestrictionSupportIntent(
2030                 anyInt(), anyString());
2031     }
2032 
2033     @SmallTest
testAddAccountAsUserUserCannotModifyAccountForTypeNoDPM()2034     public void testAddAccountAsUserUserCannotModifyAccountForTypeNoDPM() throws Exception {
2035         unlockSystemUser();
2036         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
2037                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
2038         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
2039 
2040         mAms.addAccountAsUser(
2041                 mMockAccountManagerResponse, // response
2042                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2043                 "authTokenType",
2044                 null, // requiredFeatures
2045                 true, // expectActivityLaunch
2046                 null, // optionsIn
2047                 UserHandle.USER_SYSTEM);
2048 
2049         verify(mMockAccountManagerResponse).onError(
2050                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
2051         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2052 
2053         // verify the intent for default CantAddAccountActivity is sent.
2054         Intent intent = mIntentCaptor.getValue();
2055         assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
2056         assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
2057                 AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE);
2058     }
2059 
2060     @SmallTest
testAddAccountAsUserUserCannotModifyAccountForTypeWithDPM()2061     public void testAddAccountAsUserUserCannotModifyAccountForTypeWithDPM() throws Exception {
2062         unlockSystemUser();
2063         when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
2064                 mMockDevicePolicyManager);
2065         when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
2066                 .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
2067 
2068         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
2069         LocalServices.addService(
2070                 DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
2071         when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
2072                 anyInt(), anyString())).thenReturn(new Intent());
2073         when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
2074                 anyInt(), anyBoolean())).thenReturn(new Intent());
2075 
2076         mAms.addAccountAsUser(
2077                 mMockAccountManagerResponse, // response
2078                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2079                 "authTokenType",
2080                 null, // requiredFeatures
2081                 true, // expectActivityLaunch
2082                 null, // optionsIn
2083                 UserHandle.USER_SYSTEM);
2084 
2085         verify(mMockAccountManagerResponse).onError(
2086                 eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
2087         verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
2088         verify(mMockDevicePolicyManagerInternal).createShowAdminSupportIntent(
2089                 anyInt(), anyBoolean());
2090     }
2091 
2092     @SmallTest
testAddAccountAsUserSuccess()2093     public void testAddAccountAsUserSuccess() throws Exception {
2094         unlockSystemUser();
2095         final CountDownLatch latch = new CountDownLatch(1);
2096         Response response = new Response(latch, mMockAccountManagerResponse);
2097         mAms.addAccountAsUser(
2098                 response, // response
2099                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2100                 "authTokenType",
2101                 null, // requiredFeatures
2102                 true, // expectActivityLaunch
2103                 createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
2104                 UserHandle.USER_SYSTEM);
2105         waitForLatch(latch);
2106         // Verify notification is cancelled
2107         verify(mMockNotificationManager).cancelNotificationWithTag(anyString(),
2108                 anyString(), nullable(String.class), anyInt(), anyInt());
2109 
2110         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2111         Bundle result = mBundleCaptor.getValue();
2112         // Verify response data
2113         assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
2114         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2115                 result.getString(AccountManager.KEY_ACCOUNT_NAME));
2116         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2117                 result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2118 
2119         Bundle optionBundle = result.getParcelable(
2120                 AccountManagerServiceTestFixtures.KEY_OPTIONS_BUNDLE);
2121         // Assert addAccountAsUser added calling uid and pid into the option bundle
2122         assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_UID));
2123         assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_PID));
2124     }
2125 
2126     @SmallTest
testAddAccountAsUserReturnWithInvalidIntent()2127     public void testAddAccountAsUserReturnWithInvalidIntent() throws Exception {
2128         unlockSystemUser();
2129         ResolveInfo resolveInfo = new ResolveInfo();
2130         resolveInfo.activityInfo = new ActivityInfo();
2131         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2132         when(mMockPackageManager.resolveActivityAsUser(
2133                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2134         when(mMockPackageManager.checkSignatures(
2135                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2136         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
2137                 .thenReturn(false);
2138 
2139         final CountDownLatch latch = new CountDownLatch(1);
2140         Response response = new Response(latch, mMockAccountManagerResponse);
2141         mAms.addAccountAsUser(
2142                 response, // response
2143                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2144                 "authTokenType",
2145                 null, // requiredFeatures
2146                 true, // expectActivityLaunch
2147                 createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
2148                 UserHandle.USER_SYSTEM);
2149 
2150         waitForLatch(latch);
2151         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2152         verify(mMockAccountManagerResponse).onError(
2153                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
2154     }
2155 
2156     @SmallTest
testAddAccountAsUserReturnWithValidIntent()2157     public void testAddAccountAsUserReturnWithValidIntent() throws Exception {
2158         unlockSystemUser();
2159         ResolveInfo resolveInfo = new ResolveInfo();
2160         resolveInfo.activityInfo = new ActivityInfo();
2161         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2162         when(mMockPackageManager.resolveActivityAsUser(
2163                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2164         when(mMockPackageManager.checkSignatures(
2165                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
2166 
2167         final CountDownLatch latch = new CountDownLatch(1);
2168         Response response = new Response(latch, mMockAccountManagerResponse);
2169 
2170         mAms.addAccountAsUser(
2171                 response, // response
2172                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2173                 "authTokenType",
2174                 null, // requiredFeatures
2175                 true, // expectActivityLaunch
2176                 createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
2177                 UserHandle.USER_SYSTEM);
2178 
2179         waitForLatch(latch);
2180 
2181         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2182         Bundle result = mBundleCaptor.getValue();
2183         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2184         assertNotNull(intent);
2185         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2186         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2187     }
2188 
2189     @SmallTest
testAddAccountAsUserError()2190     public void testAddAccountAsUserError() throws Exception {
2191         unlockSystemUser();
2192 
2193         final CountDownLatch latch = new CountDownLatch(1);
2194         Response response = new Response(latch, mMockAccountManagerResponse);
2195 
2196         mAms.addAccountAsUser(
2197                 response, // response
2198                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2199                 "authTokenType",
2200                 null, // requiredFeatures
2201                 true, // expectActivityLaunch
2202                 createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_ERROR),
2203                 UserHandle.USER_SYSTEM);
2204 
2205         waitForLatch(latch);
2206         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2207                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2208         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2209     }
2210 
2211     @SmallTest
testConfirmCredentialsAsUserWithNullResponse()2212     public void testConfirmCredentialsAsUserWithNullResponse() throws Exception {
2213         unlockSystemUser();
2214         try {
2215             mAms.confirmCredentialsAsUser(
2216                 null, // response
2217                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2218                 new Bundle(), // options
2219                 false, // expectActivityLaunch
2220                 UserHandle.USER_SYSTEM);
2221             fail("IllegalArgumentException expected. But no exception was thrown.");
2222         } catch (IllegalArgumentException e) {
2223             // IllegalArgumentException is expected.
2224         }
2225     }
2226 
2227     @SmallTest
testConfirmCredentialsAsUserWithNullAccount()2228     public void testConfirmCredentialsAsUserWithNullAccount() throws Exception {
2229         unlockSystemUser();
2230         try {
2231             mAms.confirmCredentialsAsUser(
2232                 mMockAccountManagerResponse, // response
2233                 null, // account
2234                 new Bundle(), // options
2235                 false, // expectActivityLaunch
2236                 UserHandle.USER_SYSTEM);
2237             fail("IllegalArgumentException expected. But no exception was thrown.");
2238         } catch (IllegalArgumentException e) {
2239             // IllegalArgumentException is expected.
2240         }
2241     }
2242 
2243     @SmallTest
testConfirmCredentialsAsUserSuccess()2244     public void testConfirmCredentialsAsUserSuccess() throws Exception {
2245         unlockSystemUser();
2246         final CountDownLatch latch = new CountDownLatch(1);
2247         Response response = new Response(latch, mMockAccountManagerResponse);
2248         mAms.confirmCredentialsAsUser(
2249                 response, // response
2250                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2251                 new Bundle(), // options
2252                 true, // expectActivityLaunch
2253                 UserHandle.USER_SYSTEM);
2254         waitForLatch(latch);
2255 
2256         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2257         Bundle result = mBundleCaptor.getValue();
2258         // Verify response data
2259         assertTrue(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT));
2260         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2261                 result.getString(AccountManager.KEY_ACCOUNT_NAME));
2262         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2263                 result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2264     }
2265 
2266     @SmallTest
testConfirmCredentialsAsUserReturnWithInvalidIntent()2267     public void testConfirmCredentialsAsUserReturnWithInvalidIntent() throws Exception {
2268         unlockSystemUser();
2269         ResolveInfo resolveInfo = new ResolveInfo();
2270         resolveInfo.activityInfo = new ActivityInfo();
2271         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2272         when(mMockPackageManager.resolveActivityAsUser(
2273                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2274         when(mMockPackageManager.checkSignatures(
2275                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2276         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
2277                 .thenReturn(false);
2278 
2279         final CountDownLatch latch = new CountDownLatch(1);
2280         Response response = new Response(latch, mMockAccountManagerResponse);
2281         mAms.confirmCredentialsAsUser(
2282                 response, // response
2283                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2284                 new Bundle(), // options
2285                 true, // expectActivityLaunch
2286                 UserHandle.USER_SYSTEM);
2287         waitForLatch(latch);
2288 
2289         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2290         verify(mMockAccountManagerResponse).onError(
2291                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
2292     }
2293 
2294     @SmallTest
testConfirmCredentialsAsUserReturnWithValidIntent()2295     public void testConfirmCredentialsAsUserReturnWithValidIntent() throws Exception {
2296         unlockSystemUser();
2297         ResolveInfo resolveInfo = new ResolveInfo();
2298         resolveInfo.activityInfo = new ActivityInfo();
2299         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2300         when(mMockPackageManager.resolveActivityAsUser(
2301                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2302         when(mMockPackageManager.checkSignatures(
2303                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
2304 
2305         final CountDownLatch latch = new CountDownLatch(1);
2306         Response response = new Response(latch, mMockAccountManagerResponse);
2307 
2308         mAms.confirmCredentialsAsUser(
2309                 response, // response
2310                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2311                 new Bundle(), // options
2312                 true, // expectActivityLaunch
2313                 UserHandle.USER_SYSTEM);
2314 
2315         waitForLatch(latch);
2316 
2317         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2318         Bundle result = mBundleCaptor.getValue();
2319         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2320         assertNotNull(intent);
2321         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2322         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2323     }
2324 
2325     @SmallTest
testConfirmCredentialsAsUserError()2326     public void testConfirmCredentialsAsUserError() throws Exception {
2327         unlockSystemUser();
2328 
2329         final CountDownLatch latch = new CountDownLatch(1);
2330         Response response = new Response(latch, mMockAccountManagerResponse);
2331 
2332         mAms.confirmCredentialsAsUser(
2333                 response, // response
2334                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
2335                 new Bundle(), // options
2336                 true, // expectActivityLaunch
2337                 UserHandle.USER_SYSTEM);
2338 
2339         waitForLatch(latch);
2340         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2341                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2342         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2343     }
2344 
2345     @SmallTest
testUpdateCredentialsWithNullResponse()2346     public void testUpdateCredentialsWithNullResponse() throws Exception {
2347         unlockSystemUser();
2348         try {
2349             mAms.updateCredentials(
2350                 null, // response
2351                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2352                 "authTokenType",
2353                 false, // expectActivityLaunch
2354                 new Bundle()); // options
2355             fail("IllegalArgumentException expected. But no exception was thrown.");
2356         } catch (IllegalArgumentException e) {
2357             // IllegalArgumentException is expected.
2358         }
2359     }
2360 
2361     @SmallTest
testUpdateCredentialsWithNullAccount()2362     public void testUpdateCredentialsWithNullAccount() throws Exception {
2363         unlockSystemUser();
2364         try {
2365             mAms.updateCredentials(
2366                 mMockAccountManagerResponse, // response
2367                 null, // account
2368                 "authTokenType",
2369                 false, // expectActivityLaunch
2370                 new Bundle()); // options
2371             fail("IllegalArgumentException expected. But no exception was thrown.");
2372         } catch (IllegalArgumentException e) {
2373             // IllegalArgumentException is expected.
2374         }
2375     }
2376 
2377     @SmallTest
testUpdateCredentialsSuccess()2378     public void testUpdateCredentialsSuccess() throws Exception {
2379         unlockSystemUser();
2380         final CountDownLatch latch = new CountDownLatch(1);
2381         Response response = new Response(latch, mMockAccountManagerResponse);
2382 
2383         mAms.updateCredentials(
2384                 response, // response
2385                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2386                 "authTokenType",
2387                 false, // expectActivityLaunch
2388                 new Bundle()); // options
2389 
2390         waitForLatch(latch);
2391 
2392         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2393         Bundle result = mBundleCaptor.getValue();
2394         // Verify response data
2395         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2396                 result.getString(AccountManager.KEY_ACCOUNT_NAME));
2397         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2398                 result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2399     }
2400 
2401     @SmallTest
testUpdateCredentialsReturnWithInvalidIntent()2402     public void testUpdateCredentialsReturnWithInvalidIntent() throws Exception {
2403         unlockSystemUser();
2404         ResolveInfo resolveInfo = new ResolveInfo();
2405         resolveInfo.activityInfo = new ActivityInfo();
2406         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2407         when(mMockPackageManager.resolveActivityAsUser(
2408                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2409         when(mMockPackageManager.checkSignatures(
2410                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2411         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
2412                 .thenReturn(false);
2413 
2414         final CountDownLatch latch = new CountDownLatch(1);
2415         Response response = new Response(latch, mMockAccountManagerResponse);
2416 
2417         mAms.updateCredentials(
2418                 response, // response
2419                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2420                 "authTokenType",
2421                 true, // expectActivityLaunch
2422                 new Bundle()); // options
2423 
2424         waitForLatch(latch);
2425 
2426         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2427         verify(mMockAccountManagerResponse).onError(
2428                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
2429     }
2430 
2431     @SmallTest
testUpdateCredentialsReturnWithValidIntent()2432     public void testUpdateCredentialsReturnWithValidIntent() throws Exception {
2433         unlockSystemUser();
2434         ResolveInfo resolveInfo = new ResolveInfo();
2435         resolveInfo.activityInfo = new ActivityInfo();
2436         resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2437         when(mMockPackageManager.resolveActivityAsUser(
2438                 any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2439         when(mMockPackageManager.checkSignatures(
2440                 anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
2441 
2442         final CountDownLatch latch = new CountDownLatch(1);
2443         Response response = new Response(latch, mMockAccountManagerResponse);
2444 
2445         mAms.updateCredentials(
2446                 response, // response
2447                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2448                 "authTokenType",
2449                 true, // expectActivityLaunch
2450                 new Bundle()); // options
2451 
2452         waitForLatch(latch);
2453 
2454         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2455         Bundle result = mBundleCaptor.getValue();
2456         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2457         assertNotNull(intent);
2458         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2459         assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2460     }
2461 
2462     @SmallTest
testUpdateCredentialsError()2463     public void testUpdateCredentialsError() throws Exception {
2464         unlockSystemUser();
2465 
2466         final CountDownLatch latch = new CountDownLatch(1);
2467         Response response = new Response(latch, mMockAccountManagerResponse);
2468 
2469         mAms.updateCredentials(
2470                 response, // response
2471                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
2472                 "authTokenType",
2473                 false, // expectActivityLaunch
2474                 new Bundle()); // options
2475 
2476         waitForLatch(latch);
2477         verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2478                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2479         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2480     }
2481 
2482     @SmallTest
testEditPropertiesWithNullResponse()2483     public void testEditPropertiesWithNullResponse() throws Exception {
2484         unlockSystemUser();
2485         try {
2486             mAms.editProperties(
2487                 null, // response
2488                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2489                 false); // expectActivityLaunch
2490             fail("IllegalArgumentException expected. But no exception was thrown.");
2491         } catch (IllegalArgumentException e) {
2492             // IllegalArgumentException is expected.
2493         }
2494     }
2495 
2496     @SmallTest
testEditPropertiesWithNullAccountType()2497     public void testEditPropertiesWithNullAccountType() throws Exception {
2498         unlockSystemUser();
2499         try {
2500             mAms.editProperties(
2501                 mMockAccountManagerResponse, // response
2502                 null, // accountType
2503                 false); // expectActivityLaunch
2504             fail("IllegalArgumentException expected. But no exception was thrown.");
2505         } catch (IllegalArgumentException e) {
2506             // IllegalArgumentException is expected.
2507         }
2508     }
2509 
2510     @SmallTest
testEditPropertiesAccountNotManagedByCaller()2511     public void testEditPropertiesAccountNotManagedByCaller() throws Exception {
2512         unlockSystemUser();
2513         when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
2514                     .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2515         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
2516                 .thenReturn(false);
2517         try {
2518             mAms.editProperties(
2519                 mMockAccountManagerResponse, // response
2520                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2521                 false); // expectActivityLaunch
2522             fail("SecurityException expected. But no exception was thrown.");
2523         } catch (SecurityException e) {
2524             // SecurityException is expected.
2525         }
2526     }
2527 
2528     @SmallTest
testEditPropertiesSuccess()2529     public void testEditPropertiesSuccess() throws Exception {
2530         unlockSystemUser();
2531         final CountDownLatch latch = new CountDownLatch(1);
2532         Response response = new Response(latch, mMockAccountManagerResponse);
2533 
2534         mAms.editProperties(
2535                 response, // response
2536                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2537                 false); // expectActivityLaunch
2538 
2539         waitForLatch(latch);
2540 
2541         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2542         Bundle result = mBundleCaptor.getValue();
2543         // Verify response data
2544         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2545                 result.getString(AccountManager.KEY_ACCOUNT_NAME));
2546         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2547                 result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2548     }
2549 
2550     @SmallTest
testGetAccountByTypeAndFeaturesWithNullResponse()2551     public void testGetAccountByTypeAndFeaturesWithNullResponse() throws Exception {
2552         unlockSystemUser();
2553         try {
2554             mAms.getAccountByTypeAndFeatures(
2555                 null, // response
2556                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2557                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2558                 "testpackage"); // opPackageName
2559             fail("IllegalArgumentException expected. But no exception was thrown.");
2560         } catch (IllegalArgumentException e) {
2561             // IllegalArgumentException is expected.
2562         }
2563     }
2564 
2565     @SmallTest
testGetAccountByTypeAndFeaturesWithNullAccountType()2566     public void testGetAccountByTypeAndFeaturesWithNullAccountType() throws Exception {
2567         unlockSystemUser();
2568         try {
2569             mAms.getAccountByTypeAndFeatures(
2570                 mMockAccountManagerResponse, // response
2571                 null, // accountType
2572                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2573                 "testpackage"); // opPackageName
2574             fail("IllegalArgumentException expected. But no exception was thrown.");
2575         } catch (IllegalArgumentException e) {
2576             // IllegalArgumentException is expected.
2577         }
2578     }
2579 
2580     @SmallTest
testGetAccountByTypeAndFeaturesWithNoFeaturesAndNoAccount()2581     public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndNoAccount() throws Exception {
2582         unlockSystemUser();
2583         mAms.getAccountByTypeAndFeatures(
2584             mMockAccountManagerResponse,
2585             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2586             null,
2587             "testpackage");
2588         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2589         Bundle result = mBundleCaptor.getValue();
2590         String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2591         String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2592         assertEquals(null, accountName);
2593         assertEquals(null, accountType);
2594     }
2595 
2596     @SmallTest
testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneVisibleAccount()2597     public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneVisibleAccount()
2598         throws Exception {
2599         unlockSystemUser();
2600         mAms.addAccountExplicitly(
2601                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2602                 /* password= */ "p11",
2603                 /* extras= */ null,
2604                 /* callerPackage= */ null);
2605         mAms.getAccountByTypeAndFeatures(
2606             mMockAccountManagerResponse,
2607             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2608             null,
2609             "testpackage");
2610         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2611         Bundle result = mBundleCaptor.getValue();
2612         String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2613         String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2614         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accountName);
2615         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accountType);
2616     }
2617 
2618     @SmallTest
testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneNotVisibleAccount()2619     public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneNotVisibleAccount()
2620         throws Exception {
2621         unlockSystemUser();
2622         HashMap<String, Integer> visibility = new HashMap<>();
2623         visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
2624             AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
2625         mAms.addAccountExplicitlyWithVisibility(
2626                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2627                 /* password= */ "p11",
2628                 /* extras= */ null,
2629                 visibility,
2630                 /* callerPackage= */ null);
2631         mAms.getAccountByTypeAndFeatures(
2632             mMockAccountManagerResponse,
2633             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2634             null,
2635             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2636         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2637         Intent intent = mIntentCaptor.getValue();
2638         Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2639         assertEquals(1, accounts.length);
2640         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2641     }
2642 
2643     @SmallTest
testGetAccountByTypeAndFeaturesWithNoFeaturesAndTwoAccounts()2644     public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndTwoAccounts() throws Exception {
2645         unlockSystemUser();
2646         mAms.addAccountExplicitly(
2647                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2648                 /* password= */ "p11",
2649                 /* extras= */ null,
2650                 /* callerPackage= */ null);
2651         mAms.addAccountExplicitly(
2652                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2653                 /* password= */ "p12",
2654                 /* extras= */ null,
2655                 /* callerPackage= */ null);
2656 
2657         mAms.getAccountByTypeAndFeatures(
2658             mMockAccountManagerResponse,
2659             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2660             null,
2661             "testpackage");
2662         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2663         Intent intent = mIntentCaptor.getValue();
2664         Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2665         assertEquals(2, accounts.length);
2666         if (accounts[0].equals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS)) {
2667             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2668             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[1]);
2669         } else {
2670             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[0]);
2671             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2672         }
2673     }
2674 
2675     @SmallTest
testGetAccountByTypeAndFeaturesWithFeaturesAndNoAccount()2676     public void testGetAccountByTypeAndFeaturesWithFeaturesAndNoAccount() throws Exception {
2677         unlockSystemUser();
2678         final CountDownLatch latch = new CountDownLatch(1);
2679         mAms.getAccountByTypeAndFeatures(
2680             mMockAccountManagerResponse,
2681             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2682             AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2683             "testpackage");
2684         waitForLatch(latch);
2685         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2686         Bundle result = mBundleCaptor.getValue();
2687         String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2688         String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2689         assertEquals(null, accountName);
2690         assertEquals(null, accountType);
2691     }
2692 
2693     @SmallTest
testGetAccountByTypeAndFeaturesWithFeaturesAndNoQualifiedAccount()2694     public void testGetAccountByTypeAndFeaturesWithFeaturesAndNoQualifiedAccount()
2695         throws Exception {
2696         unlockSystemUser();
2697         mAms.addAccountExplicitly(
2698                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2699                 /* password= */ "p12",
2700                 /* extras= */ null,
2701                 /* callerPackage= */ null);
2702         final CountDownLatch latch = new CountDownLatch(1);
2703         mAms.getAccountByTypeAndFeatures(
2704             mMockAccountManagerResponse,
2705             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2706             AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2707             "testpackage");
2708         waitForLatch(latch);
2709         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2710         Bundle result = mBundleCaptor.getValue();
2711         String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2712         String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2713         assertEquals(null, accountName);
2714         assertEquals(null, accountType);
2715     }
2716 
2717     @SmallTest
testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedAccount()2718     public void testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedAccount()
2719         throws Exception {
2720         unlockSystemUser();
2721         mAms.addAccountExplicitly(
2722                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2723                 /* password= */ "p11",
2724                 /* extras= */ null,
2725                 /* callerPackage= */ null);
2726         mAms.addAccountExplicitly(
2727                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2728                 /* password= */ "p12",
2729                 /* extras= */ null,
2730                 /* callerPackage= */ null);
2731         final CountDownLatch latch = new CountDownLatch(1);
2732         mAms.getAccountByTypeAndFeatures(
2733             mMockAccountManagerResponse,
2734             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2735             AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2736             "testpackage");
2737         waitForLatch(latch);
2738         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2739         Bundle result = mBundleCaptor.getValue();
2740         String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2741         String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2742         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accountName);
2743         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accountType);
2744     }
2745 
2746     @SmallTest
testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedNotVisibleAccount()2747     public void testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedNotVisibleAccount()
2748         throws Exception {
2749         unlockSystemUser();
2750         HashMap<String, Integer> visibility = new HashMap<>();
2751         visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
2752             AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
2753         mAms.addAccountExplicitlyWithVisibility(
2754                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2755                 /* password= */ "p11",
2756                 /* extras= */ null,
2757                 visibility,
2758                 /* callerPackage= */ null);
2759         final CountDownLatch latch = new CountDownLatch(1);
2760         mAms.getAccountByTypeAndFeatures(
2761             mMockAccountManagerResponse,
2762             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2763             AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2764             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2765         waitForLatch(latch);
2766         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2767         Intent intent = mIntentCaptor.getValue();
2768         Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2769         assertEquals(1, accounts.length);
2770         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2771     }
2772 
2773     @SmallTest
testGetAccountByTypeAndFeaturesWithFeaturesAndTwoQualifiedAccount()2774     public void testGetAccountByTypeAndFeaturesWithFeaturesAndTwoQualifiedAccount()
2775         throws Exception {
2776         unlockSystemUser();
2777         mAms.addAccountExplicitly(
2778                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2779                 /* password= */ "p11",
2780                 /* extras= */ null,
2781                 /* callerPackage= */ null);
2782         mAms.addAccountExplicitly(
2783                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2,
2784                 /* password= */ "p12",
2785                 /* extras= */ null,
2786                 /* callerPackage= */ null);
2787         mAms.addAccountExplicitly(
2788                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2789                 /* password= */ "p13",
2790                 /* extras= */ null,
2791                 /* callerPackage= */ null);
2792         final CountDownLatch latch = new CountDownLatch(1);
2793         mAms.getAccountByTypeAndFeatures(
2794             mMockAccountManagerResponse,
2795             AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2796             AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2797             "testpackage");
2798         waitForLatch(latch);
2799         verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2800         Intent intent = mIntentCaptor.getValue();
2801         Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2802         assertEquals(2, accounts.length);
2803         if (accounts[0].equals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS)) {
2804             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2805             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2, accounts[1]);
2806         } else {
2807             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2, accounts[0]);
2808             assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2809         }
2810     }
2811 
2812     @SmallTest
testGetAccountsByFeaturesWithNullResponse()2813     public void testGetAccountsByFeaturesWithNullResponse() throws Exception {
2814         unlockSystemUser();
2815         try {
2816             mAms.getAccountsByFeatures(
2817                 null, // response
2818                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2819                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2820                 "testpackage"); // opPackageName
2821             fail("IllegalArgumentException expected. But no exception was thrown.");
2822         } catch (IllegalArgumentException e) {
2823             // IllegalArgumentException is expected.
2824         }
2825     }
2826 
2827     @SmallTest
testGetAccountsByFeaturesWithNullAccountType()2828     public void testGetAccountsByFeaturesWithNullAccountType() throws Exception {
2829         unlockSystemUser();
2830         try {
2831             mAms.getAccountsByFeatures(
2832                 mMockAccountManagerResponse, // response
2833                 null, // accountType
2834                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2835                 "testpackage"); // opPackageName
2836             fail("IllegalArgumentException expected. But no exception was thrown.");
2837         } catch (IllegalArgumentException e) {
2838             // IllegalArgumentException is expected.
2839         }
2840     }
2841 
2842     @SmallTest
testGetAccountsByFeaturesAccountNotVisible()2843     public void testGetAccountsByFeaturesAccountNotVisible() throws Exception {
2844         unlockSystemUser();
2845 
2846         when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
2847                 PackageManager.PERMISSION_DENIED);
2848         when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
2849                     .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2850         when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
2851                 .thenReturn(false);
2852 
2853         final CountDownLatch latch = new CountDownLatch(1);
2854         Response response = new Response(latch, mMockAccountManagerResponse);
2855         mAms.getAccountsByFeatures(
2856                 response, // response
2857                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2858                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2859                 "testpackage"); // opPackageName
2860         waitForLatch(latch);
2861 
2862         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2863         Bundle result = mBundleCaptor.getValue();
2864         Account[] accounts = (Account[]) result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
2865         assertTrue(accounts.length == 0);
2866     }
2867 
2868     @SmallTest
testGetAccountsByFeaturesNullFeatureReturnsAllAccounts()2869     public void testGetAccountsByFeaturesNullFeatureReturnsAllAccounts() throws Exception {
2870         unlockSystemUser();
2871 
2872         mAms.addAccountExplicitly(
2873                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2874                 /* password= */ "p11",
2875                 /* extras= */ null,
2876                 /* callerPackage= */ null);
2877         mAms.addAccountExplicitly(
2878                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2879                 /* password= */ "p12",
2880                 /* extras= */ null,
2881                 /* callerPackage= */ null);
2882 
2883         final CountDownLatch latch = new CountDownLatch(1);
2884         Response response = new Response(latch, mMockAccountManagerResponse);
2885         mAms.getAccountsByFeatures(
2886                 response, // response
2887                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2888                 null, // features
2889                 "testpackage"); // opPackageName
2890         waitForLatch(latch);
2891 
2892         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2893         Bundle result = mBundleCaptor.getValue();
2894         Account[] accounts = (Account[]) result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
2895         Arrays.sort(accounts, new AccountSorter());
2896         assertEquals(2, accounts.length);
2897         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[0]);
2898         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2899     }
2900 
2901     @SmallTest
testGetAccountsByFeaturesReturnsAccountsWithFeaturesOnly()2902     public void testGetAccountsByFeaturesReturnsAccountsWithFeaturesOnly() throws Exception {
2903         unlockSystemUser();
2904 
2905         mAms.addAccountExplicitly(
2906                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2907                 /* password= */ "p11",
2908                 /* extras= */ null,
2909                 /* callerPackage= */ null);
2910         mAms.addAccountExplicitly(
2911                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2912                 /* password= */ "p12",
2913                 /* extras= */ null,
2914                 /* callerPackage= */ null);
2915 
2916         final CountDownLatch latch = new CountDownLatch(1);
2917         Response response = new Response(latch, mMockAccountManagerResponse);
2918         mAms.getAccountsByFeatures(
2919                 response, // response
2920                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2921                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2922                 "testpackage"); // opPackageName
2923         waitForLatch(latch);
2924 
2925         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2926         Bundle result = mBundleCaptor.getValue();
2927         Account[] accounts = (Account[]) result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
2928         assertEquals(1, accounts.length);
2929         assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2930     }
2931 
2932     @SmallTest
testGetAccountsByFeaturesError()2933     public void testGetAccountsByFeaturesError() throws Exception {
2934         unlockSystemUser();
2935         mAms.addAccountExplicitly(
2936                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2937                 /* password= */ "p11",
2938                 /* extras= */ null,
2939                 /* callerPackage= */ null);
2940         mAms.addAccountExplicitly(
2941                 AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
2942                 /* password= */ "p12",
2943                 /* extras= */ null,
2944                 /* callerPackage= */ null);
2945 
2946         final CountDownLatch latch = new CountDownLatch(1);
2947         Response response = new Response(latch, mMockAccountManagerResponse);
2948         mAms.getAccountsByFeatures(
2949                 response, // response
2950                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2951                 AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2952                 "testpackage"); // opPackageName
2953         waitForLatch(latch);
2954 
2955         verify(mMockAccountManagerResponse).onError(
2956                 eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
2957         verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2958     }
2959 
2960     @SmallTest
testRegisterAccountListener()2961     public void testRegisterAccountListener() throws Exception {
2962         unlockSystemUser();
2963         mAms.registerAccountListener(
2964             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2965             "testpackage"); // opPackageName
2966 
2967         mAms.registerAccountListener(
2968             null, //accountTypes
2969             "testpackage"); // opPackageName
2970 
2971         // Check that two previously registered receivers can be unregistered successfully.
2972         mAms.unregisterAccountListener(
2973             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2974             "testpackage"); // opPackageName
2975 
2976         mAms.unregisterAccountListener(
2977              null, //accountTypes
2978             "testpackage"); // opPackageName
2979     }
2980 
2981     @SmallTest
testRegisterAccountListenerAndAddAccount()2982     public void testRegisterAccountListenerAndAddAccount() throws Exception {
2983         unlockSystemUser();
2984         mAms.registerAccountListener(
2985             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2986             "testpackage"); // opPackageName
2987 
2988         mAms.addAccountExplicitly(
2989                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2990                 /* password= */ "p11",
2991                 /* extras= */ null,
2992                 /* callerPackage= */ null);
2993         // Notification about new account
2994         updateBroadcastCounters(2);
2995         assertEquals(mVisibleAccountsChangedBroadcasts, 1);
2996         assertEquals(mLoginAccountsChangedBroadcasts, 1);
2997     }
2998 
2999     @SmallTest
testRegisterAccountListenerAndAddAccountOfDifferentType()3000     public void testRegisterAccountListenerAndAddAccountOfDifferentType() throws Exception {
3001         unlockSystemUser();
3002         mAms.registerAccountListener(
3003             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2},
3004             "testpackage"); // opPackageName
3005 
3006         mAms.addAccountExplicitly(
3007                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
3008                 /* password= */ "p11",
3009                 /* extras= */ null,
3010                 /* callerPackage= */ null);
3011         mAms.addAccountExplicitly(
3012                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
3013                 /* password= */ "p11",
3014                 /* extras= */ null,
3015                 /* callerPackage= */ null);
3016         // Notification about new account
3017 
3018         updateBroadcastCounters(2);
3019         assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent
3020         assertEquals(mLoginAccountsChangedBroadcasts, 2);
3021     }
3022 
3023     @SmallTest
testRegisterAccountListenerWithAddingTwoAccounts()3024     public void testRegisterAccountListenerWithAddingTwoAccounts() throws Exception {
3025         unlockSystemUser();
3026 
3027         HashMap<String, Integer> visibility = new HashMap<>();
3028         visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
3029             AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
3030 
3031         mAms.registerAccountListener(
3032             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3033             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3034         mAms.addAccountExplicitlyWithVisibility(
3035                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
3036                 /* password= */ "p11",
3037                 /* extras= */ null, visibility,
3038                 /* callerPackage= */ null);
3039         mAms.unregisterAccountListener(
3040             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3041             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3042 
3043         addAccountRemovedReceiver(AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3044         mAms.addAccountExplicitlyWithVisibility(
3045                 AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
3046                 /* password= */ "p11",
3047                 /* extras= */ null,
3048                 visibility,
3049                 /* callerPackage= */ null);
3050 
3051         updateBroadcastCounters(3);
3052         assertEquals(mVisibleAccountsChangedBroadcasts, 1);
3053         assertEquals(mLoginAccountsChangedBroadcasts, 2);
3054         assertEquals(mAccountRemovedBroadcasts, 0);
3055 
3056         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
3057         mAms.registerAccountListener( null /* accountTypes */,
3058             AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3059         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE);
3060 
3061         updateBroadcastCounters(8);
3062         assertEquals(mVisibleAccountsChangedBroadcasts, 2);
3063         assertEquals(mLoginAccountsChangedBroadcasts, 4);
3064         assertEquals(mAccountRemovedBroadcasts, 2);
3065     }
3066 
3067     @SmallTest
testRegisterAccountListenerForThreePackages()3068     public void testRegisterAccountListenerForThreePackages() throws Exception {
3069         unlockSystemUser();
3070 
3071         addAccountRemovedReceiver("testpackage1");
3072         HashMap<String, Integer> visibility = new HashMap<>();
3073         visibility.put("testpackage1", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
3074         visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
3075         visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
3076 
3077         mAms.registerAccountListener(
3078             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3079             "testpackage1"); // opPackageName
3080         mAms.registerAccountListener(
3081             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3082             "testpackage2"); // opPackageName
3083         mAms.registerAccountListener(
3084             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3085             "testpackage3"); // opPackageName
3086         mAms.addAccountExplicitlyWithVisibility(
3087                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
3088                 /* password= */ "p11",
3089                 /* extras= */ null,
3090                 visibility,
3091                 /* callerPackage= */ null);
3092         updateBroadcastCounters(4);
3093         assertEquals(mVisibleAccountsChangedBroadcasts, 3);
3094         assertEquals(mLoginAccountsChangedBroadcasts, 1);
3095 
3096         mAms.unregisterAccountListener(
3097             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3098             "testpackage3"); // opPackageName
3099         // Remove account with 2 active listeners.
3100         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
3101         updateBroadcastCounters(8);
3102         assertEquals(mVisibleAccountsChangedBroadcasts, 5);
3103         assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove
3104         assertEquals(mAccountRemovedBroadcasts, 1);
3105 
3106         // Add account of another type.
3107         mAms.addAccountExplicitly(
3108                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2,
3109                 /* password= */ "p11",
3110                 /* extras= */ null,
3111                 /* callerPackage= */ null);
3112 
3113         updateBroadcastCounters(8);
3114         assertEquals(mVisibleAccountsChangedBroadcasts, 5);
3115         assertEquals(mLoginAccountsChangedBroadcasts, 3);
3116         assertEquals(mAccountRemovedBroadcasts, 1);
3117     }
3118 
3119     @SmallTest
testRegisterAccountListenerForAddingAccountWithVisibility()3120     public void testRegisterAccountListenerForAddingAccountWithVisibility() throws Exception {
3121         unlockSystemUser();
3122 
3123         HashMap<String, Integer> visibility = new HashMap<>();
3124         visibility.put("testpackage1", AccountManager.VISIBILITY_NOT_VISIBLE);
3125         visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
3126         visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
3127 
3128         addAccountRemovedReceiver("testpackage1");
3129         mAms.registerAccountListener(
3130             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3131             "testpackage1"); // opPackageName
3132         mAms.registerAccountListener(
3133             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3134             "testpackage2"); // opPackageName
3135         mAms.registerAccountListener(
3136             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3137             "testpackage3"); // opPackageName
3138         mAms.addAccountExplicitlyWithVisibility(
3139                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
3140                 /* password= */ "p11",
3141                 /* extras= */ null,
3142                 visibility,
3143                 /* callerPackage= */ null);
3144 
3145         updateBroadcastCounters(2);
3146         assertEquals(mVisibleAccountsChangedBroadcasts, 1);
3147         assertEquals(mLoginAccountsChangedBroadcasts, 1);
3148 
3149         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
3150 
3151         updateBroadcastCounters(4);
3152         assertEquals(mVisibleAccountsChangedBroadcasts, 2);
3153         assertEquals(mLoginAccountsChangedBroadcasts, 2);
3154         assertEquals(mAccountRemovedBroadcasts, 0); // account was never visible.
3155     }
3156 
3157     @SmallTest
testRegisterAccountListenerCredentialsUpdate()3158     public void testRegisterAccountListenerCredentialsUpdate() throws Exception {
3159         unlockSystemUser();
3160         mAms.registerAccountListener(
3161             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3162             "testpackage"); // opPackageName
3163         mAms.addAccountExplicitly(
3164                 AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
3165                 /* password= */ "p11",
3166                 /* extras= */ null,
3167                 /* callerPackage= */ null);
3168         mAms.setPassword(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "pwd");
3169         updateBroadcastCounters(4);
3170         assertEquals(mVisibleAccountsChangedBroadcasts, 2);
3171         assertEquals(mLoginAccountsChangedBroadcasts, 2);
3172     }
3173 
3174     @SmallTest
testUnregisterAccountListenerNotRegistered()3175     public void testUnregisterAccountListenerNotRegistered() throws Exception {
3176         unlockSystemUser();
3177         try {
3178             mAms.unregisterAccountListener(
3179                 new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
3180                 "testpackage"); // opPackageName
3181             fail("IllegalArgumentException expected. But no exception was thrown.");
3182         } catch (IllegalArgumentException e) {
3183             // IllegalArgumentException is expected.
3184         }
3185     }
3186 
updateBroadcastCounters(int expectedBroadcasts)3187     private void updateBroadcastCounters (int expectedBroadcasts){
3188         mVisibleAccountsChangedBroadcasts = 0;
3189         mLoginAccountsChangedBroadcasts = 0;
3190         mAccountRemovedBroadcasts = 0;
3191         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
3192         verify(mMockContext, atLeast(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(),
3193                 any(UserHandle.class), any(), any());
3194         for (Intent intent : captor.getAllValues()) {
3195             if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED.equals(intent.getAction())) {
3196                 mVisibleAccountsChangedBroadcasts++;
3197             } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
3198                 mLoginAccountsChangedBroadcasts++;
3199             } else if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) {
3200                 mAccountRemovedBroadcasts++;
3201             }
3202         }
3203     }
3204 
addAccountRemovedReceiver(String packageName)3205     private void addAccountRemovedReceiver(String packageName) {
3206         ResolveInfo resolveInfo = new ResolveInfo();
3207         resolveInfo.activityInfo = new ActivityInfo();
3208         resolveInfo.activityInfo.applicationInfo =  new ApplicationInfo();
3209         resolveInfo.activityInfo.applicationInfo.packageName = packageName;
3210 
3211         List<ResolveInfo> accountRemovedReceivers = new ArrayList<>();
3212         accountRemovedReceivers.add(resolveInfo);
3213         when(mMockPackageManager.queryBroadcastReceiversAsUser(any(Intent.class), anyInt(),
3214             anyInt())).thenReturn(accountRemovedReceivers);
3215     }
3216 
3217     @SmallTest
testConcurrencyReadWrite()3218     public void testConcurrencyReadWrite() throws Exception {
3219         // Test 2 threads calling getAccounts and 1 thread setAuthToken
3220         unlockSystemUser();
3221         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
3222         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
3223 
3224         Account a1 = new Account("account1",
3225                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3226         mAms.addAccountExplicitly(
3227                 a1, /* password= */ "p1", /* extras= */ null, /* callerPackage= */ null);
3228         List<String> errors = Collections.synchronizedList(new ArrayList<>());
3229         int readerCount = 2;
3230         ExecutorService es = Executors.newFixedThreadPool(readerCount + 1);
3231         AtomicLong readTotalTime = new AtomicLong(0);
3232         AtomicLong writeTotalTime = new AtomicLong(0);
3233         final CyclicBarrier cyclicBarrier = new CyclicBarrier(readerCount + 1);
3234 
3235         final int loopSize = 20;
3236         for (int t = 0; t < readerCount; t++) {
3237             es.submit(() -> {
3238                 for (int i = 0; i < loopSize; i++) {
3239                     String logPrefix = Thread.currentThread().getName() + " " + i;
3240                     waitForCyclicBarrier(cyclicBarrier);
3241                     cyclicBarrier.reset();
3242                     SystemClock.sleep(1); // Ensure that writer wins
3243                     Log.d(TAG, logPrefix + " getAccounts started");
3244                     long ti = System.currentTimeMillis();
3245                     try {
3246                         Account[] accounts = mAms.getAccountsAsUser(null,
3247                                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
3248                         if (accounts == null || accounts.length != 1
3249                                 || !AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1.equals(
3250                                 accounts[0].type)) {
3251                             String msg = logPrefix + ": Unexpected accounts: " + Arrays
3252                                     .toString(accounts);
3253                             Log.e(TAG, "    " + msg);
3254                             errors.add(msg);
3255                         }
3256                         Log.d(TAG, logPrefix + " getAccounts done");
3257                     } catch (Exception e) {
3258                         String msg = logPrefix + ": getAccounts failed " + e;
3259                         Log.e(TAG, msg, e);
3260                         errors.add(msg);
3261                     }
3262                     ti = System.currentTimeMillis() - ti;
3263                     readTotalTime.addAndGet(ti);
3264                 }
3265             });
3266         }
3267 
3268         es.submit(() -> {
3269             for (int i = 0; i < loopSize; i++) {
3270                 String logPrefix = Thread.currentThread().getName() + " " + i;
3271                 waitForCyclicBarrier(cyclicBarrier);
3272                 long ti = System.currentTimeMillis();
3273                 Log.d(TAG, logPrefix + " setAuthToken started");
3274                 try {
3275                     mAms.setAuthToken(a1, "t1", "v" + i);
3276                     Log.d(TAG, logPrefix + " setAuthToken done");
3277                 } catch (Exception e) {
3278                     errors.add(logPrefix + ": setAuthToken failed: " + e);
3279                 }
3280                 ti = System.currentTimeMillis() - ti;
3281                 writeTotalTime.addAndGet(ti);
3282             }
3283         });
3284         es.shutdown();
3285         assertTrue("Time-out waiting for jobs to finish",
3286                 es.awaitTermination(10, TimeUnit.SECONDS));
3287         es.shutdownNow();
3288         assertTrue("Errors: " + errors, errors.isEmpty());
3289         Log.i(TAG, "testConcurrencyReadWrite: readTotalTime=" + readTotalTime + " avg="
3290                 + (readTotalTime.doubleValue() / readerCount / loopSize));
3291         Log.i(TAG, "testConcurrencyReadWrite: writeTotalTime=" + writeTotalTime + " avg="
3292                 + (writeTotalTime.doubleValue() / loopSize));
3293     }
3294 
3295     @SmallTest
testConcurrencyRead()3296     public void testConcurrencyRead() throws Exception {
3297         // Test 2 threads calling getAccounts
3298         unlockSystemUser();
3299         String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
3300         when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
3301 
3302         Account a1 = new Account("account1",
3303                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3304         mAms.addAccountExplicitly(
3305                 a1, /* password= */ "p1", /* extras= */ null, /* callerPackage= */ null);
3306         List<String> errors = Collections.synchronizedList(new ArrayList<>());
3307         int readerCount = 2;
3308         ExecutorService es = Executors.newFixedThreadPool(readerCount + 1);
3309         AtomicLong readTotalTime = new AtomicLong(0);
3310 
3311         final int loopSize = 20;
3312         for (int t = 0; t < readerCount; t++) {
3313             es.submit(() -> {
3314                 for (int i = 0; i < loopSize; i++) {
3315                     String logPrefix = Thread.currentThread().getName() + " " + i;
3316                     Log.d(TAG, logPrefix + " getAccounts started");
3317                     long ti = System.currentTimeMillis();
3318                     try {
3319                         Account[] accounts = mAms.getAccountsAsUser(null,
3320                                 UserHandle.getCallingUserId(), mContext.getOpPackageName());
3321                         if (accounts == null || accounts.length != 1
3322                                 || !AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1.equals(
3323                                 accounts[0].type)) {
3324                             String msg = logPrefix + ": Unexpected accounts: " + Arrays
3325                                     .toString(accounts);
3326                             Log.e(TAG, "    " + msg);
3327                             errors.add(msg);
3328                         }
3329                         Log.d(TAG, logPrefix + " getAccounts done");
3330                     } catch (Exception e) {
3331                         String msg = logPrefix + ": getAccounts failed " + e;
3332                         Log.e(TAG, msg, e);
3333                         errors.add(msg);
3334                     }
3335                     ti = System.currentTimeMillis() - ti;
3336                     readTotalTime.addAndGet(ti);
3337                 }
3338             });
3339         }
3340         es.shutdown();
3341         assertTrue("Time-out waiting for jobs to finish",
3342                 es.awaitTermination(10, TimeUnit.SECONDS));
3343         es.shutdownNow();
3344         assertTrue("Errors: " + errors, errors.isEmpty());
3345         Log.i(TAG, "testConcurrencyRead: readTotalTime=" + readTotalTime + " avg="
3346                 + (readTotalTime.doubleValue() / readerCount / loopSize));
3347     }
3348 
waitForCyclicBarrier(CyclicBarrier cyclicBarrier)3349     private void waitForCyclicBarrier(CyclicBarrier cyclicBarrier) {
3350         try {
3351             cyclicBarrier.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3352         } catch (Exception e) {
3353             throw new IllegalStateException("Should not throw " + e, e);
3354         }
3355     }
3356 
waitForLatch(CountDownLatch latch)3357     private void waitForLatch(CountDownLatch latch) {
3358         try {
3359             latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3360         } catch (InterruptedException e) {
3361             throw new IllegalStateException("Should not throw an InterruptedException", e);
3362         }
3363     }
3364 
createAddAccountOptions(String accountName)3365     private Bundle createAddAccountOptions(String accountName) {
3366         Bundle options = new Bundle();
3367         options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3368         return options;
3369     }
3370 
createGetAuthTokenOptions()3371     private Bundle createGetAuthTokenOptions() {
3372         return createGetAuthTokenOptionsWithExpiry(
3373                 System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND);
3374     }
3375 
createGetAuthTokenOptionsWithExpiry(long expiryEpochTimeInMillis)3376     private Bundle createGetAuthTokenOptionsWithExpiry(long expiryEpochTimeInMillis) {
3377         Bundle options = new Bundle();
3378         options.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME,
3379                 AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3380         options.putLong(AccountManagerServiceTestFixtures.KEY_TOKEN_EXPIRY,
3381                 expiryEpochTimeInMillis);
3382         return options;
3383     }
3384 
encryptBundleWithCryptoHelper(Bundle sessionBundle)3385     private Bundle encryptBundleWithCryptoHelper(Bundle sessionBundle) {
3386         Bundle encryptedBundle = null;
3387         try {
3388             CryptoHelper cryptoHelper = CryptoHelper.getInstance();
3389             encryptedBundle = cryptoHelper.encryptBundle(sessionBundle);
3390         } catch (GeneralSecurityException e) {
3391             throw new IllegalStateException("Failed to encrypt session bundle.", e);
3392         }
3393         return encryptedBundle;
3394     }
3395 
createEncryptedSessionBundle(final String accountName)3396     private Bundle createEncryptedSessionBundle(final String accountName) {
3397         Bundle sessionBundle = new Bundle();
3398         sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3399         sessionBundle.putString(
3400                 AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3401                 AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3402         sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3403                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3404         sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3405         return encryptBundleWithCryptoHelper(sessionBundle);
3406     }
3407 
createEncryptedSessionBundleWithError(final String accountName)3408     private Bundle createEncryptedSessionBundleWithError(final String accountName) {
3409         Bundle sessionBundle = new Bundle();
3410         sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3411         sessionBundle.putString(
3412                 AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3413                 AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3414         sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3415                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3416         sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3417         sessionBundle.putInt(
3418                 AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_INVALID_RESPONSE);
3419         sessionBundle.putString(AccountManager.KEY_ERROR_MESSAGE,
3420                 AccountManagerServiceTestFixtures.ERROR_MESSAGE);
3421         return encryptBundleWithCryptoHelper(sessionBundle);
3422     }
3423 
createEncryptedSessionBundleWithNoAccountType(final String accountName)3424     private Bundle createEncryptedSessionBundleWithNoAccountType(final String accountName) {
3425         Bundle sessionBundle = new Bundle();
3426         sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3427         sessionBundle.putString(
3428                 AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3429                 AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3430         sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3431         return encryptBundleWithCryptoHelper(sessionBundle);
3432     }
3433 
createAppBundle()3434     private Bundle createAppBundle() {
3435         Bundle appBundle = new Bundle();
3436         appBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.package");
3437         return appBundle;
3438     }
3439 
createOptionsWithAccountName(final String accountName)3440     private Bundle createOptionsWithAccountName(final String accountName) {
3441         Bundle sessionBundle = new Bundle();
3442         sessionBundle.putString(
3443                 AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3444                 AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3445         sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3446                 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3447         Bundle options = new Bundle();
3448         options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3449         options.putBundle(AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE,
3450                 sessionBundle);
3451         options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD,
3452                 AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD);
3453         return options;
3454     }
3455 
readNumberOfAccountsFromDbFile(Context context, String dbName)3456     private int readNumberOfAccountsFromDbFile(Context context, String dbName) {
3457         SQLiteDatabase ceDb = context.openOrCreateDatabase(dbName, 0, null);
3458         try (Cursor cursor = ceDb.rawQuery("SELECT count(*) FROM accounts", null)) {
3459             assertTrue(cursor.moveToNext());
3460             return cursor.getInt(0);
3461         }
3462     }
3463 
unlockSystemUser()3464     private void unlockSystemUser() {
3465         mAms.onUserUnlocked(newIntentForUser(UserHandle.USER_SYSTEM));
3466     }
3467 
newIntentForUser(int userId)3468     private static Intent newIntentForUser(int userId) {
3469         Intent intent = new Intent();
3470         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3471         return intent;
3472     }
3473 
3474     static class MyMockContext extends MockContext {
3475         private Context mTestContext;
3476         private Context mMockContext;
3477 
MyMockContext(Context testContext, Context mockContext)3478         MyMockContext(Context testContext, Context mockContext) {
3479             this.mTestContext = testContext;
3480             this.mMockContext = mockContext;
3481         }
3482 
3483         @Override
checkCallingOrSelfPermission(final String permission)3484         public int checkCallingOrSelfPermission(final String permission) {
3485             return mMockContext.checkCallingOrSelfPermission(permission);
3486         }
3487 
3488         @Override
bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user)3489         public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
3490                 UserHandle user) {
3491             return mTestContext.bindServiceAsUser(service, conn, flags, user);
3492         }
3493 
3494         @Override
unbindService(ServiceConnection conn)3495         public void unbindService(ServiceConnection conn) {
3496             mTestContext.unbindService(conn);
3497         }
3498 
3499         @Override
getPackageManager()3500         public PackageManager getPackageManager() {
3501             return mMockContext.getPackageManager();
3502         }
3503 
3504         @Override
getPackageName()3505         public String getPackageName() {
3506             return mTestContext.getPackageName();
3507         }
3508 
3509         @Override
getSystemService(String name)3510         public Object getSystemService(String name) {
3511             return mMockContext.getSystemService(name);
3512         }
3513 
3514         @Override
getSystemServiceName(Class<?> serviceClass)3515         public String getSystemServiceName(Class<?> serviceClass) {
3516             return mMockContext.getSystemServiceName(serviceClass);
3517         }
3518 
3519         @Override
startActivityAsUser(Intent intent, UserHandle user)3520         public void startActivityAsUser(Intent intent, UserHandle user) {
3521             mMockContext.startActivityAsUser(intent, user);
3522         }
3523 
3524         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)3525         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
3526             return mMockContext.registerReceiver(receiver, filter,
3527                     Context.RECEIVER_EXPORTED_UNAUDITED);
3528         }
3529 
3530         @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)3531         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
3532                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
3533             return mMockContext.registerReceiverAsUser(
3534                     receiver, user, filter, broadcastPermission, scheduler);
3535         }
3536 
3537         @Override
openOrCreateDatabase(String file, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler)3538         public SQLiteDatabase openOrCreateDatabase(String file, int mode,
3539                 SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
3540             return mTestContext.openOrCreateDatabase(file, mode, factory,errorHandler);
3541         }
3542 
3543         @Override
getDatabasePath(String name)3544         public File getDatabasePath(String name) {
3545             return mTestContext.getDatabasePath(name);
3546         }
3547 
3548         @Override
sendBroadcastAsUser(Intent intent, UserHandle user)3549         public void sendBroadcastAsUser(Intent intent, UserHandle user) {
3550             sendBroadcastAsUser(intent, user, null, null);
3551         }
3552 
3553         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, Bundle options)3554         public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
3555                 Bundle options) {
3556             mMockContext.sendBroadcastAsUser(intent, user, receiverPermission, options);
3557         }
3558 
3559         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)3560         public Intent registerReceiver(BroadcastReceiver receiver,
3561                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
3562             return mMockContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
3563         }
3564 
3565         @Override
getOpPackageName()3566         public String getOpPackageName() {
3567             return mMockContext.getOpPackageName();
3568         }
3569 
3570         @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)3571         public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
3572                 throws PackageManager.NameNotFoundException {
3573             return mMockContext.createPackageContextAsUser(packageName, flags, user);
3574         }
3575     }
3576 
3577     static class TestAccountAuthenticatorCache extends AccountAuthenticatorCache {
TestAccountAuthenticatorCache(Context realContext)3578         public TestAccountAuthenticatorCache(Context realContext) {
3579             super(realContext);
3580         }
3581 
3582         @Override
getUserSystemDirectory(int userId)3583         protected File getUserSystemDirectory(int userId) {
3584             return new File(mContext.getCacheDir(), "authenticator");
3585         }
3586     }
3587 
3588     static class TestInjector extends AccountManagerService.Injector {
3589         private Context mRealContext;
3590         private INotificationManager mMockNotificationManager;
TestInjector(Context realContext, Context mockContext, INotificationManager mockNotificationManager)3591         TestInjector(Context realContext,
3592                 Context mockContext,
3593                 INotificationManager mockNotificationManager) {
3594             super(mockContext);
3595             mRealContext = realContext;
3596             mMockNotificationManager = mockNotificationManager;
3597         }
3598 
3599         @Override
getMessageHandlerLooper()3600         Looper getMessageHandlerLooper() {
3601             return Looper.getMainLooper();
3602         }
3603 
3604         @Override
addLocalService(AccountManagerInternal service)3605         void addLocalService(AccountManagerInternal service) {
3606         }
3607 
3608         @Override
getAccountAuthenticatorCache()3609         IAccountAuthenticatorCache getAccountAuthenticatorCache() {
3610             return new TestAccountAuthenticatorCache(mRealContext);
3611         }
3612 
3613         @Override
getCeDatabaseName(int userId)3614         protected String getCeDatabaseName(int userId) {
3615             return new File(mRealContext.getCacheDir(), CE_DB).getPath();
3616         }
3617 
3618         @Override
getDeDatabaseName(int userId)3619         protected String getDeDatabaseName(int userId) {
3620             return new File(mRealContext.getCacheDir(), DE_DB).getPath();
3621         }
3622 
3623         @Override
getPreNDatabaseName(int userId)3624         String getPreNDatabaseName(int userId) {
3625             return new File(mRealContext.getCacheDir(), PREN_DB).getPath();
3626         }
3627 
3628         @Override
getNotificationManager()3629         INotificationManager getNotificationManager() {
3630             return mMockNotificationManager;
3631         }
3632     }
3633 
3634     class Response extends IAccountManagerResponse.Stub {
3635         private CountDownLatch mLatch;
3636         private IAccountManagerResponse mMockResponse;
Response(CountDownLatch latch, IAccountManagerResponse mockResponse)3637         public Response(CountDownLatch latch, IAccountManagerResponse mockResponse) {
3638             mLatch = latch;
3639             mMockResponse = mockResponse;
3640         }
3641 
3642         @Override
onResult(Bundle bundle)3643         public void onResult(Bundle bundle) {
3644             try {
3645                 mMockResponse.onResult(bundle);
3646             } catch (RemoteException e) {
3647             }
3648             mLatch.countDown();
3649         }
3650 
3651         @Override
onError(int code, String message)3652         public void onError(int code, String message) {
3653             try {
3654                 mMockResponse.onError(code, message);
3655             } catch (RemoteException e) {
3656             }
3657             mLatch.countDown();
3658         }
3659     }
3660 }
3661