AccountManagerServiceTest.java revision d62dc39dc5a31c2c150fc5083e5a520fcb394c63
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 testGetAccountsByTypeForPackageWhenTypeIsNull() throws Exception {
1488        unlockSystemUser();
1489        HashMap<String, Integer> visibility1 = new HashMap<>();
1490        visibility1.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
1491            AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
1492
1493        HashMap<String, Integer> visibility2 = new HashMap<>();
1494        visibility2.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
1495            AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
1496
1497        mAms.addAccountExplicitlyWithVisibility(
1498            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "P11", null, visibility1);
1499        mAms.addAccountExplicitlyWithVisibility(
1500            AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "P12", null, visibility2);
1501
1502        Account[] accounts = mAms.getAccountsByTypeForPackage(
1503            null, "otherPackageName",
1504            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
1505        // Only get the USER_MANAGED_NOT_VISIBLE account.
1506        assertEquals(1, accounts.length);
1507        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accounts[0].name);
1508        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accounts[0].type);
1509    }
1510
1511    @SmallTest
1512    public void testGetAuthTokenLabelWithNullAccountType() throws Exception {
1513        unlockSystemUser();
1514        try {
1515            mAms.getAuthTokenLabel(
1516                mMockAccountManagerResponse, // response
1517                null, // accountType
1518                "authTokenType");
1519            fail("IllegalArgumentException expected. But no exception was thrown.");
1520        } catch (IllegalArgumentException e) {
1521            // IllegalArgumentException is expected.
1522        }
1523    }
1524
1525    @SmallTest
1526    public void testGetAuthTokenLabelWithNullAuthTokenType() throws Exception {
1527        unlockSystemUser();
1528        try {
1529            mAms.getAuthTokenLabel(
1530                mMockAccountManagerResponse, // response
1531                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1532                null); // authTokenType
1533            fail("IllegalArgumentException expected. But no exception was thrown.");
1534        } catch (IllegalArgumentException e) {
1535            // IllegalArgumentException is expected.
1536        }
1537    }
1538
1539    @SmallTest
1540    public void testGetAuthTokenWithNullResponse() throws Exception {
1541        unlockSystemUser();
1542        try {
1543            mAms.getAuthToken(
1544                    null, // response
1545                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1546                    "authTokenType", // authTokenType
1547                    true, // notifyOnAuthFailure
1548                    true, // expectActivityLaunch
1549                    createGetAuthTokenOptions());
1550            fail("IllegalArgumentException expected. But no exception was thrown.");
1551        } catch (IllegalArgumentException e) {
1552            // IllegalArgumentException is expected.
1553        }
1554    }
1555
1556    @SmallTest
1557    public void testGetAuthTokenWithNullAccount() throws Exception {
1558        unlockSystemUser();
1559        final CountDownLatch latch = new CountDownLatch(1);
1560        Response response = new Response(latch, mMockAccountManagerResponse);
1561        mAms.getAuthToken(
1562                    response, // response
1563                    null, // account
1564                    "authTokenType", // authTokenType
1565                    true, // notifyOnAuthFailure
1566                    true, // expectActivityLaunch
1567                    createGetAuthTokenOptions());
1568        waitForLatch(latch);
1569
1570        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1571        verify(mMockAccountManagerResponse).onError(
1572                eq(AccountManager.ERROR_CODE_BAD_ARGUMENTS), anyString());
1573    }
1574
1575    @SmallTest
1576    public void testGetAuthTokenWithNullAuthTokenType() throws Exception {
1577        unlockSystemUser();
1578        final CountDownLatch latch = new CountDownLatch(1);
1579        Response response = new Response(latch, mMockAccountManagerResponse);
1580        mAms.getAuthToken(
1581                    response, // response
1582                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1583                    null, // authTokenType
1584                    true, // notifyOnAuthFailure
1585                    true, // expectActivityLaunch
1586                    createGetAuthTokenOptions());
1587        waitForLatch(latch);
1588
1589        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1590        verify(mMockAccountManagerResponse).onError(
1591                eq(AccountManager.ERROR_CODE_BAD_ARGUMENTS), anyString());
1592    }
1593
1594    @SmallTest
1595    public void testGetAuthTokenWithInvalidPackage() throws Exception {
1596        unlockSystemUser();
1597        String[] list = new String[]{"test"};
1598        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1599        try {
1600            mAms.getAuthToken(
1601                    mMockAccountManagerResponse, // response
1602                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1603                    "authTokenType", // authTokenType
1604                    true, // notifyOnAuthFailure
1605                    true, // expectActivityLaunch
1606                    createGetAuthTokenOptions());
1607            fail("SecurityException expected. But no exception was thrown.");
1608        } catch (SecurityException e) {
1609            // SecurityException is expected.
1610        }
1611    }
1612
1613    @SmallTest
1614    public void testGetAuthTokenFromInternal() throws Exception {
1615        unlockSystemUser();
1616        when(mMockContext.createPackageContextAsUser(
1617                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1618        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1619        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1620        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1621        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
1622
1623        mAms.setAuthToken(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1624                "authTokenType", AccountManagerServiceTestFixtures.AUTH_TOKEN);
1625        final CountDownLatch latch = new CountDownLatch(1);
1626        Response response = new Response(latch, mMockAccountManagerResponse);
1627        mAms.getAuthToken(
1628                    response, // response
1629                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1630                    "authTokenType", // authTokenType
1631                    true, // notifyOnAuthFailure
1632                    true, // expectActivityLaunch
1633                    createGetAuthTokenOptions());
1634        waitForLatch(latch);
1635
1636        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1637        Bundle result = mBundleCaptor.getValue();
1638        assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN),
1639                AccountManagerServiceTestFixtures.AUTH_TOKEN);
1640        assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME),
1641                AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
1642        assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE),
1643                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
1644    }
1645
1646    @SmallTest
1647    public void testGetAuthTokenSuccess() throws Exception {
1648        unlockSystemUser();
1649        when(mMockContext.createPackageContextAsUser(
1650                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1651        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1652        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1653        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1654
1655        final CountDownLatch latch = new CountDownLatch(1);
1656        Response response = new Response(latch, mMockAccountManagerResponse);
1657        mAms.getAuthToken(
1658                    response, // response
1659                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
1660                    "authTokenType", // authTokenType
1661                    true, // notifyOnAuthFailure
1662                    false, // expectActivityLaunch
1663                    createGetAuthTokenOptions());
1664        waitForLatch(latch);
1665
1666        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1667        Bundle result = mBundleCaptor.getValue();
1668        assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN),
1669                AccountManagerServiceTestFixtures.AUTH_TOKEN);
1670        assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME),
1671                AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS);
1672        assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE),
1673                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
1674    }
1675
1676    @SmallTest
1677    public void testGetAuthTokenReturnWithInvalidIntent() throws Exception {
1678        unlockSystemUser();
1679        when(mMockContext.createPackageContextAsUser(
1680                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1681        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1682        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1683        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1684        ResolveInfo resolveInfo = new ResolveInfo();
1685        resolveInfo.activityInfo = new ActivityInfo();
1686        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1687        when(mMockPackageManager.resolveActivityAsUser(
1688                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1689        when(mMockPackageManager.checkSignatures(
1690                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
1691
1692        final CountDownLatch latch = new CountDownLatch(1);
1693        Response response = new Response(latch, mMockAccountManagerResponse);
1694        mAms.getAuthToken(
1695                    response, // response
1696                    AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1697                    "authTokenType", // authTokenType
1698                    true, // notifyOnAuthFailure
1699                    false, // expectActivityLaunch
1700                    createGetAuthTokenOptions());
1701        waitForLatch(latch);
1702        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1703        verify(mMockAccountManagerResponse).onError(
1704                eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
1705    }
1706
1707    @SmallTest
1708    public void testGetAuthTokenReturnWithValidIntent() throws Exception {
1709        unlockSystemUser();
1710        when(mMockContext.createPackageContextAsUser(
1711                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1712        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1713        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1714        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1715
1716        ResolveInfo resolveInfo = new ResolveInfo();
1717        resolveInfo.activityInfo = new ActivityInfo();
1718        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1719        when(mMockPackageManager.resolveActivityAsUser(
1720                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1721        when(mMockPackageManager.checkSignatures(
1722                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
1723
1724        final CountDownLatch latch = new CountDownLatch(1);
1725        Response response = new Response(latch, mMockAccountManagerResponse);
1726        mAms.getAuthToken(
1727                    response, // response
1728                    AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
1729                    "authTokenType", // authTokenType
1730                    false, // notifyOnAuthFailure
1731                    true, // expectActivityLaunch
1732                    createGetAuthTokenOptions());
1733        waitForLatch(latch);
1734        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1735        Bundle result = mBundleCaptor.getValue();
1736        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
1737        assertNotNull(intent);
1738        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
1739        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
1740    }
1741
1742    @SmallTest
1743    public void testGetAuthTokenError() throws Exception {
1744        unlockSystemUser();
1745        when(mMockContext.createPackageContextAsUser(
1746                 anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext);
1747        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
1748        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
1749        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
1750        final CountDownLatch latch = new CountDownLatch(1);
1751        Response response = new Response(latch, mMockAccountManagerResponse);
1752        mAms.getAuthToken(
1753                    response, // response
1754                    AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
1755                    "authTokenType", // authTokenType
1756                    true, // notifyOnAuthFailure
1757                    false, // expectActivityLaunch
1758                    createGetAuthTokenOptions());
1759        waitForLatch(latch);
1760        verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
1761                AccountManagerServiceTestFixtures.ERROR_MESSAGE);
1762        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1763
1764    }
1765
1766    @SmallTest
1767    public void testAddAccountAsUserWithNullResponse() throws Exception {
1768        unlockSystemUser();
1769        try {
1770            mAms.addAccountAsUser(
1771                null, // response
1772                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
1773                "authTokenType",
1774                null, // requiredFeatures
1775                true, // expectActivityLaunch
1776                null, // optionsIn
1777                UserHandle.USER_SYSTEM);
1778            fail("IllegalArgumentException expected. But no exception was thrown.");
1779        } catch (IllegalArgumentException e) {
1780            // IllegalArgumentException is expected.
1781        }
1782    }
1783
1784    @SmallTest
1785    public void testAddAccountAsUserWithNullAccountType() throws Exception {
1786        unlockSystemUser();
1787        try {
1788            mAms.addAccountAsUser(
1789                mMockAccountManagerResponse, // response
1790                null, // accountType
1791                "authTokenType",
1792                null, // requiredFeatures
1793                true, // expectActivityLaunch
1794                null, // optionsIn
1795                UserHandle.USER_SYSTEM);
1796            fail("IllegalArgumentException expected. But no exception was thrown.");
1797        } catch (IllegalArgumentException e) {
1798            // IllegalArgumentException is expected.
1799        }
1800    }
1801
1802    @SmallTest
1803    public void testAddAccountAsUserUserCannotModifyAccountNoDPM() throws Exception {
1804        unlockSystemUser();
1805        Bundle bundle = new Bundle();
1806        bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1807        when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1808        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1809
1810        mAms.addAccountAsUser(
1811                mMockAccountManagerResponse, // response
1812                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1813                "authTokenType",
1814                null, // requiredFeatures
1815                true, // expectActivityLaunch
1816                null, // optionsIn
1817                UserHandle.USER_SYSTEM);
1818        verify(mMockAccountManagerResponse).onError(
1819                eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1820        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
1821
1822        // verify the intent for default CantAddAccountActivity is sent.
1823        Intent intent = mIntentCaptor.getValue();
1824        assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
1825        assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
1826                AccountManager.ERROR_CODE_USER_RESTRICTED);
1827    }
1828
1829    @SmallTest
1830    public void testAddAccountAsUserUserCannotModifyAccountWithDPM() throws Exception {
1831        unlockSystemUser();
1832        Bundle bundle = new Bundle();
1833        bundle.putBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
1834        when(mMockUserManager.getUserRestrictions(any(UserHandle.class))).thenReturn(bundle);
1835        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1836        LocalServices.addService(
1837                DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
1838        when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
1839                anyInt(), anyString())).thenReturn(new Intent());
1840        when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
1841                anyInt(), anyBoolean())).thenReturn(new Intent());
1842
1843        mAms.addAccountAsUser(
1844                mMockAccountManagerResponse, // response
1845                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1846                "authTokenType",
1847                null, // requiredFeatures
1848                true, // expectActivityLaunch
1849                null, // optionsIn
1850                UserHandle.USER_SYSTEM);
1851
1852        verify(mMockAccountManagerResponse).onError(
1853                eq(AccountManager.ERROR_CODE_USER_RESTRICTED), anyString());
1854        verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
1855        verify(mMockDevicePolicyManagerInternal).createUserRestrictionSupportIntent(
1856                anyInt(), anyString());
1857    }
1858
1859    @SmallTest
1860    public void testAddAccountAsUserUserCannotModifyAccountForTypeNoDPM() throws Exception {
1861        unlockSystemUser();
1862        when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
1863                .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
1864        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1865
1866        mAms.addAccountAsUser(
1867                mMockAccountManagerResponse, // response
1868                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1869                "authTokenType",
1870                null, // requiredFeatures
1871                true, // expectActivityLaunch
1872                null, // optionsIn
1873                UserHandle.USER_SYSTEM);
1874
1875        verify(mMockAccountManagerResponse).onError(
1876                eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
1877        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
1878
1879        // verify the intent for default CantAddAccountActivity is sent.
1880        Intent intent = mIntentCaptor.getValue();
1881        assertEquals(intent.getComponent().getClassName(), CantAddAccountActivity.class.getName());
1882        assertEquals(intent.getIntExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, 0),
1883                AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE);
1884    }
1885
1886    @SmallTest
1887    public void testAddAccountAsUserUserCannotModifyAccountForTypeWithDPM() throws Exception {
1888        unlockSystemUser();
1889        when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
1890                mMockDevicePolicyManager);
1891        when(mMockDevicePolicyManager.getAccountTypesWithManagementDisabledAsUser(anyInt()))
1892                .thenReturn(new String[]{AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, "BBB"});
1893
1894        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
1895        LocalServices.addService(
1896                DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
1897        when(mMockDevicePolicyManagerInternal.createUserRestrictionSupportIntent(
1898                anyInt(), anyString())).thenReturn(new Intent());
1899        when(mMockDevicePolicyManagerInternal.createShowAdminSupportIntent(
1900                anyInt(), anyBoolean())).thenReturn(new Intent());
1901
1902        mAms.addAccountAsUser(
1903                mMockAccountManagerResponse, // response
1904                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1905                "authTokenType",
1906                null, // requiredFeatures
1907                true, // expectActivityLaunch
1908                null, // optionsIn
1909                UserHandle.USER_SYSTEM);
1910
1911        verify(mMockAccountManagerResponse).onError(
1912                eq(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE), anyString());
1913        verify(mMockContext).startActivityAsUser(any(Intent.class), eq(UserHandle.SYSTEM));
1914        verify(mMockDevicePolicyManagerInternal).createShowAdminSupportIntent(
1915                anyInt(), anyBoolean());
1916    }
1917
1918    @SmallTest
1919    public void testAddAccountAsUserSuccess() throws Exception {
1920        unlockSystemUser();
1921        final CountDownLatch latch = new CountDownLatch(1);
1922        Response response = new Response(latch, mMockAccountManagerResponse);
1923        mAms.addAccountAsUser(
1924                response, // response
1925                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1926                "authTokenType",
1927                null, // requiredFeatures
1928                true, // expectActivityLaunch
1929                createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS),
1930                UserHandle.USER_SYSTEM);
1931        waitForLatch(latch);
1932        // Verify notification is cancelled
1933        verify(mMockNotificationManager).cancelNotificationWithTag(
1934                anyString(), nullable(String.class), anyInt(), anyInt());
1935
1936        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
1937        Bundle result = mBundleCaptor.getValue();
1938        // Verify response data
1939        assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
1940        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
1941                result.getString(AccountManager.KEY_ACCOUNT_NAME));
1942        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
1943                result.getString(AccountManager.KEY_ACCOUNT_TYPE));
1944
1945        Bundle optionBundle = result.getParcelable(
1946                AccountManagerServiceTestFixtures.KEY_OPTIONS_BUNDLE);
1947        // Assert addAccountAsUser added calling uid and pid into the option bundle
1948        assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_UID));
1949        assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_PID));
1950    }
1951
1952    @SmallTest
1953    public void testAddAccountAsUserReturnWithInvalidIntent() throws Exception {
1954        unlockSystemUser();
1955        ResolveInfo resolveInfo = new ResolveInfo();
1956        resolveInfo.activityInfo = new ActivityInfo();
1957        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1958        when(mMockPackageManager.resolveActivityAsUser(
1959                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1960        when(mMockPackageManager.checkSignatures(
1961                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
1962
1963        final CountDownLatch latch = new CountDownLatch(1);
1964        Response response = new Response(latch, mMockAccountManagerResponse);
1965        mAms.addAccountAsUser(
1966                response, // response
1967                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1968                "authTokenType",
1969                null, // requiredFeatures
1970                true, // expectActivityLaunch
1971                createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
1972                UserHandle.USER_SYSTEM);
1973
1974        waitForLatch(latch);
1975        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
1976        verify(mMockAccountManagerResponse).onError(
1977                eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
1978    }
1979
1980    @SmallTest
1981    public void testAddAccountAsUserReturnWithValidIntent() throws Exception {
1982        unlockSystemUser();
1983        ResolveInfo resolveInfo = new ResolveInfo();
1984        resolveInfo.activityInfo = new ActivityInfo();
1985        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
1986        when(mMockPackageManager.resolveActivityAsUser(
1987                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
1988        when(mMockPackageManager.checkSignatures(
1989                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
1990
1991        final CountDownLatch latch = new CountDownLatch(1);
1992        Response response = new Response(latch, mMockAccountManagerResponse);
1993
1994        mAms.addAccountAsUser(
1995                response, // response
1996                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
1997                "authTokenType",
1998                null, // requiredFeatures
1999                true, // expectActivityLaunch
2000                createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE),
2001                UserHandle.USER_SYSTEM);
2002
2003        waitForLatch(latch);
2004
2005        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2006        Bundle result = mBundleCaptor.getValue();
2007        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2008        assertNotNull(intent);
2009        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2010        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2011    }
2012
2013    @SmallTest
2014    public void testAddAccountAsUserError() throws Exception {
2015        unlockSystemUser();
2016
2017        final CountDownLatch latch = new CountDownLatch(1);
2018        Response response = new Response(latch, mMockAccountManagerResponse);
2019
2020        mAms.addAccountAsUser(
2021                response, // response
2022                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2023                "authTokenType",
2024                null, // requiredFeatures
2025                true, // expectActivityLaunch
2026                createAddAccountOptions(AccountManagerServiceTestFixtures.ACCOUNT_NAME_ERROR),
2027                UserHandle.USER_SYSTEM);
2028
2029        waitForLatch(latch);
2030        verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2031                AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2032        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2033    }
2034
2035    @SmallTest
2036    public void testConfirmCredentialsAsUserWithNullResponse() throws Exception {
2037        unlockSystemUser();
2038        try {
2039            mAms.confirmCredentialsAsUser(
2040                null, // response
2041                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2042                new Bundle(), // options
2043                false, // expectActivityLaunch
2044                UserHandle.USER_SYSTEM);
2045            fail("IllegalArgumentException expected. But no exception was thrown.");
2046        } catch (IllegalArgumentException e) {
2047            // IllegalArgumentException is expected.
2048        }
2049    }
2050
2051    @SmallTest
2052    public void testConfirmCredentialsAsUserWithNullAccount() throws Exception {
2053        unlockSystemUser();
2054        try {
2055            mAms.confirmCredentialsAsUser(
2056                mMockAccountManagerResponse, // response
2057                null, // account
2058                new Bundle(), // options
2059                false, // expectActivityLaunch
2060                UserHandle.USER_SYSTEM);
2061            fail("IllegalArgumentException expected. But no exception was thrown.");
2062        } catch (IllegalArgumentException e) {
2063            // IllegalArgumentException is expected.
2064        }
2065    }
2066
2067    @SmallTest
2068    public void testConfirmCredentialsAsUserSuccess() throws Exception {
2069        unlockSystemUser();
2070        final CountDownLatch latch = new CountDownLatch(1);
2071        Response response = new Response(latch, mMockAccountManagerResponse);
2072        mAms.confirmCredentialsAsUser(
2073                response, // response
2074                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2075                new Bundle(), // options
2076                true, // expectActivityLaunch
2077                UserHandle.USER_SYSTEM);
2078        waitForLatch(latch);
2079
2080        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2081        Bundle result = mBundleCaptor.getValue();
2082        // Verify response data
2083        assertTrue(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT));
2084        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2085                result.getString(AccountManager.KEY_ACCOUNT_NAME));
2086        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2087                result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2088    }
2089
2090    @SmallTest
2091    public void testConfirmCredentialsAsUserReturnWithInvalidIntent() throws Exception {
2092        unlockSystemUser();
2093        ResolveInfo resolveInfo = new ResolveInfo();
2094        resolveInfo.activityInfo = new ActivityInfo();
2095        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2096        when(mMockPackageManager.resolveActivityAsUser(
2097                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2098        when(mMockPackageManager.checkSignatures(
2099                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2100
2101        final CountDownLatch latch = new CountDownLatch(1);
2102        Response response = new Response(latch, mMockAccountManagerResponse);
2103        mAms.confirmCredentialsAsUser(
2104                response, // response
2105                AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2106                new Bundle(), // options
2107                true, // expectActivityLaunch
2108                UserHandle.USER_SYSTEM);
2109        waitForLatch(latch);
2110
2111        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2112        verify(mMockAccountManagerResponse).onError(
2113                eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
2114    }
2115
2116    @SmallTest
2117    public void testConfirmCredentialsAsUserReturnWithValidIntent() throws Exception {
2118        unlockSystemUser();
2119        ResolveInfo resolveInfo = new ResolveInfo();
2120        resolveInfo.activityInfo = new ActivityInfo();
2121        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2122        when(mMockPackageManager.resolveActivityAsUser(
2123                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2124        when(mMockPackageManager.checkSignatures(
2125                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
2126
2127        final CountDownLatch latch = new CountDownLatch(1);
2128        Response response = new Response(latch, mMockAccountManagerResponse);
2129
2130        mAms.confirmCredentialsAsUser(
2131                response, // response
2132                AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2133                new Bundle(), // options
2134                true, // expectActivityLaunch
2135                UserHandle.USER_SYSTEM);
2136
2137        waitForLatch(latch);
2138
2139        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2140        Bundle result = mBundleCaptor.getValue();
2141        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2142        assertNotNull(intent);
2143        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2144        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2145    }
2146
2147    @SmallTest
2148    public void testConfirmCredentialsAsUserError() throws Exception {
2149        unlockSystemUser();
2150
2151        final CountDownLatch latch = new CountDownLatch(1);
2152        Response response = new Response(latch, mMockAccountManagerResponse);
2153
2154        mAms.confirmCredentialsAsUser(
2155                response, // response
2156                AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
2157                new Bundle(), // options
2158                true, // expectActivityLaunch
2159                UserHandle.USER_SYSTEM);
2160
2161        waitForLatch(latch);
2162        verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2163                AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2164        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2165    }
2166
2167    @SmallTest
2168    public void testUpdateCredentialsWithNullResponse() throws Exception {
2169        unlockSystemUser();
2170        try {
2171            mAms.updateCredentials(
2172                null, // response
2173                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2174                "authTokenType",
2175                false, // expectActivityLaunch
2176                new Bundle()); // options
2177            fail("IllegalArgumentException expected. But no exception was thrown.");
2178        } catch (IllegalArgumentException e) {
2179            // IllegalArgumentException is expected.
2180        }
2181    }
2182
2183    @SmallTest
2184    public void testUpdateCredentialsWithNullAccount() throws Exception {
2185        unlockSystemUser();
2186        try {
2187            mAms.updateCredentials(
2188                mMockAccountManagerResponse, // response
2189                null, // account
2190                "authTokenType",
2191                false, // expectActivityLaunch
2192                new Bundle()); // options
2193            fail("IllegalArgumentException expected. But no exception was thrown.");
2194        } catch (IllegalArgumentException e) {
2195            // IllegalArgumentException is expected.
2196        }
2197    }
2198
2199    @SmallTest
2200    public void testUpdateCredentialsSuccess() throws Exception {
2201        unlockSystemUser();
2202        final CountDownLatch latch = new CountDownLatch(1);
2203        Response response = new Response(latch, mMockAccountManagerResponse);
2204
2205        mAms.updateCredentials(
2206                response, // response
2207                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
2208                "authTokenType",
2209                false, // expectActivityLaunch
2210                new Bundle()); // options
2211
2212        waitForLatch(latch);
2213
2214        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2215        Bundle result = mBundleCaptor.getValue();
2216        // Verify response data
2217        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2218                result.getString(AccountManager.KEY_ACCOUNT_NAME));
2219        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2220                result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2221    }
2222
2223    @SmallTest
2224    public void testUpdateCredentialsReturnWithInvalidIntent() throws Exception {
2225        unlockSystemUser();
2226        ResolveInfo resolveInfo = new ResolveInfo();
2227        resolveInfo.activityInfo = new ActivityInfo();
2228        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2229        when(mMockPackageManager.resolveActivityAsUser(
2230                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2231        when(mMockPackageManager.checkSignatures(
2232                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2233
2234        final CountDownLatch latch = new CountDownLatch(1);
2235        Response response = new Response(latch, mMockAccountManagerResponse);
2236
2237        mAms.updateCredentials(
2238                response, // response
2239                AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2240                "authTokenType",
2241                true, // expectActivityLaunch
2242                new Bundle()); // options
2243
2244        waitForLatch(latch);
2245
2246        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2247        verify(mMockAccountManagerResponse).onError(
2248                eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
2249    }
2250
2251    @SmallTest
2252    public void testUpdateCredentialsReturnWithValidIntent() throws Exception {
2253        unlockSystemUser();
2254        ResolveInfo resolveInfo = new ResolveInfo();
2255        resolveInfo.activityInfo = new ActivityInfo();
2256        resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
2257        when(mMockPackageManager.resolveActivityAsUser(
2258                any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
2259        when(mMockPackageManager.checkSignatures(
2260                anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
2261
2262        final CountDownLatch latch = new CountDownLatch(1);
2263        Response response = new Response(latch, mMockAccountManagerResponse);
2264
2265        mAms.updateCredentials(
2266                response, // response
2267                AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE,
2268                "authTokenType",
2269                true, // expectActivityLaunch
2270                new Bundle()); // options
2271
2272        waitForLatch(latch);
2273
2274        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2275        Bundle result = mBundleCaptor.getValue();
2276        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
2277        assertNotNull(intent);
2278        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_RESULT));
2279        assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
2280    }
2281
2282    @SmallTest
2283    public void testUpdateCredentialsError() throws Exception {
2284        unlockSystemUser();
2285
2286        final CountDownLatch latch = new CountDownLatch(1);
2287        Response response = new Response(latch, mMockAccountManagerResponse);
2288
2289        mAms.updateCredentials(
2290                response, // response
2291                AccountManagerServiceTestFixtures.ACCOUNT_ERROR,
2292                "authTokenType",
2293                false, // expectActivityLaunch
2294                new Bundle()); // options
2295
2296        waitForLatch(latch);
2297        verify(mMockAccountManagerResponse).onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
2298                AccountManagerServiceTestFixtures.ERROR_MESSAGE);
2299        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2300    }
2301
2302    @SmallTest
2303    public void testEditPropertiesWithNullResponse() throws Exception {
2304        unlockSystemUser();
2305        try {
2306            mAms.editProperties(
2307                null, // response
2308                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2309                false); // expectActivityLaunch
2310            fail("IllegalArgumentException expected. But no exception was thrown.");
2311        } catch (IllegalArgumentException e) {
2312            // IllegalArgumentException is expected.
2313        }
2314    }
2315
2316    @SmallTest
2317    public void testEditPropertiesWithNullAccountType() throws Exception {
2318        unlockSystemUser();
2319        try {
2320            mAms.editProperties(
2321                mMockAccountManagerResponse, // response
2322                null, // accountType
2323                false); // expectActivityLaunch
2324            fail("IllegalArgumentException expected. But no exception was thrown.");
2325        } catch (IllegalArgumentException e) {
2326            // IllegalArgumentException is expected.
2327        }
2328    }
2329
2330    @SmallTest
2331    public void testEditPropertiesAccountNotManagedByCaller() throws Exception {
2332        unlockSystemUser();
2333        when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
2334                    .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2335        try {
2336            mAms.editProperties(
2337                mMockAccountManagerResponse, // response
2338                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2339                false); // expectActivityLaunch
2340            fail("SecurityException expected. But no exception was thrown.");
2341        } catch (SecurityException e) {
2342            // SecurityException is expected.
2343        }
2344    }
2345
2346    @SmallTest
2347    public void testEditPropertiesSuccess() throws Exception {
2348        unlockSystemUser();
2349        final CountDownLatch latch = new CountDownLatch(1);
2350        Response response = new Response(latch, mMockAccountManagerResponse);
2351
2352        mAms.editProperties(
2353                response, // response
2354                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2355                false); // expectActivityLaunch
2356
2357        waitForLatch(latch);
2358
2359        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2360        Bundle result = mBundleCaptor.getValue();
2361        // Verify response data
2362        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS,
2363                result.getString(AccountManager.KEY_ACCOUNT_NAME));
2364        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2365                result.getString(AccountManager.KEY_ACCOUNT_TYPE));
2366    }
2367
2368    @SmallTest
2369    public void testGetAccountByTypeAndFeaturesWithNullResponse() throws Exception {
2370        unlockSystemUser();
2371        try {
2372            mAms.getAccountByTypeAndFeatures(
2373                null, // response
2374                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2375                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2376                "testpackage"); // opPackageName
2377            fail("IllegalArgumentException expected. But no exception was thrown.");
2378        } catch (IllegalArgumentException e) {
2379            // IllegalArgumentException is expected.
2380        }
2381    }
2382
2383    @SmallTest
2384    public void testGetAccountByTypeAndFeaturesWithNullAccountType() throws Exception {
2385        unlockSystemUser();
2386        try {
2387            mAms.getAccountByTypeAndFeatures(
2388                mMockAccountManagerResponse, // response
2389                null, // accountType
2390                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2391                "testpackage"); // opPackageName
2392            fail("IllegalArgumentException expected. But no exception was thrown.");
2393        } catch (IllegalArgumentException e) {
2394            // IllegalArgumentException is expected.
2395        }
2396    }
2397
2398    @SmallTest
2399    public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndNoAccount() throws Exception {
2400        unlockSystemUser();
2401        mAms.getAccountByTypeAndFeatures(
2402            mMockAccountManagerResponse,
2403            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2404            null,
2405            "testpackage");
2406        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2407        Bundle result = mBundleCaptor.getValue();
2408        String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2409        String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2410        assertEquals(null, accountName);
2411        assertEquals(null, accountType);
2412    }
2413
2414    @SmallTest
2415    public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneVisibleAccount()
2416        throws Exception {
2417        unlockSystemUser();
2418        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2419        mAms.getAccountByTypeAndFeatures(
2420            mMockAccountManagerResponse,
2421            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2422            null,
2423            "testpackage");
2424        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2425        Bundle result = mBundleCaptor.getValue();
2426        String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2427        String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2428        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accountName);
2429        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accountType);
2430    }
2431
2432    @SmallTest
2433    public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndOneNotVisibleAccount()
2434        throws Exception {
2435        unlockSystemUser();
2436        HashMap<String, Integer> visibility = new HashMap<>();
2437        visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
2438            AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
2439        mAms.addAccountExplicitlyWithVisibility(
2440            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
2441        mAms.getAccountByTypeAndFeatures(
2442            mMockAccountManagerResponse,
2443            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2444            null,
2445            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2446        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2447        Intent intent = mIntentCaptor.getValue();
2448        Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2449        assertEquals(1, accounts.length);
2450        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2451    }
2452
2453    @SmallTest
2454    public void testGetAccountByTypeAndFeaturesWithNoFeaturesAndTwoAccounts() throws Exception {
2455        unlockSystemUser();
2456        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2457        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p12", null);
2458
2459        mAms.getAccountByTypeAndFeatures(
2460            mMockAccountManagerResponse,
2461            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2462            null,
2463            "testpackage");
2464        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2465        Intent intent = mIntentCaptor.getValue();
2466        Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2467        assertEquals(2, accounts.length);
2468        if (accounts[0].equals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS)) {
2469            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2470            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[1]);
2471        } else {
2472            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[0]);
2473            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2474        }
2475    }
2476
2477    @SmallTest
2478    public void testGetAccountByTypeAndFeaturesWithFeaturesAndNoAccount() throws Exception {
2479        unlockSystemUser();
2480        final CountDownLatch latch = new CountDownLatch(1);
2481        mAms.getAccountByTypeAndFeatures(
2482            mMockAccountManagerResponse,
2483            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2484            AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2485            "testpackage");
2486        waitForLatch(latch);
2487        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2488        Bundle result = mBundleCaptor.getValue();
2489        String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2490        String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2491        assertEquals(null, accountName);
2492        assertEquals(null, accountType);
2493    }
2494
2495    @SmallTest
2496    public void testGetAccountByTypeAndFeaturesWithFeaturesAndNoQualifiedAccount()
2497        throws Exception {
2498        unlockSystemUser();
2499        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p12", null);
2500        final CountDownLatch latch = new CountDownLatch(1);
2501        mAms.getAccountByTypeAndFeatures(
2502            mMockAccountManagerResponse,
2503            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2504            AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2505            "testpackage");
2506        waitForLatch(latch);
2507        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2508        Bundle result = mBundleCaptor.getValue();
2509        String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2510        String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2511        assertEquals(null, accountName);
2512        assertEquals(null, accountType);
2513    }
2514
2515    @SmallTest
2516    public void testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedAccount()
2517        throws Exception {
2518        unlockSystemUser();
2519        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2520        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p12", null);
2521        final CountDownLatch latch = new CountDownLatch(1);
2522        mAms.getAccountByTypeAndFeatures(
2523            mMockAccountManagerResponse,
2524            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2525            AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2526            "testpackage");
2527        waitForLatch(latch);
2528        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2529        Bundle result = mBundleCaptor.getValue();
2530        String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
2531        String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
2532        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS, accountName);
2533        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, accountType);
2534    }
2535
2536    @SmallTest
2537    public void testGetAccountByTypeAndFeaturesWithFeaturesAndOneQualifiedNotVisibleAccount()
2538        throws Exception {
2539        unlockSystemUser();
2540        HashMap<String, Integer> visibility = new HashMap<>();
2541        visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
2542            AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
2543        mAms.addAccountExplicitlyWithVisibility(
2544            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
2545        final CountDownLatch latch = new CountDownLatch(1);
2546        mAms.getAccountByTypeAndFeatures(
2547            mMockAccountManagerResponse,
2548            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2549            AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2550            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2551        waitForLatch(latch);
2552        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2553        Intent intent = mIntentCaptor.getValue();
2554        Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2555        assertEquals(1, accounts.length);
2556        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2557    }
2558
2559    @SmallTest
2560    public void testGetAccountByTypeAndFeaturesWithFeaturesAndTwoQualifiedAccount()
2561        throws Exception {
2562        unlockSystemUser();
2563        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2564        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2, "p12", null);
2565        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p13", null);
2566        final CountDownLatch latch = new CountDownLatch(1);
2567        mAms.getAccountByTypeAndFeatures(
2568            mMockAccountManagerResponse,
2569            AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2570            AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2571            "testpackage");
2572        waitForLatch(latch);
2573        verify(mMockContext).startActivityAsUser(mIntentCaptor.capture(), eq(UserHandle.SYSTEM));
2574        Intent intent = mIntentCaptor.getValue();
2575        Account[] accounts = (Account[]) intent.getExtra(AccountManager.KEY_ACCOUNTS);
2576        assertEquals(2, accounts.length);
2577        if (accounts[0].equals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS)) {
2578            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2579            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2, accounts[1]);
2580        } else {
2581            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_2, accounts[0]);
2582            assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2583        }
2584    }
2585
2586    @SmallTest
2587    public void testGetAccountsByFeaturesWithNullResponse() throws Exception {
2588        unlockSystemUser();
2589        try {
2590            mAms.getAccountsByFeatures(
2591                null, // response
2592                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
2593                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2594                "testpackage"); // opPackageName
2595            fail("IllegalArgumentException expected. But no exception was thrown.");
2596        } catch (IllegalArgumentException e) {
2597            // IllegalArgumentException is expected.
2598        }
2599    }
2600
2601    @SmallTest
2602    public void testGetAccountsByFeaturesWithNullAccountType() throws Exception {
2603        unlockSystemUser();
2604        try {
2605            mAms.getAccountsByFeatures(
2606                mMockAccountManagerResponse, // response
2607                null, // accountType
2608                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2609                "testpackage"); // opPackageName
2610            fail("IllegalArgumentException expected. But no exception was thrown.");
2611        } catch (IllegalArgumentException e) {
2612            // IllegalArgumentException is expected.
2613        }
2614    }
2615
2616    @SmallTest
2617    public void testGetAccountsByFeaturesAccountNotVisible() throws Exception {
2618        unlockSystemUser();
2619
2620        when(mMockContext.checkCallingOrSelfPermission(anyString())).thenReturn(
2621                PackageManager.PERMISSION_DENIED);
2622        when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
2623                    .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
2624
2625        final CountDownLatch latch = new CountDownLatch(1);
2626        Response response = new Response(latch, mMockAccountManagerResponse);
2627        mAms.getAccountsByFeatures(
2628                response, // response
2629                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2630                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2631                "testpackage"); // opPackageName
2632        waitForLatch(latch);
2633
2634        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2635        Bundle result = mBundleCaptor.getValue();
2636        Account[] accounts = (Account[]) result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
2637        assertTrue(accounts.length == 0);
2638    }
2639
2640    @SmallTest
2641    public void testGetAccountsByFeaturesNullFeatureReturnsAllAccounts() 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                null, // 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        Arrays.sort(accounts, new AccountSorter());
2660        assertEquals(2, accounts.length);
2661        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, accounts[0]);
2662        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[1]);
2663    }
2664
2665    @SmallTest
2666    public void testGetAccountsByFeaturesReturnsAccountsWithFeaturesOnly() throws Exception {
2667        unlockSystemUser();
2668
2669        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2670        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p12", null);
2671
2672        final CountDownLatch latch = new CountDownLatch(1);
2673        Response response = new Response(latch, mMockAccountManagerResponse);
2674        mAms.getAccountsByFeatures(
2675                response, // response
2676                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2677                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2678                "testpackage"); // opPackageName
2679        waitForLatch(latch);
2680
2681        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
2682        Bundle result = mBundleCaptor.getValue();
2683        Account[] accounts = (Account[]) result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
2684        assertEquals(1, accounts.length);
2685        assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, accounts[0]);
2686    }
2687
2688    @SmallTest
2689    public void testGetAccountsByFeaturesError() throws Exception {
2690        unlockSystemUser();
2691        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2692        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_ERROR, "p12", null);
2693
2694        final CountDownLatch latch = new CountDownLatch(1);
2695        Response response = new Response(latch, mMockAccountManagerResponse);
2696        mAms.getAccountsByFeatures(
2697                response, // response
2698                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
2699                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES,
2700                "testpackage"); // opPackageName
2701        waitForLatch(latch);
2702
2703        verify(mMockAccountManagerResponse).onError(
2704                eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
2705        verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
2706    }
2707
2708    @SmallTest
2709    public void testRegisterAccountListener() throws Exception {
2710        unlockSystemUser();
2711        mAms.registerAccountListener(
2712            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2713            "testpackage"); // opPackageName
2714
2715        mAms.registerAccountListener(
2716            null, //accountTypes
2717            "testpackage"); // opPackageName
2718
2719        // Check that two previously registered receivers can be unregistered successfully.
2720        mAms.unregisterAccountListener(
2721            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2722            "testpackage"); // opPackageName
2723
2724        mAms.unregisterAccountListener(
2725             null, //accountTypes
2726            "testpackage"); // opPackageName
2727    }
2728
2729    @SmallTest
2730    public void testRegisterAccountListenerAndAddAccount() throws Exception {
2731        unlockSystemUser();
2732        mAms.registerAccountListener(
2733            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2734            "testpackage"); // opPackageName
2735
2736        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2737        // Notification about new account
2738        updateBroadcastCounters(2);
2739        assertEquals(mVisibleAccountsChangedBroadcasts, 1);
2740        assertEquals(mLoginAccountsChangedBroadcasts, 1);
2741    }
2742
2743    @SmallTest
2744    public void testRegisterAccountListenerAndAddAccountOfDifferentType() throws Exception {
2745        unlockSystemUser();
2746        mAms.registerAccountListener(
2747            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2},
2748            "testpackage"); // opPackageName
2749
2750        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2751        mAms.addAccountExplicitly(
2752            AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null);
2753        // Notification about new account
2754
2755        updateBroadcastCounters(2);
2756        assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent
2757        assertEquals(mLoginAccountsChangedBroadcasts, 2);
2758    }
2759
2760    @SmallTest
2761    public void testRegisterAccountListenerWithAddingTwoAccounts() throws Exception {
2762        unlockSystemUser();
2763
2764        HashMap<String, Integer> visibility = new HashMap<>();
2765        visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
2766            AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
2767
2768        mAms.registerAccountListener(
2769            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2770            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2771        mAms.addAccountExplicitlyWithVisibility(
2772            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
2773        mAms.unregisterAccountListener(
2774            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2775            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2776
2777        addAccountRemovedReceiver(AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2778        mAms.addAccountExplicitlyWithVisibility(
2779            AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null, visibility);
2780
2781        updateBroadcastCounters(3);
2782        assertEquals(mVisibleAccountsChangedBroadcasts, 1);
2783        assertEquals(mLoginAccountsChangedBroadcasts, 2);
2784        assertEquals(mAccountRemovedBroadcasts, 0);
2785
2786        mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
2787        mAms.registerAccountListener( null /* accountTypes */,
2788            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
2789        mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE);
2790
2791        updateBroadcastCounters(8);
2792        assertEquals(mVisibleAccountsChangedBroadcasts, 2);
2793        assertEquals(mLoginAccountsChangedBroadcasts, 4);
2794        assertEquals(mAccountRemovedBroadcasts, 2);
2795    }
2796
2797    @SmallTest
2798    public void testRegisterAccountListenerForThreePackages() throws Exception {
2799        unlockSystemUser();
2800
2801        addAccountRemovedReceiver("testpackage1");
2802        HashMap<String, Integer> visibility = new HashMap<>();
2803        visibility.put("testpackage1", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
2804        visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
2805        visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
2806
2807        mAms.registerAccountListener(
2808            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2809            "testpackage1"); // opPackageName
2810        mAms.registerAccountListener(
2811            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2812            "testpackage2"); // opPackageName
2813        mAms.registerAccountListener(
2814            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2815            "testpackage3"); // opPackageName
2816        mAms.addAccountExplicitlyWithVisibility(
2817            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
2818        updateBroadcastCounters(4);
2819        assertEquals(mVisibleAccountsChangedBroadcasts, 3);
2820        assertEquals(mLoginAccountsChangedBroadcasts, 1);
2821
2822        mAms.unregisterAccountListener(
2823            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2824            "testpackage3"); // opPackageName
2825        // Remove account with 2 active listeners.
2826        mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
2827        updateBroadcastCounters(8);
2828        assertEquals(mVisibleAccountsChangedBroadcasts, 5);
2829        assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove
2830        assertEquals(mAccountRemovedBroadcasts, 1);
2831
2832        // Add account of another type.
2833        mAms.addAccountExplicitly(
2834            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null);
2835
2836        updateBroadcastCounters(8);
2837        assertEquals(mVisibleAccountsChangedBroadcasts, 5);
2838        assertEquals(mLoginAccountsChangedBroadcasts, 3);
2839        assertEquals(mAccountRemovedBroadcasts, 1);
2840    }
2841
2842    @SmallTest
2843    public void testRegisterAccountListenerForAddingAccountWithVisibility() throws Exception {
2844        unlockSystemUser();
2845
2846        HashMap<String, Integer> visibility = new HashMap<>();
2847        visibility.put("testpackage1", AccountManager.VISIBILITY_NOT_VISIBLE);
2848        visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
2849        visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
2850
2851        addAccountRemovedReceiver("testpackage1");
2852        mAms.registerAccountListener(
2853            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2854            "testpackage1"); // opPackageName
2855        mAms.registerAccountListener(
2856            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2857            "testpackage2"); // opPackageName
2858        mAms.registerAccountListener(
2859            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2860            "testpackage3"); // opPackageName
2861        mAms.addAccountExplicitlyWithVisibility(
2862            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
2863
2864        updateBroadcastCounters(2);
2865        assertEquals(mVisibleAccountsChangedBroadcasts, 1);
2866        assertEquals(mLoginAccountsChangedBroadcasts, 1);
2867
2868        mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
2869
2870        updateBroadcastCounters(4);
2871        assertEquals(mVisibleAccountsChangedBroadcasts, 2);
2872        assertEquals(mLoginAccountsChangedBroadcasts, 2);
2873        assertEquals(mAccountRemovedBroadcasts, 0); // account was never visible.
2874    }
2875
2876    @SmallTest
2877    public void testRegisterAccountListenerCredentialsUpdate() throws Exception {
2878        unlockSystemUser();
2879        mAms.registerAccountListener(
2880            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2881            "testpackage"); // opPackageName
2882        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
2883        mAms.setPassword(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "pwd");
2884        updateBroadcastCounters(4);
2885        assertEquals(mVisibleAccountsChangedBroadcasts, 2);
2886        assertEquals(mLoginAccountsChangedBroadcasts, 2);
2887    }
2888
2889    @SmallTest
2890    public void testUnregisterAccountListenerNotRegistered() throws Exception {
2891        unlockSystemUser();
2892        try {
2893            mAms.unregisterAccountListener(
2894                new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
2895                "testpackage"); // opPackageName
2896            fail("IllegalArgumentException expected. But no exception was thrown.");
2897        } catch (IllegalArgumentException e) {
2898            // IllegalArgumentException is expected.
2899        }
2900    }
2901
2902    private void updateBroadcastCounters (int expectedBroadcasts){
2903        mVisibleAccountsChangedBroadcasts = 0;
2904        mLoginAccountsChangedBroadcasts = 0;
2905        mAccountRemovedBroadcasts = 0;
2906        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
2907        verify(mMockContext, atLeast(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(),
2908            any(UserHandle.class));
2909        for (Intent intent : captor.getAllValues()) {
2910            if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED.equals(intent.getAction())) {
2911                mVisibleAccountsChangedBroadcasts++;
2912            } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
2913                mLoginAccountsChangedBroadcasts++;
2914            } else if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) {
2915                mAccountRemovedBroadcasts++;
2916            }
2917        }
2918    }
2919
2920    private void addAccountRemovedReceiver(String packageName) {
2921        ResolveInfo resolveInfo = new ResolveInfo();
2922        resolveInfo.activityInfo = new ActivityInfo();
2923        resolveInfo.activityInfo.applicationInfo =  new ApplicationInfo();
2924        resolveInfo.activityInfo.applicationInfo.packageName = packageName;
2925
2926        List<ResolveInfo> accountRemovedReceivers = new ArrayList<>();
2927        accountRemovedReceivers.add(resolveInfo);
2928        when(mMockPackageManager.queryBroadcastReceiversAsUser(any(Intent.class), anyInt(),
2929            anyInt())).thenReturn(accountRemovedReceivers);
2930    }
2931
2932    @SmallTest
2933    public void testConcurrencyReadWrite() throws Exception {
2934        // Test 2 threads calling getAccounts and 1 thread setAuthToken
2935        unlockSystemUser();
2936        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
2937        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
2938
2939        Account a1 = new Account("account1",
2940                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
2941        mAms.addAccountExplicitly(a1, "p1", null);
2942        List<String> errors = Collections.synchronizedList(new ArrayList<>());
2943        int readerCount = 2;
2944        ExecutorService es = Executors.newFixedThreadPool(readerCount + 1);
2945        AtomicLong readTotalTime = new AtomicLong(0);
2946        AtomicLong writeTotalTime = new AtomicLong(0);
2947        final CyclicBarrier cyclicBarrier = new CyclicBarrier(readerCount + 1);
2948
2949        final int loopSize = 20;
2950        for (int t = 0; t < readerCount; t++) {
2951            es.submit(() -> {
2952                for (int i = 0; i < loopSize; i++) {
2953                    String logPrefix = Thread.currentThread().getName() + " " + i;
2954                    waitForCyclicBarrier(cyclicBarrier);
2955                    cyclicBarrier.reset();
2956                    SystemClock.sleep(1); // Ensure that writer wins
2957                    Log.d(TAG, logPrefix + " getAccounts started");
2958                    long ti = System.currentTimeMillis();
2959                    try {
2960                        Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
2961                        if (accounts == null || accounts.length != 1
2962                                || !AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1.equals(
2963                                accounts[0].type)) {
2964                            String msg = logPrefix + ": Unexpected accounts: " + Arrays
2965                                    .toString(accounts);
2966                            Log.e(TAG, "    " + msg);
2967                            errors.add(msg);
2968                        }
2969                        Log.d(TAG, logPrefix + " getAccounts done");
2970                    } catch (Exception e) {
2971                        String msg = logPrefix + ": getAccounts failed " + e;
2972                        Log.e(TAG, msg, e);
2973                        errors.add(msg);
2974                    }
2975                    ti = System.currentTimeMillis() - ti;
2976                    readTotalTime.addAndGet(ti);
2977                }
2978            });
2979        }
2980
2981        es.submit(() -> {
2982            for (int i = 0; i < loopSize; i++) {
2983                String logPrefix = Thread.currentThread().getName() + " " + i;
2984                waitForCyclicBarrier(cyclicBarrier);
2985                long ti = System.currentTimeMillis();
2986                Log.d(TAG, logPrefix + " setAuthToken started");
2987                try {
2988                    mAms.setAuthToken(a1, "t1", "v" + i);
2989                    Log.d(TAG, logPrefix + " setAuthToken done");
2990                } catch (Exception e) {
2991                    errors.add(logPrefix + ": setAuthToken failed: " + e);
2992                }
2993                ti = System.currentTimeMillis() - ti;
2994                writeTotalTime.addAndGet(ti);
2995            }
2996        });
2997        es.shutdown();
2998        assertTrue("Time-out waiting for jobs to finish",
2999                es.awaitTermination(10, TimeUnit.SECONDS));
3000        es.shutdownNow();
3001        assertTrue("Errors: " + errors, errors.isEmpty());
3002        Log.i(TAG, "testConcurrencyReadWrite: readTotalTime=" + readTotalTime + " avg="
3003                + (readTotalTime.doubleValue() / readerCount / loopSize));
3004        Log.i(TAG, "testConcurrencyReadWrite: writeTotalTime=" + writeTotalTime + " avg="
3005                + (writeTotalTime.doubleValue() / loopSize));
3006    }
3007
3008    @SmallTest
3009    public void testConcurrencyRead() throws Exception {
3010        // Test 2 threads calling getAccounts
3011        unlockSystemUser();
3012        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
3013        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
3014
3015        Account a1 = new Account("account1",
3016                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3017        mAms.addAccountExplicitly(a1, "p1", null);
3018        List<String> errors = Collections.synchronizedList(new ArrayList<>());
3019        int readerCount = 2;
3020        ExecutorService es = Executors.newFixedThreadPool(readerCount + 1);
3021        AtomicLong readTotalTime = new AtomicLong(0);
3022
3023        final int loopSize = 20;
3024        for (int t = 0; t < readerCount; t++) {
3025            es.submit(() -> {
3026                for (int i = 0; i < loopSize; i++) {
3027                    String logPrefix = Thread.currentThread().getName() + " " + i;
3028                    Log.d(TAG, logPrefix + " getAccounts started");
3029                    long ti = System.currentTimeMillis();
3030                    try {
3031                        Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
3032                        if (accounts == null || accounts.length != 1
3033                                || !AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1.equals(
3034                                accounts[0].type)) {
3035                            String msg = logPrefix + ": Unexpected accounts: " + Arrays
3036                                    .toString(accounts);
3037                            Log.e(TAG, "    " + msg);
3038                            errors.add(msg);
3039                        }
3040                        Log.d(TAG, logPrefix + " getAccounts done");
3041                    } catch (Exception e) {
3042                        String msg = logPrefix + ": getAccounts failed " + e;
3043                        Log.e(TAG, msg, e);
3044                        errors.add(msg);
3045                    }
3046                    ti = System.currentTimeMillis() - ti;
3047                    readTotalTime.addAndGet(ti);
3048                }
3049            });
3050        }
3051        es.shutdown();
3052        assertTrue("Time-out waiting for jobs to finish",
3053                es.awaitTermination(10, TimeUnit.SECONDS));
3054        es.shutdownNow();
3055        assertTrue("Errors: " + errors, errors.isEmpty());
3056        Log.i(TAG, "testConcurrencyRead: readTotalTime=" + readTotalTime + " avg="
3057                + (readTotalTime.doubleValue() / readerCount / loopSize));
3058    }
3059
3060    private void waitForCyclicBarrier(CyclicBarrier cyclicBarrier) {
3061        try {
3062            cyclicBarrier.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3063        } catch (Exception e) {
3064            throw new IllegalStateException("Should not throw " + e, e);
3065        }
3066    }
3067
3068    private void waitForLatch(CountDownLatch latch) {
3069        try {
3070            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3071        } catch (InterruptedException e) {
3072            throw new IllegalStateException("Should not throw an InterruptedException", e);
3073        }
3074    }
3075
3076    private Bundle createAddAccountOptions(String accountName) {
3077        Bundle options = new Bundle();
3078        options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3079        return options;
3080    }
3081
3082    private Bundle createGetAuthTokenOptions() {
3083        Bundle options = new Bundle();
3084        options.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME,
3085                AccountManagerServiceTestFixtures.CALLER_PACKAGE);
3086        options.putLong(AccountManagerServiceTestFixtures.KEY_TOKEN_EXPIRY,
3087                System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND);
3088        return options;
3089    }
3090
3091    private Bundle encryptBundleWithCryptoHelper(Bundle sessionBundle) {
3092        Bundle encryptedBundle = null;
3093        try {
3094            CryptoHelper cryptoHelper = CryptoHelper.getInstance();
3095            encryptedBundle = cryptoHelper.encryptBundle(sessionBundle);
3096        } catch (GeneralSecurityException e) {
3097            throw new IllegalStateException("Failed to encrypt session bundle.", e);
3098        }
3099        return encryptedBundle;
3100    }
3101
3102    private Bundle createEncryptedSessionBundle(final String accountName) {
3103        Bundle sessionBundle = new Bundle();
3104        sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3105        sessionBundle.putString(
3106                AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3107                AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3108        sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3109                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3110        sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3111        return encryptBundleWithCryptoHelper(sessionBundle);
3112    }
3113
3114    private Bundle createEncryptedSessionBundleWithError(final String accountName) {
3115        Bundle sessionBundle = new Bundle();
3116        sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3117        sessionBundle.putString(
3118                AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3119                AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3120        sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3121                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3122        sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3123        sessionBundle.putInt(
3124                AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_INVALID_RESPONSE);
3125        sessionBundle.putString(AccountManager.KEY_ERROR_MESSAGE,
3126                AccountManagerServiceTestFixtures.ERROR_MESSAGE);
3127        return encryptBundleWithCryptoHelper(sessionBundle);
3128    }
3129
3130    private Bundle createEncryptedSessionBundleWithNoAccountType(final String accountName) {
3131        Bundle sessionBundle = new Bundle();
3132        sessionBundle.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3133        sessionBundle.putString(
3134                AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3135                AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3136        sessionBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.session.package");
3137        return encryptBundleWithCryptoHelper(sessionBundle);
3138    }
3139
3140    private Bundle createAppBundle() {
3141        Bundle appBundle = new Bundle();
3142        appBundle.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, "APCT.package");
3143        return appBundle;
3144    }
3145
3146    private Bundle createOptionsWithAccountName(final String accountName) {
3147        Bundle sessionBundle = new Bundle();
3148        sessionBundle.putString(
3149                AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1,
3150                AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1);
3151        sessionBundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
3152                AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
3153        Bundle options = new Bundle();
3154        options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME, accountName);
3155        options.putBundle(AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE,
3156                sessionBundle);
3157        options.putString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD,
3158                AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD);
3159        return options;
3160    }
3161
3162    private int readNumberOfAccountsFromDbFile(Context context, String dbName) {
3163        SQLiteDatabase ceDb = context.openOrCreateDatabase(dbName, 0, null);
3164        try (Cursor cursor = ceDb.rawQuery("SELECT count(*) FROM accounts", null)) {
3165            assertTrue(cursor.moveToNext());
3166            return cursor.getInt(0);
3167        }
3168    }
3169
3170    private void unlockSystemUser() {
3171        mAms.onUserUnlocked(newIntentForUser(UserHandle.USER_SYSTEM));
3172    }
3173
3174    private static Intent newIntentForUser(int userId) {
3175        Intent intent = new Intent();
3176        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3177        return intent;
3178    }
3179
3180    static class MyMockContext extends MockContext {
3181        private Context mTestContext;
3182        private Context mMockContext;
3183
3184        MyMockContext(Context testContext, Context mockContext) {
3185            this.mTestContext = testContext;
3186            this.mMockContext = mockContext;
3187        }
3188
3189        @Override
3190        public int checkCallingOrSelfPermission(final String permission) {
3191            return mMockContext.checkCallingOrSelfPermission(permission);
3192        }
3193
3194        @Override
3195        public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
3196                UserHandle user) {
3197            return mTestContext.bindServiceAsUser(service, conn, flags, user);
3198        }
3199
3200        @Override
3201        public void unbindService(ServiceConnection conn) {
3202            mTestContext.unbindService(conn);
3203        }
3204
3205        @Override
3206        public PackageManager getPackageManager() {
3207            return mMockContext.getPackageManager();
3208        }
3209
3210        @Override
3211        public String getPackageName() {
3212            return mTestContext.getPackageName();
3213        }
3214
3215        @Override
3216        public Object getSystemService(String name) {
3217            return mMockContext.getSystemService(name);
3218        }
3219
3220        @Override
3221        public String getSystemServiceName(Class<?> serviceClass) {
3222            return mMockContext.getSystemServiceName(serviceClass);
3223        }
3224
3225        @Override
3226        public void startActivityAsUser(Intent intent, UserHandle user) {
3227            mMockContext.startActivityAsUser(intent, user);
3228        }
3229
3230        @Override
3231        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
3232            return mMockContext.registerReceiver(receiver, filter);
3233        }
3234
3235        @Override
3236        public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
3237                IntentFilter filter, String broadcastPermission, Handler scheduler) {
3238            return mMockContext.registerReceiverAsUser(
3239                    receiver, user, filter, broadcastPermission, scheduler);
3240        }
3241
3242        @Override
3243        public SQLiteDatabase openOrCreateDatabase(String file, int mode,
3244                SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
3245            return mTestContext.openOrCreateDatabase(file, mode, factory,errorHandler);
3246        }
3247
3248        @Override
3249        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
3250            mMockContext.sendBroadcastAsUser(intent, user);
3251        }
3252
3253        @Override
3254        public String getOpPackageName() {
3255            return mMockContext.getOpPackageName();
3256        }
3257
3258        @Override
3259        public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
3260                throws PackageManager.NameNotFoundException {
3261            return mMockContext.createPackageContextAsUser(packageName, flags, user);
3262        }
3263    }
3264
3265    static class TestAccountAuthenticatorCache extends AccountAuthenticatorCache {
3266        public TestAccountAuthenticatorCache(Context realContext) {
3267            super(realContext);
3268        }
3269
3270        @Override
3271        protected File getUserSystemDirectory(int userId) {
3272            return new File(mContext.getCacheDir(), "authenticator");
3273        }
3274    }
3275
3276    static class TestInjector extends AccountManagerService.Injector {
3277        private Context mRealContext;
3278        private INotificationManager mMockNotificationManager;
3279        TestInjector(Context realContext,
3280                Context mockContext,
3281                INotificationManager mockNotificationManager) {
3282            super(mockContext);
3283            mRealContext = realContext;
3284            mMockNotificationManager = mockNotificationManager;
3285        }
3286
3287        @Override
3288        Looper getMessageHandlerLooper() {
3289            return Looper.getMainLooper();
3290        }
3291
3292        @Override
3293        void addLocalService(AccountManagerInternal service) {
3294        }
3295
3296        @Override
3297        IAccountAuthenticatorCache getAccountAuthenticatorCache() {
3298            return new TestAccountAuthenticatorCache(mRealContext);
3299        }
3300
3301        @Override
3302        protected String getCeDatabaseName(int userId) {
3303            return new File(mRealContext.getCacheDir(), CE_DB).getPath();
3304        }
3305
3306        @Override
3307        protected String getDeDatabaseName(int userId) {
3308            return new File(mRealContext.getCacheDir(), DE_DB).getPath();
3309        }
3310
3311        @Override
3312        String getPreNDatabaseName(int userId) {
3313            return new File(mRealContext.getCacheDir(), PREN_DB).getPath();
3314        }
3315
3316        @Override
3317        INotificationManager getNotificationManager() {
3318            return mMockNotificationManager;
3319        }
3320    }
3321
3322    class Response extends IAccountManagerResponse.Stub {
3323        private CountDownLatch mLatch;
3324        private IAccountManagerResponse mMockResponse;
3325        public Response(CountDownLatch latch, IAccountManagerResponse mockResponse) {
3326            mLatch = latch;
3327            mMockResponse = mockResponse;
3328        }
3329
3330        @Override
3331        public void onResult(Bundle bundle) {
3332            try {
3333                mMockResponse.onResult(bundle);
3334            } catch (RemoteException e) {
3335            }
3336            mLatch.countDown();
3337        }
3338
3339        @Override
3340        public void onError(int code, String message) {
3341            try {
3342                mMockResponse.onError(code, message);
3343            } catch (RemoteException e) {
3344            }
3345            mLatch.countDown();
3346        }
3347    }
3348}
3349