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