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