Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7668f4d authored by Dongzhuo Zhang's avatar Dongzhuo Zhang Committed by Android (Google) Code Review
Browse files

Merge "Add OnAccountsUpdateListener in ContactsStorageSettings to refresh the...

Merge "Add OnAccountsUpdateListener in ContactsStorageSettings to refresh the account when there's account change." into main
parents 0d585fc4 ffe54b4f
Loading
Loading
Loading
Loading
+28 −10
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
@@ -58,7 +57,8 @@ import java.util.Map;
 */
@SearchIndexable
public class ContactsStorageSettings extends DashboardFragment
        implements SelectorWithWidgetPreference.OnClickListener, OnPreferenceClickListener {
        implements SelectorWithWidgetPreference.OnClickListener, OnPreferenceClickListener,
        AuthenticatorHelper.OnAccountsUpdateListener {
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.contacts_storage_settings);
    private static final String TAG = "ContactsStorageSettings";
@@ -72,13 +72,15 @@ public class ContactsStorageSettings extends DashboardFragment
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mAuthenticatorHelper = new AuthenticatorHelper(context,
                new UserHandle(UserHandle.myUserId()), null);
        String[] accountTypes = getEligibleAccountTypes();
        for (String accountType : accountTypes) {
            // Preload the drawable for the account type to avoid the latency when rendering the
            // account preference.
            mAuthenticatorHelper.preloadDrawableForType(context, accountType);
                new UserHandle(UserHandle.myUserId()), this);
        mAuthenticatorHelper.listenToAccountUpdates();
        preloadEligibleAccountIcon();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mAuthenticatorHelper.stopListeningToAccountUpdates();
    }

    @UiThread
@@ -126,6 +128,12 @@ public class ContactsStorageSettings extends DashboardFragment
        return false;
    }

    @Override
    public void onAccountsUpdate(UserHandle userHandle) {
        preloadEligibleAccountIcon();
        refreshUI();
    }

    @Override
    public void onCreatePreferences(@NonNull Bundle savedInstanceState,
            @NonNull String rootKey) {
@@ -139,6 +147,7 @@ public class ContactsStorageSettings extends DashboardFragment
        // when creating eligible account preferences.
        mAccountMap.clear();
        final PreferenceGroup preferenceGroup = findPreference(PREF_KEY_ACCOUNT_CATEGORY);
        preferenceGroup.removeAll();
        // If the default account is SIM, we should show in the page, otherwise don't show.
        SelectorWithWidgetPreference simAccountPreference = buildSimAccountPreference();
        if (simAccountPreference != null) {
@@ -152,12 +161,21 @@ public class ContactsStorageSettings extends DashboardFragment
        // If there's no eligible account types, the "Add Account" preference should
        // not be shown to the users.
        if (getEligibleAccountTypes().length > 0) {
            getPreferenceScreen().addPreference(buildAddAccountPreference(accounts.isEmpty()));
            preferenceGroup.addPreference(buildAddAccountPreference(accounts.isEmpty()));
        }
        setupDeviceOnlyPreference();
        setDefaultAccountPreference(preferenceGroup);
    }

    private void preloadEligibleAccountIcon() {
        String[] accountTypes = getEligibleAccountTypes();
        for (String accountType : accountTypes) {
            // Preload the drawable for the account type to avoid the latency when rendering the
            // account preference.
            mAuthenticatorHelper.preloadDrawableForType(getContext(), accountType);
        }
    }

    private void setupDeviceOnlyPreference() {
        SelectorWithWidgetPreference preference = findPreference(PREF_KEY_DEVICE_ONLY);
        if (preference != null) {
+92 −13
Original line number Diff line number Diff line
@@ -38,10 +38,13 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;

import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
@@ -51,7 +54,7 @@ import androidx.test.core.app.ApplicationProvider;

import com.android.settings.R;
import com.android.settings.accounts.AddAccountSettings;
import com.android.settings.testutils.shadow.ShadowAuthenticationHelper;
import com.android.settingslib.accounts.AuthenticatorHelper;
import com.android.settingslib.widget.SelectorWithWidgetPreference;

import org.junit.Before;
@@ -66,22 +69,24 @@ import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import java.util.ArrayList;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowAuthenticationHelper.class)
@Config(shadows = ContactsStorageSettingsTest.ShadowAuthenticatorHelper.class)
public class ContactsStorageSettingsTest {
    private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
    private static final String PREF_KEY_ACCOUNT_CATEGORY = "account_category";
    private static final String PREF_KEY_ADD_ACCOUNT = "add_account";

    private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "type1");
    private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "com.google");

    private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "type2");
    private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "com.samsung");

    private static final Account TEST_ACCOUNT3 = new Account("test@outlook.com", "type3");
    private static final Account TEST_ACCOUNT3 = new Account("test@outlook.com", "com.outlook");

    private static final Account SIM_ACCOUNT = new Account("SIM", "SIM");

@@ -100,7 +105,8 @@ public class ContactsStorageSettingsTest {

    @Before
    public void setUp() throws Exception {
        mContactsStorageSettings = spy(new TestContactsStorageSettings(mContext, mContentResolver));
        mContactsStorageSettings = spy(
                new TestContactsStorageSettings(mContext, mContentResolver));
        when(mContentResolver.acquireContentProviderClient(
                eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient);
        mPreferenceManager = new PreferenceManager(mContext);
@@ -116,6 +122,7 @@ public class ContactsStorageSettingsTest {
        when(mContactsStorageSettings.findPreference(eq(PREF_KEY_ACCOUNT_CATEGORY))).thenReturn(
                accountCategory);
        when(mContactsStorageSettings.getPreferenceScreen()).thenReturn(mScreen);
        mContactsStorageSettings.setEligibleAccountTypes(new String[]{"com.google"});
        mContactsStorageSettings.onAttach(mContext);
    }

@@ -179,7 +186,6 @@ public class ContactsStorageSettingsTest {
                new ArrayList<>());
        when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
                any())).thenReturn(eligibleAccountBundle);
        mContactsStorageSettings.setEligibleAccountTypes(new String[]{"com.google"});

        mContactsStorageSettings.refreshUI();

@@ -244,13 +250,13 @@ public class ContactsStorageSettingsTest {

        SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT1.hashCode()));
        assertThat(account1Preference.getTitle()).isEqualTo("Device and LABEL1");
        assertThat(account1Preference.getTitle()).isEqualTo("Device and Google");
        assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
        assertThat(account1Preference.getIcon()).isNotNull();

        SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT2.hashCode()));
        assertThat(account2Preference.getTitle()).isEqualTo("Device and LABEL2");
        assertThat(account2Preference.getTitle()).isEqualTo("Device and Samsung");
        assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
        assertThat(account2Preference.getIcon()).isNotNull();

@@ -265,7 +271,7 @@ public class ContactsStorageSettingsTest {
        assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_NAME)).isEqualTo(
                "test@samsung.com");
        assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_TYPE)).isEqualTo(
                "type2");
                "com.samsung");

        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).startActivity(intentCaptor.capture());
@@ -298,19 +304,19 @@ public class ContactsStorageSettingsTest {

        SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT1.hashCode()));
        assertThat(account1Preference.getTitle()).isEqualTo("Device and LABEL1");
        assertThat(account1Preference.getTitle()).isEqualTo("Device and Google");
        assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
        assertThat(account1Preference.getIcon()).isNotNull();

        SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT2.hashCode()));
        assertThat(account2Preference.getTitle()).isEqualTo("Device and LABEL2");
        assertThat(account2Preference.getTitle()).isEqualTo("Device and Samsung");
        assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
        assertThat(account2Preference.getIcon()).isNotNull();

        SelectorWithWidgetPreference account3Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT3.hashCode()));
        assertThat(account3Preference.getTitle()).isEqualTo("Device and LABEL3");
        assertThat(account3Preference.getTitle()).isEqualTo("Device and Outlook");
        assertThat(account3Preference.getSummary()).isEqualTo("test@outlook.com");
        assertThat(account3Preference.getIcon()).isNotNull();

@@ -345,6 +351,40 @@ public class ContactsStorageSettingsTest {
        assertThat(simPreference.isChecked()).isTrue();
    }

    @Test
    public void verifyAccountPreference_newAccountAdded_accountAddedToAccountPreference()
            throws Exception {
        Bundle currentDefaultAccount = new Bundle();
        currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
                DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT1.name);
        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT1.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.onAccountsUpdate(null);

        // onAccountsUpdate should refresh the icon and layouts.
        SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT1.hashCode()));
        assertThat(account1Preference.getTitle()).isEqualTo("Device and Google");
        assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
        assertThat(account1Preference.getIcon()).isNotNull();

        SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
                String.valueOf(TEST_ACCOUNT2.hashCode()));
        assertThat(account2Preference.getTitle()).isEqualTo("Device and Samsung");
        assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
        assertThat(account2Preference.getIcon()).isNotNull();
    }

    @Test
    public void searchIndexProvider_shouldIndexResource() {
        final List<SearchIndexableResource> indexRes =
@@ -388,4 +428,43 @@ public class ContactsStorageSettingsTest {
            mEligibleAccountTypes = eligibleAccountTypes;
        }
    }

    @Implements(AuthenticatorHelper.class)
    public static class ShadowAuthenticatorHelper {

        boolean preloadDrawableForType = false;

        @Implementation
        public void listenToAccountUpdates() {
        }

        @Implementation
        public void onAccountsUpdated(Account[] accounts) {

        }
        @Implementation
        public void preloadDrawableForType(final Context context, final String accountType) {
            preloadDrawableForType = true;
        }

        @Implementation
        protected Drawable getDrawableForType(Context context, final String accountType) {
            if (preloadDrawableForType) {
                return context.getPackageManager().getDefaultActivityIcon();
            }
            return null;
        }

        @Implementation
        protected CharSequence getLabelForType(Context context, final String accountType) {
            if (TextUtils.equals(accountType, "com.google")) {
                return "Google";
            } else if (TextUtils.equals(accountType, "com.samsung")) {
                return "Samsung";
            } else if (TextUtils.equals(accountType, "com.outlook")) {
                return "Outlook";
            }
            return null;
        }
    }
}