1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.contacts.tests;
17 
18 import static junit.framework.Assert.assertTrue;
19 
20 import android.accounts.Account;
21 import android.accounts.AccountManager;
22 import android.content.ContentResolver;
23 import android.content.Context;
24 import android.os.Build;
25 import android.provider.ContactsContract.RawContacts;
26 
27 import androidx.annotation.NonNull;
28 import androidx.annotation.RequiresApi;
29 import androidx.test.InstrumentationRegistry;
30 
31 import com.android.contacts.model.account.AccountWithDataSet;
32 
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.List;
36 
37 @SuppressWarnings("MissingPermission")
38 public class AccountsTestHelper {
39     private static final String TAG = "AccountsTestHelper";
40 
41     public static final String TEST_ACCOUNT_TYPE = "com.android.contacts.tests.testauth.basic";
42 
43     private final Context mContext;
44     private final AccountManager mAccountManager;
45     private final ContentResolver mResolver;
46 
47     private List<Account> mAddedAccounts;
48 
AccountsTestHelper()49     public AccountsTestHelper() {
50         // Use context instead of target context because the test package has the permissions needed
51         // to add and remove accounts.
52         this(InstrumentationRegistry.getContext());
53     }
54 
AccountsTestHelper(Context context)55     public AccountsTestHelper(Context context) {
56         mContext = context;
57         mAccountManager = AccountManager.get(mContext);
58         mResolver = mContext.getContentResolver();
59         mAddedAccounts = new ArrayList<>();
60     }
61 
addTestAccount(AccountWithDataSet account)62     public void addTestAccount(AccountWithDataSet account) {
63         Account newAccount = new Account(account.name, account.type);
64         assertTrue(mAccountManager.addAccountExplicitly(newAccount, null, null));
65         mAddedAccounts.add(newAccount);
66     }
67 
addTestAccount()68     public AccountWithDataSet addTestAccount() {
69         return addTestAccount(generateAccountName());
70     }
71 
addTestAccount(@onNull String name)72     public AccountWithDataSet addTestAccount(@NonNull String name) {
73         // remember the most recent one. If the caller wants to add multiple accounts they will
74         // have to keep track of them themselves.
75         final AccountWithDataSet account = new AccountWithDataSet(name, TEST_ACCOUNT_TYPE, null);
76         addTestAccount(account);
77         return account;
78     }
79 
generateAccountName(String prefix)80     public String generateAccountName(String prefix) {
81         return prefix + "_t" + System.nanoTime();
82     }
83 
generateAccountName()84     public String generateAccountName() {
85         return generateAccountName("test");
86     }
87 
88     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
removeTestAccount(AccountWithDataSet account)89     public void removeTestAccount(AccountWithDataSet account) {
90         final Account remove = account.getAccountOrNull();
91         mAccountManager.removeAccountExplicitly(remove);
92         mAddedAccounts.remove(remove);
93     }
94 
95     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
removeTestAccount(String accountName)96     public void removeTestAccount(String accountName) {
97         removeTestAccount(new AccountWithDataSet(accountName, TEST_ACCOUNT_TYPE, null));
98     }
99 
hasTestAccount(String name)100     public boolean hasTestAccount(String name) {
101         final List<Account> accounts = Arrays.asList(
102                 mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE));
103         return accounts.contains(new Account(name, TEST_ACCOUNT_TYPE));
104     }
105 
removeContactsForAccount(AccountWithDataSet account)106     public void removeContactsForAccount(AccountWithDataSet account) {
107         mResolver.delete(RawContacts.CONTENT_URI,
108                 RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
109                 new String[] { account.name, account.type });
110     }
111 
112     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
cleanup()113     public void cleanup() {
114         // Note that we don't need to cleanup up the contact data associated with the account.
115         // CP2 will eventually do that automatically so as long as we're using unique account
116         // names we should be safe. Note that cleanup is not done synchronously when the account
117         // is removed so if multiple tests are using the same account name then the data should
118         // be manually deleted after each test run.
119 
120         for (Account account : mAddedAccounts) {
121             mAccountManager.removeAccountExplicitly(account);
122         }
123         mAddedAccounts.clear();
124     }
125 
126     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
removeAccountsWithPrefix(Context context, String prefix)127     public static void removeAccountsWithPrefix(Context context, String prefix) {
128         final AccountManager accountManager =
129                 (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
130         final Account[] accounts = accountManager.getAccountsByType(TEST_ACCOUNT_TYPE);
131         for (Account account : accounts) {
132             if (account.name.startsWith(prefix)) {
133                 accountManager.removeAccountExplicitly(account);
134             }
135         }
136 
137 
138     }
139 }
140