• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.settings.applications.contacts;
17 
18 import static android.provider.ContactsContract.RawContacts.DefaultAccount.KEY_DEFAULT_ACCOUNT_STATE;
19 import static android.provider.ContactsContract.RawContacts.DefaultAccount.KEY_ELIGIBLE_DEFAULT_ACCOUNTS;
20 import static android.provider.ContactsContract.RawContacts.DefaultAccount.QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD;
21 import static android.provider.ContactsContract.RawContacts.DefaultAccount.QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD;
22 import static android.provider.ContactsContract.RawContacts.DefaultAccount.SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD;
23 import static android.provider.Settings.ACTION_ADD_ACCOUNT;
24 import static android.provider.Settings.EXTRA_ACCOUNT_TYPES;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 
34 import android.accounts.Account;
35 import android.app.settings.SettingsEnums;
36 import android.content.ContentProviderClient;
37 import android.content.ContentResolver;
38 import android.content.Context;
39 import android.content.Intent;
40 import android.content.res.Resources;
41 import android.graphics.drawable.Drawable;
42 import android.os.Bundle;
43 import android.provider.ContactsContract;
44 import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
45 import android.provider.SearchIndexableResource;
46 import android.text.TextUtils;
47 
48 import androidx.preference.Preference;
49 import androidx.preference.PreferenceGroup;
50 import androidx.preference.PreferenceManager;
51 import androidx.preference.PreferenceScreen;
52 import androidx.test.core.app.ApplicationProvider;
53 
54 import com.android.settings.R;
55 import com.android.settings.accounts.AddAccountSettings;
56 import com.android.settingslib.accounts.AuthenticatorHelper;
57 import com.android.settingslib.widget.SelectorWithWidgetPreference;
58 
59 import org.junit.Before;
60 import org.junit.Rule;
61 import org.junit.Test;
62 import org.junit.runner.RunWith;
63 import org.mockito.ArgumentCaptor;
64 import org.mockito.Mock;
65 import org.mockito.Spy;
66 import org.mockito.junit.MockitoJUnit;
67 import org.mockito.junit.MockitoRule;
68 import org.robolectric.RobolectricTestRunner;
69 import org.robolectric.RuntimeEnvironment;
70 import org.robolectric.annotation.Config;
71 import org.robolectric.annotation.Implementation;
72 import org.robolectric.annotation.Implements;
73 
74 import java.util.ArrayList;
75 import java.util.List;
76 
77 @RunWith(RobolectricTestRunner.class)
78 @Config(shadows = ContactsStorageSettingsTest.ShadowAuthenticatorHelper.class)
79 public class ContactsStorageSettingsTest {
80     private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
81     private static final String PREF_KEY_ACCOUNT_CATEGORY = "account_category";
82     private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
83 
84     private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "com.google");
85 
86     private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "com.samsung");
87 
88     private static final Account TEST_ACCOUNT3 = new Account("test@outlook.com", "com.outlook");
89 
90     private static final Account SIM_ACCOUNT = new Account("SIM", "SIM");
91 
92     @Rule
93     public final MockitoRule mockito = MockitoJUnit.rule();
94     @Spy
95     public final Context mContext = spy(ApplicationProvider.getApplicationContext());
96     @Mock
97     private ContentResolver mContentResolver;
98     @Mock
99     private ContentProviderClient mContentProviderClient;
100     private PreferenceManager mPreferenceManager;
101     private TestContactsStorageSettings mContactsStorageSettings;
102     private PreferenceScreen mScreen;
103     private PreferenceGroup accountCategory;
104 
105     @Before
setUp()106     public void setUp() throws Exception {
107         mContactsStorageSettings = spy(
108                 new TestContactsStorageSettings(mContext, mContentResolver));
109         when(mContentResolver.acquireContentProviderClient(
110                 eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient);
111         mPreferenceManager = new PreferenceManager(mContext);
112         when(mContactsStorageSettings.getPreferenceManager()).thenReturn(mPreferenceManager);
113         mScreen = spy(mPreferenceManager.inflateFromResource(mContext,
114                 R.xml.contacts_storage_settings, mScreen));
115         when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
116         accountCategory = mScreen.findPreference(PREF_KEY_ACCOUNT_CATEGORY);
117         SelectorWithWidgetPreference deviceOnlyPreference = mScreen.findPreference(
118                 PREF_KEY_DEVICE_ONLY);
119         when(mContactsStorageSettings.findPreference(eq(PREF_KEY_DEVICE_ONLY))).thenReturn(
120                 deviceOnlyPreference);
121         when(mContactsStorageSettings.findPreference(eq(PREF_KEY_ACCOUNT_CATEGORY))).thenReturn(
122                 accountCategory);
123         when(mContactsStorageSettings.getPreferenceScreen()).thenReturn(mScreen);
124         mContactsStorageSettings.setEligibleAccountTypes(new String[]{"com.google"});
125         mContactsStorageSettings.onAttach(mContext);
126     }
127 
128     @Test
getMetricsCategory()129     public void getMetricsCategory() {
130         assertThat(mContactsStorageSettings.getMetricsCategory()).isEqualTo(
131                 SettingsEnums.CONTACTS_STORAGE);
132     }
133 
134     @Test
getPreferenceScreenResId()135     public void getPreferenceScreenResId() {
136         assertThat(mContactsStorageSettings.getPreferenceScreenResId()).isEqualTo(
137                 R.xml.contacts_storage_settings);
138     }
139 
140     @Test
verifyDeviceOnlyPreference_onClick_setDefaultAccountToNull()141     public void verifyDeviceOnlyPreference_onClick_setDefaultAccountToNull() throws Exception {
142         Bundle currentDefaultAccount = new Bundle();
143         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
144                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
145         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
146                 any())).thenReturn(currentDefaultAccount);
147         Bundle eligibleAccountBundle = new Bundle();
148         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
149                 new ArrayList<>());
150         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
151                 any())).thenReturn(eligibleAccountBundle);
152 
153         SelectorWithWidgetPreference deviceOnlyPreference = mContactsStorageSettings.findPreference(
154                 PREF_KEY_DEVICE_ONLY);
155 
156         assertThat(deviceOnlyPreference.getTitle()).isEqualTo("Device only");
157         assertThat(deviceOnlyPreference.getSummary()).isEqualTo(
158                 "Contacts may not sync or be available on your other devices");
159         assertThat(deviceOnlyPreference.getOrder()).isEqualTo(999);
160         assertThat(mContactsStorageSettings.findPreference(
161                 PREF_KEY_ACCOUNT_CATEGORY).getTitle()).isEqualTo("Where to save contacts");
162 
163         mContactsStorageSettings.refreshUI();
164         mContactsStorageSettings.onRadioButtonClicked(deviceOnlyPreference);
165 
166         assertThat(deviceOnlyPreference.isChecked()).isTrue();
167         ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
168         verify(mContentProviderClient).call(eq(SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
169                 captor.capture());
170         Bundle accountBundle = captor.getValue();
171         assertThat(accountBundle.getString(ContactsContract.Settings.ACCOUNT_NAME)).isNull();
172         assertThat(accountBundle.getString(ContactsContract.Settings.ACCOUNT_TYPE)).isNull();
173     }
174 
175     @Test
verifyAddAccountPreference_eligibleAccountsAvailable_startAddAccountActivityOnClick()176     public void verifyAddAccountPreference_eligibleAccountsAvailable_startAddAccountActivityOnClick()
177             throws Exception {
178         Bundle currentDefaultAccount = new Bundle();
179         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
180                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
181         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
182                 any())).thenReturn(currentDefaultAccount);
183         Bundle eligibleAccountBundle = new Bundle();
184         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
185                 new ArrayList<>());
186         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
187                 any())).thenReturn(eligibleAccountBundle);
188 
189         mContactsStorageSettings.refreshUI();
190 
191         assertThat(mContactsStorageSettings.findPreference(
192                 PREF_KEY_ACCOUNT_CATEGORY).getTitle()).isEqualTo("Where to save contacts");
193         assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getTitle()).isEqualTo(
194                 "Add an account to get started");
195         assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getOrder()).isEqualTo(998);
196 
197         mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).performClick();
198 
199         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
200         verify(mContext).startActivity(captor.capture());
201         Intent addAccountIntent = captor.getValue();
202         assertThat(addAccountIntent.getAction()).isEqualTo(ACTION_ADD_ACCOUNT);
203         assertThat(addAccountIntent.getComponent().getClassName()).isEqualTo(
204                 AddAccountSettings.class.getCanonicalName());
205         String[] eligibleAccounts = (String[]) addAccountIntent.getExtra(EXTRA_ACCOUNT_TYPES);
206         assertThat(List.of(eligibleAccounts)).containsExactly("com.google");
207     }
208 
209     @Test
verifyAddAccountPreference_noEligibleAccountsAvailable_dontShowPreference()210     public void verifyAddAccountPreference_noEligibleAccountsAvailable_dontShowPreference()
211             throws Exception {
212         Bundle currentDefaultAccount = new Bundle();
213         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
214                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
215         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
216                 any())).thenReturn(currentDefaultAccount);
217         Bundle eligibleAccountBundle = new Bundle();
218         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
219                 new ArrayList<>());
220         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
221                 any())).thenReturn(eligibleAccountBundle);
222         mContactsStorageSettings.setEligibleAccountTypes(new String[]{});
223 
224         mContactsStorageSettings.refreshUI();
225 
226         Preference addAccountPreference = mScreen.findPreference(PREF_KEY_ADD_ACCOUNT);
227         assertThat(addAccountPreference).isNull();
228     }
229 
230     @Test
verifyEligibleAccountPreference_onClick_setSelectedDefaultAccount()231     public void verifyEligibleAccountPreference_onClick_setSelectedDefaultAccount()
232             throws Exception {
233         Bundle currentDefaultAccount = new Bundle();
234         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
235                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
236         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT2.name);
237         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT2.type);
238         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
239                 any())).thenReturn(currentDefaultAccount);
240         Bundle eligibleAccountBundle = new Bundle();
241         ArrayList<Account> eligibleAccounts = new ArrayList<>(
242                 List.of(TEST_ACCOUNT1, TEST_ACCOUNT2));
243         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
244                 eligibleAccounts);
245         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
246                 any())).thenReturn(eligibleAccountBundle);
247 
248         mContactsStorageSettings.refreshUI();
249 
250         SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
251                 String.valueOf(TEST_ACCOUNT1.hashCode()));
252         assertThat(account1Preference.getTitle()).isEqualTo("Device & Google");
253         assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
254         assertThat(account1Preference.getIcon()).isNotNull();
255 
256         SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
257                 String.valueOf(TEST_ACCOUNT2.hashCode()));
258         assertThat(account2Preference.getTitle()).isEqualTo("Device & Samsung");
259         assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
260         assertThat(account2Preference.getIcon()).isNotNull();
261 
262         mContactsStorageSettings.onRadioButtonClicked(account2Preference);
263         assertThat(account1Preference.isChecked()).isFalse();
264         assertThat(account2Preference.isChecked()).isTrue();
265 
266         ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
267         verify(mContentProviderClient).call(eq(SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
268                 captor.capture());
269         Bundle setAccountBundle = captor.getValue();
270         assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_NAME)).isEqualTo(
271                 "test@samsung.com");
272         assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_TYPE)).isEqualTo(
273                 "com.samsung");
274 
275         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
276         verify(mContext).startActivity(intentCaptor.capture());
277         Intent moveContactsIntent = intentCaptor.getValue();
278         assertThat(moveContactsIntent.getAction()).isEqualTo(
279                 ContactsContract.RawContacts.DefaultAccount.ACTION_MOVE_CONTACTS_TO_DEFAULT_ACCOUNT);
280         assertThat(moveContactsIntent.getPackage()).isEqualTo(
281                 "com.android.providers.contacts");
282     }
283 
284     @Test
verifyAccountPreference_defaultAccountIsNotEligibleCloudAccount_createNewDefaultAccountPreference()285     public void verifyAccountPreference_defaultAccountIsNotEligibleCloudAccount_createNewDefaultAccountPreference()
286             throws Exception {
287         Bundle currentDefaultAccount = new Bundle();
288         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
289                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
290         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT3.name);
291         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT3.type);
292         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
293                 any())).thenReturn(currentDefaultAccount);
294         Bundle eligibleAccountBundle = new Bundle();
295         ArrayList<Account> eligibleAccounts = new ArrayList<>(
296                 List.of(TEST_ACCOUNT1, TEST_ACCOUNT2));
297         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
298                 eligibleAccounts);
299         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
300                 any())).thenReturn(eligibleAccountBundle);
301 
302         mContactsStorageSettings.refreshUI();
303 
304         SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
305                 String.valueOf(TEST_ACCOUNT1.hashCode()));
306         assertThat(account1Preference.getTitle()).isEqualTo("Device & Google");
307         assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
308         assertThat(account1Preference.getIcon()).isNotNull();
309 
310         SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
311                 String.valueOf(TEST_ACCOUNT2.hashCode()));
312         assertThat(account2Preference.getTitle()).isEqualTo("Device & Samsung");
313         assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
314         assertThat(account2Preference.getIcon()).isNotNull();
315 
316         SelectorWithWidgetPreference account3Preference = accountCategory.findPreference(
317                 String.valueOf(TEST_ACCOUNT3.hashCode()));
318         assertThat(account3Preference.getTitle()).isEqualTo("Device & Outlook");
319         assertThat(account3Preference.getSummary()).isEqualTo("test@outlook.com");
320         assertThat(account3Preference.getIcon()).isNotNull();
321 
322         assertThat(account1Preference.isChecked()).isFalse();
323         assertThat(account2Preference.isChecked()).isFalse();
324         assertThat(account3Preference.isChecked()).isTrue();
325     }
326 
327     @Test
verifyAccountPreference_defaultAccountIsSimAccount_createSimAccountPreference()328     public void verifyAccountPreference_defaultAccountIsSimAccount_createSimAccountPreference()
329             throws Exception {
330         Bundle currentDefaultAccount = new Bundle();
331         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
332                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM);
333         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, SIM_ACCOUNT.name);
334         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, SIM_ACCOUNT.type);
335         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
336                 any())).thenReturn(currentDefaultAccount);
337         Bundle eligibleAccountBundle = new Bundle();
338         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
339                 new ArrayList<>());
340         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
341                 any())).thenReturn(eligibleAccountBundle);
342 
343         mContactsStorageSettings.refreshUI();
344 
345         SelectorWithWidgetPreference simPreference = accountCategory.findPreference(
346                 String.valueOf(SIM_ACCOUNT.hashCode()));
347         assertThat(simPreference.getTitle()).isEqualTo("SIM");
348         assertThat(simPreference.getSummary()).isEqualTo(
349                 "Contacts may not sync or be available on your other devices");
350         assertThat(simPreference.getIcon()).isNotNull();
351         assertThat(simPreference.isChecked()).isTrue();
352     }
353 
354     @Test
verifyAccountPreference_newAccountAdded_accountAddedToAccountPreference()355     public void verifyAccountPreference_newAccountAdded_accountAddedToAccountPreference()
356             throws Exception {
357         Bundle currentDefaultAccount = new Bundle();
358         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
359                 DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
360         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT1.name);
361         currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT1.type);
362         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
363                 any())).thenReturn(currentDefaultAccount);
364         Bundle eligibleAccountBundle = new Bundle();
365         ArrayList<Account> eligibleAccounts = new ArrayList<>(
366                 List.of(TEST_ACCOUNT1, TEST_ACCOUNT2));
367         eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
368                 eligibleAccounts);
369         when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
370                 any())).thenReturn(eligibleAccountBundle);
371 
372         mContactsStorageSettings.onAccountsUpdate(null);
373 
374         // onAccountsUpdate should refresh the icon and layouts.
375         SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
376                 String.valueOf(TEST_ACCOUNT1.hashCode()));
377         assertThat(account1Preference.getTitle()).isEqualTo("Device & Google");
378         assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
379         assertThat(account1Preference.getIcon()).isNotNull();
380 
381         SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
382                 String.valueOf(TEST_ACCOUNT2.hashCode()));
383         assertThat(account2Preference.getTitle()).isEqualTo("Device & Samsung");
384         assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
385         assertThat(account2Preference.getIcon()).isNotNull();
386     }
387 
388     @Test
searchIndexProvider_shouldIndexResource()389     public void searchIndexProvider_shouldIndexResource() {
390         final List<SearchIndexableResource> indexRes =
391                 ContactsStorageSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
392                         RuntimeEnvironment.application, true /* enabled */);
393 
394         assertThat(indexRes).isNotNull();
395         assertThat(indexRes.get(0).xmlResId).isEqualTo(
396                 mContactsStorageSettings.getPreferenceScreenResId());
397     }
398 
399     private static class TestContactsStorageSettings extends ContactsStorageSettings {
400         private final Context mContext;
401         private final ContentResolver mContentResolver;
402         private String[] mEligibleAccountTypes;
403 
TestContactsStorageSettings(Context context, ContentResolver contentResolver)404         TestContactsStorageSettings(Context context, ContentResolver contentResolver) {
405             mContext = context;
406             mContentResolver = contentResolver;
407         }
408 
409         @Override
getContext()410         public Context getContext() {
411             return mContext;
412         }
413 
414         @Override
getContentResolver()415         protected ContentResolver getContentResolver() {
416             // Override it so we can access this method in test
417             return mContentResolver;
418         }
419 
420         @Override
getEligibleAccountTypes()421         String[] getEligibleAccountTypes() {
422             return mEligibleAccountTypes == null ? Resources.getSystem().getStringArray(
423                     com.android.internal.R.array.config_rawContactsEligibleDefaultAccountTypes)
424                     : mEligibleAccountTypes;
425         }
426 
setEligibleAccountTypes(String[] eligibleAccountTypes)427         public void setEligibleAccountTypes(String[] eligibleAccountTypes) {
428             mEligibleAccountTypes = eligibleAccountTypes;
429         }
430     }
431 
432     @Implements(AuthenticatorHelper.class)
433     public static class ShadowAuthenticatorHelper {
434 
435         boolean preloadDrawableForType = false;
436 
437         @Implementation
listenToAccountUpdates()438         public void listenToAccountUpdates() {
439         }
440 
441         @Implementation
onAccountsUpdated(Account[] accounts)442         public void onAccountsUpdated(Account[] accounts) {
443 
444         }
445         @Implementation
preloadDrawableForType(final Context context, final String accountType)446         public void preloadDrawableForType(final Context context, final String accountType) {
447             preloadDrawableForType = true;
448         }
449 
450         @Implementation
getDrawableForType(Context context, final String accountType)451         protected Drawable getDrawableForType(Context context, final String accountType) {
452             if (preloadDrawableForType) {
453                 return context.getPackageManager().getDefaultActivityIcon();
454             }
455             return null;
456         }
457 
458         @Implementation
getLabelForType(Context context, final String accountType)459         protected CharSequence getLabelForType(Context context, final String accountType) {
460             if (TextUtils.equals(accountType, "com.google")) {
461                 return "Google";
462             } else if (TextUtils.equals(accountType, "com.samsung")) {
463                 return "Samsung";
464             } else if (TextUtils.equals(accountType, "com.outlook")) {
465                 return "Outlook";
466             }
467             return null;
468         }
469     }
470 }
471