Loading src/com/android/contacts/common/preference/ContactMetadataSyncAccountPreference.java 0 → 100644 +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); } } src/com/android/contacts/common/preference/ContactsPreferences.java +88 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 */ Loading Loading @@ -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(); Loading src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java +5 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading
src/com/android/contacts/common/preference/ContactMetadataSyncAccountPreference.java 0 → 100644 +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); } }
src/com/android/contacts/common/preference/ContactsPreferences.java +88 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 */ Loading Loading @@ -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(); Loading
src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java +5 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading