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

Commit a4277fd3 authored by Tingting Wang's avatar Tingting Wang Committed by Android (Google) Code Review
Browse files

Merge "Add turn on/off setting for Lychee in Contacts App." into ub-contactsdialer-b-dev

parents 40a8c9ac 3571ced3
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.contacts.common.preference;

import android.app.AlertDialog;
import android.content.Context;
import android.preference.ListPreference;
import android.util.AttributeSet;

import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountTypeWithDataSet;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.model.account.GoogleAccountType;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ContactMetadataSyncAccountPreference extends ListPreference {
    private ContactsPreferences mPreferences;
    private Map<String, AccountWithDataSet> mAccountMap;

    public ContactMetadataSyncAccountPreference(Context context) {
        super(context);
        prepare();
    }

    public ContactMetadataSyncAccountPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        prepare();
    }

    private void prepare() {
        mPreferences = new ContactsPreferences(getContext());
        mAccountMap = new HashMap<>();
        final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(getContext());
        List<AccountWithDataSet> accounts = accountTypeManager.getAccounts(true);
        mAccountMap.put(ContactsPreferences.DO_NOT_SYNC_CONTACT_METADATA_MSG, null);
        for (AccountWithDataSet account : accounts) {
            if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type) && account.dataSet == null) {
                mAccountMap.put(account.name, account);
            }
        }
        final Set<String> accountNames = mAccountMap.keySet();
        final String[] accountNamesArray = accountNames.toArray(new String[accountNames.size()]);
        setEntries(accountNamesArray);
        setEntryValues(accountNamesArray);
        setValue(mPreferences.getContactMetadataSyncAccount());
    }

    @Override
    protected boolean shouldPersist() {
        return false;   // This preference takes care of its own storage
    }

    @Override
    public CharSequence getSummary() {
        return mPreferences.getContactMetadataSyncAccount();
    }

    @Override
    protected boolean persistString(String value) {
        if (value == null && mPreferences.getContactMetadataSyncAccount() == null) {
            return true;
        }
        if (value == null || mPreferences.getContactMetadataSyncAccount() == null
                || !value.equals(mPreferences.getContactMetadataSyncAccount())) {
            mPreferences.setContactMetadataSyncAccount(mAccountMap.get(value));
            notifyChanged();
        }
        return true;
    }

    @Override
    // UX recommendation is not to show cancel button on such lists.
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
        super.onPrepareDialogBuilder(builder);
        builder.setNegativeButton(null, null);
    }
}
+88 −0
Original line number Diff line number Diff line
@@ -16,18 +16,28 @@

package com.android.contacts.common.preference;

import android.accounts.Account;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;

import com.android.contacts.common.R;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.model.account.GoogleAccountType;
import com.android.contacts.common.model.AccountTypeManager;

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

/**
 * Manages user preferences for contacts.
@@ -62,6 +72,10 @@ public final class ContactsPreferences implements OnSharedPreferenceChangeListen

    public static final boolean PREF_DISPLAY_ONLY_PHONES_DEFAULT = false;

    public static final String DO_NOT_SYNC_CONTACT_METADATA_MSG = "Do not sync contact metadata.";

    public static final String CONTACT_METADATA_AUTHORITY = "com.android.contacts.metadata";

    /**
     * Value to use when a preference is unassigned and needs to be read from the shared preferences
     */
@@ -179,6 +193,80 @@ public final class ContactsPreferences implements OnSharedPreferenceChangeListen
        editor.commit();
    }

    public String getContactMetadataSyncAccount() {
        for (Account account : getFocusGoogleAccounts()) {
            if (ContentResolver.getIsSyncable(account, CONTACT_METADATA_AUTHORITY) == 1
                    && ContentResolver.getSyncAutomatically(account, CONTACT_METADATA_AUTHORITY)) {
                return account.name;
            }
        }
        return DO_NOT_SYNC_CONTACT_METADATA_MSG;
    }

    public void setContactMetadataSyncAccount(AccountWithDataSet accountWithDataSet) {
        final String mContactMetadataSyncAccount =
                accountWithDataSet == null ? null : accountWithDataSet.name;
        toggleContactMetadata(mContactMetadataSyncAccount);
    }

    private void toggleContactMetadata(String syncAccount) {
        mContext.getContentResolver().delete(getMetadataSyncUri(), null, null);
        mContext.getContentResolver().delete(getMetadataSyncStateUri(), null, null);
        requestMetadataSyncForAccount(syncAccount);
    }

    /**
     * Turn on contact metadata sync for this {@param accountName} and turn off automatic sync
     * for other accounts. If accountName is null, then turn off automatic sync for all accounts.
     */
    private void requestMetadataSyncForAccount(String accountName) {
        for (Account account : getFocusGoogleAccounts()) {
            if (!TextUtils.isEmpty(accountName) && accountName.equals(account.name)) {
                ContentResolver.setIsSyncable(account, CONTACT_METADATA_AUTHORITY, 1 /*syncable*/);
                ContentResolver.setSyncAutomatically(account, CONTACT_METADATA_AUTHORITY, true);

                // Request sync.
                final Bundle b = new Bundle();
                b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
                ContentResolver.requestSync(account, CONTACT_METADATA_AUTHORITY, b);
            } else {
                // Turn off automatic sync for all other accounts.
                ContentResolver.setSyncAutomatically(account, CONTACT_METADATA_AUTHORITY, false);
            }
        }
    }

    /**
     * @return google accounts with "com.google" account type and null data set.
     */
    private List<Account> getFocusGoogleAccounts() {
        List<Account> focusGoogleAccounts = new ArrayList<Account>();
        final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(mContext);
        List<AccountWithDataSet> accounts = accountTypeManager.getAccounts(true);
        for (AccountWithDataSet account : accounts) {
            if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type) && account.dataSet == null) {
                focusGoogleAccounts.add(account.getAccountOrNull());
            }
        }
        return focusGoogleAccounts;
    }

    private static Uri getMetadataSyncUri() {
        final Uri metadataUri = Uri.parse("content://" + CONTACT_METADATA_AUTHORITY);
        return metadataUri.buildUpon()
                .appendPath("metadata_sync")
                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                .build();
    }

    private static Uri getMetadataSyncStateUri() {
        final Uri metadataUri = Uri.parse("content://" + CONTACT_METADATA_AUTHORITY);
        return metadataUri.buildUpon()
                .appendPath("metadata_sync_state")
                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                .build();
    }

    public void registerChangeListener(ChangeListener listener) {
        if (mListener != null) unregisterChangeListener();

+5 −0
Original line number Diff line number Diff line
@@ -54,6 +54,11 @@ public class DisplayOptionsPreferenceFragment extends PreferenceFragment {
            preferenceScreen.removePreference((ListPreference) findPreference("accounts"));
        }

        // STOPSHIP Show this option when 1) metadata sync is enabled and 2) at least one
        // focus google account.
        final PreferenceScreen preferenceScreen = getPreferenceScreen();
        preferenceScreen.removePreference((ListPreference) findPreference("contactMetadata"));

        // Set build version of Contacts App.
        final PackageManager manager = getActivity().getPackageManager();
        try {