Swtich to use DefaultAccount related API to get and set default account for handling contacts.
Test: atest SettingsRoboTests:com.android.settings.applications.contacts.ContactsStorageSettingsTest atest SettingsRoboTests:com.android.settings.applications.contacts.ContactsStoragePreferenceControllerTest Bug: 368641291 Flag: com.android.settings.flags.enable_contacts_default_account_in_settings Change-Id: I1164c120881714d051a6acc34e75d2b5de0f01b5
This commit is contained in:
@@ -3324,27 +3324,27 @@
|
||||
|
||||
<!-- Dialog body informing user about an unmountable storage device. [CHAR LIMIT=NONE]-->
|
||||
<string name="storage_dialog_unmountable">This <xliff:g id="name" example="SD card">^1</xliff:g> is corrupted.
|
||||
\n\nTo use this <xliff:g id="name" example="SD card">^1</xliff:g>, you have to set it up first.</string>
|
||||
\n\nTo use this <xliff:g id="name" example="SD card">^1</xliff:g>, you have to set it up first.</string>
|
||||
|
||||
<!-- Body of dialog informing user about consequences of formatting an internal storage device [CHAR LIMIT=NONE]-->
|
||||
<string name="storage_internal_format_details">You can format this SD card to store photos, videos, music,
|
||||
and more and access them on other devices.
|
||||
\n\n<b>All data on this SD card will be erased.</b>
|
||||
\n\n<b>Before formatting</b>
|
||||
\n\n<b>Back up photos & other media</b>
|
||||
\nMove your media files to alternative storage on this device, or transfer them to a computer using a USB cable.
|
||||
\n\n<b>Back up apps</b>
|
||||
\nAll apps stored on this <xliff:g id="name" example="SD card">^1</xliff:g> will be uninstalled and their data will be erased. To keep these apps, move them to alternative storage on this device.</string>
|
||||
\n\n<b>Back up photos & other media</b>
|
||||
\nMove your media files to alternative storage on this device, or transfer them to a computer using a USB cable.
|
||||
\n\n<b>Back up apps</b>
|
||||
\nAll apps stored on this <xliff:g id="name" example="SD card">^1</xliff:g> will be uninstalled and their data will be erased. To keep these apps, move them to alternative storage on this device.</string>
|
||||
|
||||
<!-- Body of dialog informing user about consequences of ejecting an internal storage device [CHAR LIMIT=NONE]-->
|
||||
<string name="storage_internal_unmount_details"><b>When you eject this <xliff:g id="name" example="SD card">^1</xliff:g>, apps stored on it will stop working, and media files stored on it will not be available until it is reinserted.</b>
|
||||
\n\nThis <xliff:g id="name" example="SD card">^1</xliff:g> is formatted to work on this device only. It won\u2019t work on any others.</string>
|
||||
\n\nThis <xliff:g id="name" example="SD card">^1</xliff:g> is formatted to work on this device only. It won\u2019t work on any others.</string>
|
||||
|
||||
<!-- Body of dialog informing user about consequences of forgetting an internal storage device [CHAR LIMIT=NONE]-->
|
||||
<string name="storage_internal_forget_details">To use the apps, photos, or data this <xliff:g id="name" example="SD card">^1</xliff:g> contains, reinsert it.
|
||||
\n\nAlternatively, you can choose to forget this storage if the device isn\u2019t available.
|
||||
\n\nIf you choose to forget, all the data the device contains will be lost forever.
|
||||
\n\nYou can reinstall the apps later, but their data stored on this device will be lost.</string>
|
||||
\n\nAlternatively, you can choose to forget this storage if the device isn\u2019t available.
|
||||
\n\nIf you choose to forget, all the data the device contains will be lost forever.
|
||||
\n\nYou can reinstall the apps later, but their data stored on this device will be lost.</string>
|
||||
|
||||
<!-- Title of dialog confirming that user wants to forget an internal storage device [CHAR LIMIT=32]-->
|
||||
<string name="storage_internal_forget_confirm_title">Forget <xliff:g id="name" example="SD card">^1</xliff:g>?</string>
|
||||
@@ -3378,7 +3378,7 @@
|
||||
<string name="storage_wizard_move_confirm_title">Move <xliff:g id="app" example="Calculator">^1</xliff:g></string>
|
||||
<!-- Body of wizard step prompting user to move an app [CHAR LIMIT=NONE] -->
|
||||
<string name="storage_wizard_move_confirm_body">Moving <xliff:g id="app" example="Calculator">^1</xliff:g> and its data to <xliff:g id="name" example="SD card">^2</xliff:g> will take only a few moments. You won\u2019t be able to use the app until the move is complete.
|
||||
\n\nDon\u2019t remove the <xliff:g id="name" example="SD card">^2</xliff:g> during the move.
|
||||
\n\nDon\u2019t remove the <xliff:g id="name" example="SD card">^2</xliff:g> during the move.
|
||||
</string>
|
||||
|
||||
<!-- Body of lock screen challenge message explaining that the given user must be unlocked before data can be moved [CHAR LIMIT=64] -->
|
||||
@@ -3388,7 +3388,7 @@
|
||||
<string name="storage_wizard_move_progress_title">Moving <xliff:g id="app" example="Calculator">^1</xliff:g>\u2026</string>
|
||||
<!-- Body of wizard step showing app move progress [CHAR LIMIT=NONE] -->
|
||||
<string name="storage_wizard_move_progress_body">Don\u2019t remove the <xliff:g id="name" example="SD card">^1</xliff:g> during the move.
|
||||
\n\nThe <xliff:g id="app" example="Calculator">^2</xliff:g> app on this device won\u2019t be available until the move is complete.
|
||||
\n\nThe <xliff:g id="app" example="Calculator">^2</xliff:g> app on this device won\u2019t be available until the move is complete.
|
||||
</string>
|
||||
|
||||
<!-- This is the title of a full-screen message. After this question, the user will get to choose how they want to use the storage device that they have in their phone. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
|
||||
@@ -3408,7 +3408,7 @@
|
||||
<string name="storage_wizard_format_confirm_v2_title">Format this <xliff:g id="name" example="SD card">^1</xliff:g>?</string>
|
||||
<!-- Body of a dialog. This text is confirming that the user wants to use their SD card as extra phone storage, but the formatting process will erase existing content on the card. The first placeholder is for the name of the device (e.g. a brand name of the SD card or USB drive). The second and third placeholders are for the general references (e.g. SD card, USB drive). [CHAR LIMIT=NONE] -->
|
||||
<string name="storage_wizard_format_confirm_v2_body">This <xliff:g id="name" example="SanDisk SD card">^1</xliff:g> needs to be formatted to store apps, files, and media.
|
||||
\n\nFormatting will erase existing content on the <xliff:g id="name" example="SD card">^2</xliff:g>. To avoid losing content, back it up to another <xliff:g id="name" example="SD card">^3</xliff:g> or device.</string>
|
||||
\n\nFormatting will erase existing content on the <xliff:g id="name" example="SD card">^2</xliff:g>. To avoid losing content, back it up to another <xliff:g id="name" example="SD card">^3</xliff:g> or device.</string>
|
||||
<!-- Body of a dialog. This text is confirming that the user wants to use their SD card as portable storage, but the formatting process will erase existing content on the card. The first placeholder is for the name of the device (e.g. a brand name of the SD card or USB drive). The second and third placeholders are for the general references (e.g. SD card, USB drive). [CHAR LIMIT=NONE] -->
|
||||
<string name="storage_wizard_format_confirm_v2_body_external">This <xliff:g id="name" example="SanDisk SD card">^1</xliff:g> needs to be formatted to store photos, videos, music, and more.
|
||||
\n\nFormatting will erase existing content on the <xliff:g id="name" example="SD card">^2</xliff:g>. To avoid losing content, back it up to another <xliff:g id="name" example="SD card">^3</xliff:g> or device.</string>
|
||||
@@ -3437,8 +3437,8 @@
|
||||
<string name="storage_wizard_slow_v2_title">Slow <xliff:g id="name" example="SD card">^1</xliff:g></string>
|
||||
<!-- Strings that are part of a full-screen message. These strings let the user know that their storage device is slow, and include some options they can try. The first placeholder is for the name of the storage device (e.g. brand name of the SD card), and the second and third placeholders are for the general references (e.g. SD card, USB drive, etc.). [CHAR LIMIT=NONE] -->
|
||||
<string name="storage_wizard_slow_v2_body">You can still use this <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>, but it may be slow.
|
||||
\n\nApps stored on this <xliff:g id="name" example="SD card">^2</xliff:g> may not work properly, and content transfers could take a long time.
|
||||
\n\nTry using a faster <xliff:g id="name" example="SD card">^3</xliff:g>, or use this <xliff:g id="name" example="SD card">^4</xliff:g> for portable storage instead.</string>
|
||||
\n\nApps stored on this <xliff:g id="name" example="SD card">^2</xliff:g> may not work properly, and content transfers could take a long time.
|
||||
\n\nTry using a faster <xliff:g id="name" example="SD card">^3</xliff:g>, or use this <xliff:g id="name" example="SD card">^4</xliff:g> for portable storage instead.</string>
|
||||
<!-- Action of a dialog. This action will start the wizard from the beginning, letting the user make an alternative choice. [CHAR LIMIT=32] -->
|
||||
<string name="storage_wizard_slow_v2_start_over">Start over</string>
|
||||
<!-- Action of a dialog. This action will continue the wizard, meaning the user acknowledges their card is slow. [CHAR LIMIT=32] -->
|
||||
@@ -13729,8 +13729,12 @@
|
||||
<string name="contacts_storage_device_only_preference_summary">New contacts won\'t be synced with an account</string>
|
||||
<!-- Text for explaining the selection in Contacts Storage Settings [CHAR LIMIT=NONE] -->
|
||||
<string name="contacts_storage_selection_message">Contacts will be saved to your device and synced to your account by default</string>
|
||||
<!-- Text for error toast when there's error setting the default account in Contacts Storage Settings [CHAR LIMIT=NONE] -->
|
||||
<string name="contacts_storage_set_default_account_error_message">Error setting the default account</string>
|
||||
<!-- Text for displaying when no account is set as default account [CHAR LIMIT=50] -->
|
||||
<string name="contacts_storage_no_account_set">No default set</string>
|
||||
<string name="contacts_storage_no_account_set_summary">No default set</string>
|
||||
<!-- Text for displaying when default account is set as local only [CHAR LIMIT=50] -->
|
||||
<string name="contacts_storage_local_account_summary">Device only</string>
|
||||
<!-- Text for add account selection message when no account has been added [CHAR LIMIT=100] -->
|
||||
<string name="contacts_storage_first_time_add_account_message">Add an account to get started</string>
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
@@ -16,12 +15,13 @@
|
||||
*/
|
||||
package com.android.settings.applications.contacts;
|
||||
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.ContactsContract;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -36,33 +36,53 @@ public class ContactsStoragePreferenceController extends BasePreferenceControlle
|
||||
|
||||
private final AuthenticatorHelper mAuthenticatorHelper;
|
||||
|
||||
private DefaultAccountAndState mCurrentDefaultAccountAndState;
|
||||
|
||||
public ContactsStoragePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mAuthenticatorHelper = new AuthenticatorHelper(mContext,
|
||||
new UserHandle(UserHandle.myUserId()), null);
|
||||
try {
|
||||
mCurrentDefaultAccountAndState =
|
||||
DefaultAccount.getDefaultAccountForNewContacts(mContext.getContentResolver());
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(TAG, "The default account is in an invalid state: " + e);
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(TAG, "Failed to look up the default account: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return Flags.enableContactsDefaultAccountInSettings()
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
return (Flags.enableContactsDefaultAccountInSettings()
|
||||
&& mCurrentDefaultAccountAndState != null) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
Account currentDefaultAccount =
|
||||
ContactsContract.Settings.getDefaultAccount(mContext.getContentResolver());
|
||||
if (currentDefaultAccount == null) {
|
||||
if (mCurrentDefaultAccountAndState != null) {
|
||||
int currentDefaultAccountState = mCurrentDefaultAccountAndState.getState();
|
||||
Account currentDefaultAccount = mCurrentDefaultAccountAndState.getAccount();
|
||||
if (currentDefaultAccountState
|
||||
== DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET) {
|
||||
return mContext.getResources().getString(
|
||||
R.string.contacts_storage_no_account_set);
|
||||
}
|
||||
R.string.contacts_storage_no_account_set_summary);
|
||||
} else if (currentDefaultAccountState
|
||||
== DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL) {
|
||||
return mContext.getResources().getString(
|
||||
R.string.contacts_storage_local_account_summary);
|
||||
} else if (currentDefaultAccount != null) {
|
||||
String accountTypeLabel = (String) mAuthenticatorHelper.getLabelForType(mContext,
|
||||
currentDefaultAccount.type);
|
||||
// If there's no account type, or the account type is the same as the
|
||||
// current default account name, just return the account name.
|
||||
if (accountTypeLabel == null || accountTypeLabel.equals(currentDefaultAccount.name)) {
|
||||
if (accountTypeLabel == null || accountTypeLabel.equals(
|
||||
currentDefaultAccount.name)) {
|
||||
return currentDefaultAccount.name;
|
||||
}
|
||||
return accountTypeLabel + " | " + currentDefaultAccount.name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
@@ -17,25 +16,27 @@
|
||||
package com.android.settings.applications.contacts;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount;
|
||||
import static android.provider.Settings.ACTION_ADD_ACCOUNT;
|
||||
import static android.provider.Settings.EXTRA_ACCOUNT_TYPES;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.ContactsContract.Settings;
|
||||
|
||||
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accounts.AddAccountSettings;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
@@ -46,6 +47,7 @@ import com.android.settingslib.search.SearchIndexable;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -59,7 +61,7 @@ public class ContactsStorageSettings extends DashboardFragment
|
||||
private static final String TAG = "ContactsStorageSettings";
|
||||
private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
|
||||
private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
|
||||
private final Map<String, Account> mAccountMap = new HashMap<>();
|
||||
private final Map<String, DefaultAccountAndState> mAccountMap = new HashMap<>();
|
||||
private AuthenticatorHelper mAuthenticatorHelper;
|
||||
|
||||
@Override
|
||||
@@ -73,13 +75,18 @@ public class ContactsStorageSettings extends DashboardFragment
|
||||
@Override
|
||||
public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference selectedPref) {
|
||||
final String selectedPreferenceKey = selectedPref.getKey();
|
||||
// Check if current provider is different from the selected provider.
|
||||
// Check if current account is different from the selected account.
|
||||
for (String preferenceKey : mAccountMap.keySet()) {
|
||||
if (selectedPreferenceKey.equals(preferenceKey)) {
|
||||
try {
|
||||
DefaultAccount.setDefaultAccountForNewContacts(getContentResolver(),
|
||||
mAccountMap.get(preferenceKey));
|
||||
selectedPref.setChecked(true);
|
||||
//TODO: Call DefaultAccount.setDefaultAccountForNewContacts once
|
||||
// the implementation is ready.
|
||||
Settings.setDefaultAccount(getContentResolver(), mAccountMap.get(preferenceKey));
|
||||
} catch (RuntimeException e) {
|
||||
Toast.makeText(getContext(),
|
||||
R.string.contacts_storage_set_default_account_error_message,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else {
|
||||
SelectorWithWidgetPreference unSelectedPreference =
|
||||
getPreferenceScreen().findPreference(preferenceKey);
|
||||
@@ -92,10 +99,7 @@ public class ContactsStorageSettings extends DashboardFragment
|
||||
|
||||
public boolean onPreferenceClick(@NonNull Preference preference) {
|
||||
if (PREF_KEY_ADD_ACCOUNT.equals(preference.getKey())) {
|
||||
Resources resources = Resources.getSystem();
|
||||
String[] accountTypesArray =
|
||||
resources.getStringArray(
|
||||
com.android.internal.R.array.config_rawContactsEligibleDefaultAccountTypes);
|
||||
String[] accountTypesArray = getEligibleAccountTypes();
|
||||
Intent intent = new Intent(ACTION_ADD_ACCOUNT);
|
||||
intent.setClass(getContext(), AddAccountSettings.class);
|
||||
intent.putExtra(EXTRA_ACCOUNT_TYPES, accountTypesArray);
|
||||
@@ -119,48 +123,60 @@ public class ContactsStorageSettings extends DashboardFragment
|
||||
// when creating eligible account preferences.
|
||||
mAccountMap.clear();
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
AccountManager accountManager = AccountManager.get(getPrefContext());
|
||||
//TODO: Call DefaultAccount.getDefaultAccountForNewContacts once
|
||||
// implementation is ready.
|
||||
Account[] accounts = accountManager.getAccounts();
|
||||
|
||||
for (int i = 0; i < accounts.length; i++) {
|
||||
screen.addPreference(buildAccountPreference(accounts[i], i));
|
||||
List<Account> accounts = DefaultAccount.getEligibleCloudAccounts(getContentResolver());
|
||||
for (int i = 0; i < accounts.size(); i++) {
|
||||
screen.addPreference(buildAccountPreference(accounts.get(i), /*order=*/i));
|
||||
}
|
||||
// If there's no eligible account types, the "Add Account" preference should
|
||||
// not be shown to the users.
|
||||
if (getEligibleAccountTypes().length > 0) {
|
||||
screen.addPreference(buildAddAccountPreference(accounts.isEmpty()));
|
||||
}
|
||||
screen.addPreference(buildAddAccountPreference(accounts.length == 0));
|
||||
setupDeviceOnlyPreference();
|
||||
|
||||
//TODO: Call DefaultAccount.ListEligibleCloudAccounts once the
|
||||
// implementation is ready. And differentiate device only account vs account not set case.
|
||||
Account currentDefaultAccount = Settings.getDefaultAccount(getContentResolver());
|
||||
String preferenceKey = currentDefaultAccount != null ?
|
||||
String.valueOf(currentDefaultAccount.hashCode()) : PREF_KEY_DEVICE_ONLY;
|
||||
SelectorWithWidgetPreference preference = getPreferenceScreen().findPreference(
|
||||
preferenceKey);
|
||||
if (preference != null) {
|
||||
preference.setChecked(true);
|
||||
}
|
||||
setDefaultAccountPreference();
|
||||
}
|
||||
|
||||
private void setupDeviceOnlyPreference() {
|
||||
SelectorWithWidgetPreference preference = findPreference(PREF_KEY_DEVICE_ONLY);
|
||||
if (preference != null) {
|
||||
preference.setOnClickListener(this);
|
||||
mAccountMap.put(PREF_KEY_DEVICE_ONLY, null);
|
||||
mAccountMap.put(PREF_KEY_DEVICE_ONLY, DefaultAccountAndState.ofLocal());
|
||||
}
|
||||
}
|
||||
|
||||
private void setDefaultAccountPreference() {
|
||||
DefaultAccountAndState currentDefaultAccountAndState =
|
||||
DefaultAccount.getDefaultAccountForNewContacts(getContentResolver());
|
||||
String preferenceKey = getAccountHashCode(currentDefaultAccountAndState);
|
||||
Account currentDefaultAccount = currentDefaultAccountAndState.getAccount();
|
||||
|
||||
// Set the current default account preference to be checked if found among existing
|
||||
// preferences. If not, then create a new preference for default account.
|
||||
SelectorWithWidgetPreference preference = null;
|
||||
if (mAccountMap.containsKey(preferenceKey)) {
|
||||
preference = getPreferenceScreen().findPreference(preferenceKey);
|
||||
} else if (preferenceKey != null && currentDefaultAccount != null) {
|
||||
preference = buildAccountPreference(currentDefaultAccount, mAccountMap.size());
|
||||
getPreferenceScreen().addPreference(preference);
|
||||
}
|
||||
if (preference != null) {
|
||||
preference.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Add preference category on account preferences.
|
||||
private Preference buildAccountPreference(Account account, int order) {
|
||||
private SelectorWithWidgetPreference buildAccountPreference(Account account, int order) {
|
||||
SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(
|
||||
getPrefContext());
|
||||
DefaultAccountAndState accountAndState = DefaultAccountAndState.ofCloud(account);
|
||||
String preferenceKey = getAccountHashCode(accountAndState);
|
||||
preference.setTitle(mAuthenticatorHelper.getLabelForType(getPrefContext(), account.type));
|
||||
preference.setIcon(mAuthenticatorHelper.getDrawableForType(getPrefContext(), account.type));
|
||||
preference.setSummary(account.name);
|
||||
preference.setKey(String.valueOf(account.hashCode()));
|
||||
preference.setKey(preferenceKey);
|
||||
preference.setOnClickListener(this);
|
||||
preference.setOrder(order);
|
||||
mAccountMap.put(String.valueOf(account.hashCode()), account);
|
||||
mAccountMap.put(preferenceKey, accountAndState);
|
||||
return preference;
|
||||
}
|
||||
|
||||
@@ -178,6 +194,29 @@ public class ContactsStorageSettings extends DashboardFragment
|
||||
return preference;
|
||||
}
|
||||
|
||||
private @Nullable String getAccountHashCode(DefaultAccountAndState currentDefaultAccountAndState) {
|
||||
Account currentDefaultAccount = currentDefaultAccountAndState.getAccount();
|
||||
if (currentDefaultAccount != null && (currentDefaultAccountAndState.getState()
|
||||
== DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD
|
||||
|| currentDefaultAccountAndState.getState()
|
||||
== DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM)) {
|
||||
return String.valueOf(currentDefaultAccount.hashCode());
|
||||
} else if (currentDefaultAccountAndState.getState()
|
||||
== DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL) {
|
||||
return PREF_KEY_DEVICE_ONLY;
|
||||
} else {
|
||||
// If the account is not set or in error state, it should just return null and won't
|
||||
// set the checked status in radio button.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String[] getEligibleAccountTypes() {
|
||||
return Resources.getSystem().getStringArray(
|
||||
com.android.internal.R.array.config_rawContactsEligibleDefaultAccountTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.contacts_storage_settings;
|
||||
|
@@ -16,8 +16,9 @@
|
||||
|
||||
package com.android.settings.applications.contacts;
|
||||
|
||||
import static android.provider.ContactsContract.Settings.KEY_DEFAULT_ACCOUNT;
|
||||
import static android.provider.ContactsContract.Settings.QUERY_DEFAULT_ACCOUNT_METHOD;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.KEY_DEFAULT_ACCOUNT_STATE;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD;
|
||||
import static android.provider.ContactsContract.Settings;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
@@ -28,25 +29,26 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.testutils.shadow.ShadowAuthenticationHelper;
|
||||
|
||||
import org.junit.Before;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -62,11 +64,6 @@ public class ContactsStoragePreferenceControllerTest {
|
||||
|
||||
private static final String CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY =
|
||||
"contacts_default_account";
|
||||
private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "type1");
|
||||
|
||||
private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "type2");
|
||||
|
||||
private static final Account TEST_ACCOUNT3 = new Account("LABEL3", "type3");
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@@ -83,6 +80,9 @@ public class ContactsStoragePreferenceControllerTest {
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Mock
|
||||
private ContentProviderClient mContentProviderClient;
|
||||
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
|
||||
@@ -94,9 +94,15 @@ public class ContactsStoragePreferenceControllerTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
when(mContentResolver.acquireContentProviderClient(
|
||||
eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient);
|
||||
when(mContext.getSystemService(eq(Context.ACCOUNT_SERVICE))).thenReturn(mAccountManager);
|
||||
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[]{});
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(bundle);
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
}
|
||||
@@ -104,13 +110,39 @@ public class ContactsStoragePreferenceControllerTest {
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
|
||||
public void getAvailabilityStatus_flagIsOn_shouldReturnAvailable() {
|
||||
|
||||
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
|
||||
public void getAvailabilityStatus_flagIsOff_shouldReturnConditionallyUnavailable() {
|
||||
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(
|
||||
CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
|
||||
public void getAvailabilityStatus_illegalStateExceptionThrown_shouldReturnConditionallyUnavailable()
|
||||
throws Exception {
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenThrow(new IllegalStateException());
|
||||
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(
|
||||
CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
|
||||
public void getAvailabilityStatus_runtimeExceptionThrown_shouldReturnConditionallyUnavailable()
|
||||
throws Exception {
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenThrow(new RuntimeException());
|
||||
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(
|
||||
CONDITIONALLY_UNAVAILABLE);
|
||||
@@ -118,43 +150,77 @@ public class ContactsStoragePreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void getSummary_noAccountIsSetAsDefault_shouldReturnNoAccountSetSummary() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, null);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getString(eq(R.string.contacts_storage_no_account_set))).thenReturn(
|
||||
when(mResources.getString(eq(R.string.contacts_storage_no_account_set_summary))).thenReturn(
|
||||
"No default set");
|
||||
|
||||
// Fetch the default account from CP2.
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getSummary()).isEqualTo("No default set");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_googleAccountIsSetAsDefault_shouldReturnGoogleAccountTypeAndAccountName() {
|
||||
public void getSummary_localAccountIsSetAsDefault_shouldReturnLocalAccountSetSummary()
|
||||
throws Exception {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT1);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(bundle);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getString(eq(R.string.contacts_storage_local_account_summary))).thenReturn(
|
||||
"Device only");
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getSummary()).isEqualTo("Device only");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_googleAccountIsSetAsDefault_shouldReturnGoogleAccountTypeAndAccountName()
|
||||
throws Exception {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
|
||||
bundle.putString(Settings.ACCOUNT_TYPE, "type1");
|
||||
bundle.putString(Settings.ACCOUNT_NAME, "test@gmail.com");
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(bundle);
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL1 | test@gmail.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_samsungAccountIsSetAsDefault_shouldReturnSamsungAccountTypeAndAccountName() {
|
||||
public void getSummary_samsungAccountIsSetAsDefault_shouldReturnSamsungAccountTypeAndAccountName()
|
||||
throws Exception {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT2);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
|
||||
bundle.putString(Settings.ACCOUNT_TYPE, "type2");
|
||||
bundle.putString(Settings.ACCOUNT_NAME, "test@samsung.com");
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(bundle);
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL2 | test@samsung.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_accountLabelSameAsAccountName_onlyReturnAccountName() {
|
||||
public void getSummary_accountLabelSameAsAccountName_onlyReturnAccountName() throws Exception {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT3);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
|
||||
bundle.putString(Settings.ACCOUNT_TYPE, "type3");
|
||||
bundle.putString(Settings.ACCOUNT_NAME, "LABEL3");
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(bundle);
|
||||
mPreferenceController = new ContactsStoragePreferenceController(mContext,
|
||||
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
|
||||
|
||||
// Since package name and account name is the same, we only return account name.
|
||||
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL3");
|
||||
|
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package com.android.settings.applications.contacts;
|
||||
|
||||
import static android.provider.ContactsContract.Settings.KEY_DEFAULT_ACCOUNT;
|
||||
import static android.provider.ContactsContract.Settings.QUERY_DEFAULT_ACCOUNT_METHOD;
|
||||
import static android.provider.ContactsContract.Settings.SET_DEFAULT_ACCOUNT_METHOD;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.KEY_DEFAULT_ACCOUNT_STATE;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.KEY_ELIGIBLE_DEFAULT_ACCOUNTS;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD;
|
||||
import static android.provider.ContactsContract.RawContacts.DefaultAccount.SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD;
|
||||
import static android.provider.Settings.ACTION_ADD_ACCOUNT;
|
||||
import static android.provider.Settings.EXTRA_ACCOUNT_TYPES;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -33,14 +34,17 @@ import static org.mockito.Mockito.when;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@@ -63,6 +67,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -76,6 +81,8 @@ public class ContactsStorageSettingsTest {
|
||||
|
||||
private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "type2");
|
||||
|
||||
private static final Account TEST_ACCOUNT3 = new Account("test@outlook.com", "type3");
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Spy
|
||||
@@ -83,8 +90,7 @@ public class ContactsStorageSettingsTest {
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
@Mock
|
||||
private AccountManager mAccountManager;
|
||||
|
||||
private ContentProviderClient mContentProviderClient;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private TestContactsStorageSettings mContactsStorageSettings;
|
||||
private PreferenceScreen mScreen;
|
||||
@@ -92,8 +98,8 @@ public class ContactsStorageSettingsTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mContactsStorageSettings = spy(new TestContactsStorageSettings(mContext, mContentResolver));
|
||||
when(mContext.getSystemService(eq(Context.ACCOUNT_SERVICE))).thenReturn(mAccountManager);
|
||||
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[]{});
|
||||
when(mContentResolver.acquireContentProviderClient(
|
||||
eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
when(mContactsStorageSettings.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null));
|
||||
@@ -115,12 +121,17 @@ public class ContactsStorageSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyDeviceOnlyPreference_onClick_setDefaultAccountToNull() {
|
||||
when(mAccountManager.getAccounts()).thenReturn(new Account[]{});
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, null);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
public void verifyDeviceOnlyPreference_onClick_setDefaultAccountToNull() throws Exception {
|
||||
Bundle currentDefaultAccount = new Bundle();
|
||||
currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(currentDefaultAccount);
|
||||
Bundle eligibleAccountBundle = new Bundle();
|
||||
eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
|
||||
new ArrayList<>());
|
||||
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
|
||||
any())).thenReturn(eligibleAccountBundle);
|
||||
|
||||
PreferenceScreen settingScreen = mPreferenceManager.inflateFromResource(mContext,
|
||||
R.xml.contacts_storage_settings, mScreen);
|
||||
@@ -139,18 +150,27 @@ public class ContactsStorageSettingsTest {
|
||||
|
||||
assertThat(deviceOnlyPreference.isChecked()).isTrue();
|
||||
ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
|
||||
verify(mContentResolver).call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(SET_DEFAULT_ACCOUNT_METHOD), any(), captor.capture());
|
||||
verify(mContentProviderClient).call(eq(SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
captor.capture());
|
||||
Bundle accountBundle = captor.getValue();
|
||||
assertThat(accountBundle.getString(ContactsContract.Settings.ACCOUNT_NAME)).isNull();
|
||||
assertThat(accountBundle.getString(ContactsContract.Settings.ACCOUNT_TYPE)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyAddAccountPreference_onClick_startAddAccountActivity() {
|
||||
when(mAccountManager.getAccounts()).thenReturn(new Account[]{});
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(Bundle.EMPTY);
|
||||
public void verifyAddAccountPreference_eligibleAccountsAvailable_startAddAccountActivityOnClick()
|
||||
throws Exception {
|
||||
Bundle currentDefaultAccount = new Bundle();
|
||||
currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(currentDefaultAccount);
|
||||
Bundle eligibleAccountBundle = new Bundle();
|
||||
eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
|
||||
new ArrayList<>());
|
||||
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
|
||||
any())).thenReturn(eligibleAccountBundle);
|
||||
mContactsStorageSettings.setEligibleAccountTypes(new String[]{"com.google"});
|
||||
|
||||
mContactsStorageSettings.refreshUI();
|
||||
|
||||
@@ -167,16 +187,45 @@ public class ContactsStorageSettingsTest {
|
||||
assertThat(addAccountIntent.getComponent().getClassName()).isEqualTo(
|
||||
AddAccountSettings.class.getCanonicalName());
|
||||
String[] eligibleAccounts = (String[]) addAccountIntent.getExtra(EXTRA_ACCOUNT_TYPES);
|
||||
assertThat(eligibleAccounts).isEmpty();
|
||||
assertThat(List.of(eligibleAccounts)).containsExactly("com.google");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyEligibleAccountPreference_onClick_setSelectedDefaultAccount() {
|
||||
when(mAccountManager.getAccounts()).thenReturn(new Account[]{TEST_ACCOUNT1, TEST_ACCOUNT2});
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT2);
|
||||
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
|
||||
public void verifyAddAccountPreference_noEligibleAccountsAvailable_dontShowPreference()
|
||||
throws Exception {
|
||||
Bundle currentDefaultAccount = new Bundle();
|
||||
currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(currentDefaultAccount);
|
||||
Bundle eligibleAccountBundle = new Bundle();
|
||||
eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
|
||||
new ArrayList<>());
|
||||
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
|
||||
any())).thenReturn(eligibleAccountBundle);
|
||||
mContactsStorageSettings.setEligibleAccountTypes(new String[]{});
|
||||
|
||||
mContactsStorageSettings.refreshUI();
|
||||
|
||||
Preference addAccountPreference = mScreen.findPreference(PREF_KEY_ADD_ACCOUNT);
|
||||
assertThat(addAccountPreference).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyEligibleAccountPreference_onClick_setSelectedDefaultAccount()
|
||||
throws Exception {
|
||||
Bundle currentDefaultAccount = new Bundle();
|
||||
currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(currentDefaultAccount);
|
||||
Bundle eligibleAccountBundle = new Bundle();
|
||||
ArrayList<Account> eligibleAccounts = new ArrayList<>(
|
||||
List.of(TEST_ACCOUNT1, TEST_ACCOUNT2));
|
||||
eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
|
||||
eligibleAccounts);
|
||||
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
|
||||
any())).thenReturn(eligibleAccountBundle);
|
||||
|
||||
mContactsStorageSettings.refreshUI();
|
||||
|
||||
@@ -197,8 +246,8 @@ public class ContactsStorageSettingsTest {
|
||||
assertThat(account2Preference.isChecked()).isTrue();
|
||||
|
||||
ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
|
||||
verify(mContentResolver).call(eq(ContactsContract.AUTHORITY_URI),
|
||||
eq(SET_DEFAULT_ACCOUNT_METHOD), any(), captor.capture());
|
||||
verify(mContentProviderClient).call(eq(SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
captor.capture());
|
||||
Bundle setAccountBundle = captor.getValue();
|
||||
assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_NAME)).isEqualTo(
|
||||
"test@samsung.com");
|
||||
@@ -206,6 +255,49 @@ public class ContactsStorageSettingsTest {
|
||||
"type2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyAccountPreference_defaultAccountIsNotEligibleCloudAccount_createNewDefaultAccountPreference()
|
||||
throws Exception {
|
||||
Bundle currentDefaultAccount = new Bundle();
|
||||
currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
|
||||
DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
|
||||
currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT3.name);
|
||||
currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT3.type);
|
||||
when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
|
||||
any())).thenReturn(currentDefaultAccount);
|
||||
Bundle eligibleAccountBundle = new Bundle();
|
||||
ArrayList<Account> eligibleAccounts = new ArrayList<>(
|
||||
List.of(TEST_ACCOUNT1, TEST_ACCOUNT2));
|
||||
eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
|
||||
eligibleAccounts);
|
||||
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
|
||||
any())).thenReturn(eligibleAccountBundle);
|
||||
|
||||
mContactsStorageSettings.refreshUI();
|
||||
|
||||
SelectorWithWidgetPreference account1Preference = mScreen.findPreference(
|
||||
String.valueOf(TEST_ACCOUNT1.hashCode()));
|
||||
assertThat(account1Preference.getTitle()).isEqualTo("LABEL1");
|
||||
assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
|
||||
assertThat(account1Preference.getIcon()).isNotNull();
|
||||
|
||||
SelectorWithWidgetPreference account2Preference = mScreen.findPreference(
|
||||
String.valueOf(TEST_ACCOUNT2.hashCode()));
|
||||
assertThat(account2Preference.getTitle()).isEqualTo("LABEL2");
|
||||
assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
|
||||
assertThat(account2Preference.getIcon()).isNotNull();
|
||||
|
||||
SelectorWithWidgetPreference account3Preference = mScreen.findPreference(
|
||||
String.valueOf(TEST_ACCOUNT3.hashCode()));
|
||||
assertThat(account3Preference.getTitle()).isEqualTo("LABEL3");
|
||||
assertThat(account3Preference.getSummary()).isEqualTo("test@outlook.com");
|
||||
assertThat(account3Preference.getIcon()).isNotNull();
|
||||
|
||||
assertThat(account1Preference.isChecked()).isFalse();
|
||||
assertThat(account2Preference.isChecked()).isFalse();
|
||||
assertThat(account3Preference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchIndexProvider_shouldIndexResource() {
|
||||
final List<SearchIndexableResource> indexRes =
|
||||
@@ -220,6 +312,7 @@ public class ContactsStorageSettingsTest {
|
||||
private static class TestContactsStorageSettings extends ContactsStorageSettings {
|
||||
private final Context mContext;
|
||||
private final ContentResolver mContentResolver;
|
||||
private String[] mEligibleAccountTypes;
|
||||
|
||||
TestContactsStorageSettings(Context context, ContentResolver contentResolver) {
|
||||
mContext = context;
|
||||
@@ -236,5 +329,16 @@ public class ContactsStorageSettingsTest {
|
||||
// Override it so we can access this method in test
|
||||
return mContentResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
String[] getEligibleAccountTypes() {
|
||||
return mEligibleAccountTypes == null ? Resources.getSystem().getStringArray(
|
||||
com.android.internal.R.array.config_rawContactsEligibleDefaultAccountTypes)
|
||||
: mEligibleAccountTypes;
|
||||
}
|
||||
|
||||
public void setEligibleAccountTypes(String[] eligibleAccountTypes) {
|
||||
mEligibleAccountTypes = eligibleAccountTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user