Merge "Add turn on/off setting for Lychee in Contacts App." into ub-contactsdialer-b-dev
diff --git a/src/com/android/contacts/common/preference/ContactMetadataSyncAccountPreference.java b/src/com/android/contacts/common/preference/ContactMetadataSyncAccountPreference.java
new file mode 100644
index 0000000..37d45f5
--- /dev/null
+++ b/src/com/android/contacts/common/preference/ContactMetadataSyncAccountPreference.java
@@ -0,0 +1,96 @@
+/*
+ * 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);
+ }
+}
diff --git a/src/com/android/contacts/common/preference/ContactsPreferences.java b/src/com/android/contacts/common/preference/ContactsPreferences.java
index ca38af7..37448e3 100644
--- a/src/com/android/contacts/common/preference/ContactsPreferences.java
+++ b/src/com/android/contacts/common/preference/ContactsPreferences.java
@@ -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 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 @@
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();
diff --git a/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java b/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
index e143450..3a5c536 100644
--- a/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
+++ b/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
@@ -54,6 +54,11 @@
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 {