Set up a sync preference and policy for syncing [2]

- Adds a preference for enabling sync, which controls the sync behavior
- Make the ProductionFlags depend on appropriate flags to guarantee that
  we don't mess things when flipping some flags
- Preferences now control the "syncable" property of the provider
  thereby controlling the policy and when this entry shows up in
  system settings.

Bug: 17464069
Change-Id: I1d58351188518c1ae9f1f9e147b5ea15d32a3427
main
Sandeep Siddhartha 2014-10-09 16:41:25 -07:00
parent 1e10d29bc8
commit d9015233f5
8 changed files with 199 additions and 131 deletions

View File

@ -46,5 +46,5 @@ public final class ProductionFlags {
/** /**
* When {@code true}, personal dictionary sync feature is ready to be enabled. * When {@code true}, personal dictionary sync feature is ready to be enabled.
*/ */
public static final boolean ENABLE_PERSONAL_DICTIONARY_SYNC = false; public static final boolean ENABLE_PERSONAL_DICTIONARY_SYNC = ENABLE_ACCOUNT_SIGN_IN && false;
} }

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2014 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.inputmethod.latin.sync;
import android.content.Context;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.GuardedBy;
public class BeanstalkManager {
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static BeanstalkManager sInstance;
/**
* @return the singleton instance of {@link BeanstalkManager}.
*/
@Nonnull
public static BeanstalkManager getInstance(Context context) {
synchronized(sLock) {
if (sInstance == null) {
sInstance = new BeanstalkManager(context.getApplicationContext());
}
}
return sInstance;
}
private BeanstalkManager(final Context context) {
// Intentional private constructor for singleton.
}
public void onCreate() {
}
public void requestSync() {
}
public void onDestroy() {
}
}

View File

@ -56,9 +56,11 @@
<!-- Option for enabling or disabling the split keyboard layout. [CHAR LIMIT=65]--> <!-- Option for enabling or disabling the split keyboard layout. [CHAR LIMIT=65]-->
<string name="enable_split_keyboard">Enable split keyboard</string> <string name="enable_split_keyboard">Enable split keyboard</string>
<string name="sync_now_title" translatable="false">Sync Now</string> <!-- TODO: Enable translation for user-visible strings -->
<string name="sync_now_summary" translatable="false">Sync your personal dictionary</string> <string name="cloud_sync_title" translatable="false">Enable sync</string>
<string name="sync_now_summary_disabled_signed_out" translatable="false">Select an account to enable sync</string> <string name="cloud_sync_summary" translatable="false">Sync your personal dictionary across devices</string>
<string name="cloud_sync_summary_disabled_signed_out" translatable="false">Select an account to enable sync</string>
<string name="sync_now_title" translatable="false">[DEBUG] Sync Now</string>
<!-- Option name for including other IMEs in the language switch list [CHAR LIMIT=30] --> <!-- Option name for including other IMEs in the language switch list [CHAR LIMIT=30] -->
<string name="include_other_imes_in_language_switch_list">Switch to other input methods</string> <string name="include_other_imes_in_language_switch_list">Switch to other input methods</string>

View File

@ -28,7 +28,15 @@
android:title="@string/switch_accounts" android:title="@string/switch_accounts"
android:summary="@string/no_accounts_selected" /> android:summary="@string/no_accounts_selected" />
<!-- title will be set programmatically to embed application name --> <!-- Summary will be set programmatically to reflect the account status -->
<CheckBoxPreference
android:key="pref_enable_cloud_sync"
android:title="@string/cloud_sync_title"
android:defaultValue="false"
android:persistent="true"
android:disableDependentsState="false" />
<!-- Title will be set programmatically to embed application name -->
<CheckBoxPreference <CheckBoxPreference
android:key="pref_enable_metrics_logging" android:key="pref_enable_metrics_logging"
android:summary="@string/enable_metrics_logging_summary" android:summary="@string/enable_metrics_logging_summary"
@ -38,5 +46,6 @@
<!-- This preference (acts like a button) enables the user to initiate an one time sync. --> <!-- This preference (acts like a button) enables the user to initiate an one time sync. -->
<Preference android:key="pref_beanstalk" <Preference android:key="pref_beanstalk"
android:persistent="false" android:persistent="false"
android:title="@string/sync_now_title" /> android:title="@string/sync_now_title"
android:dependency="pref_enable_cloud_sync" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -87,7 +87,6 @@ import com.android.inputmethod.latin.settings.SettingsActivity;
import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.suggestions.SuggestionStripView; import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
import com.android.inputmethod.latin.sync.BeanstalkManager;
import com.android.inputmethod.latin.touchinputconsumer.GestureConsumer; import com.android.inputmethod.latin.touchinputconsumer.GestureConsumer;
import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CapsModeUtils;
@ -561,7 +560,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
AudioAndHapticFeedbackManager.init(this); AudioAndHapticFeedbackManager.init(this);
AccessibilityUtils.init(this); AccessibilityUtils.init(this);
mStatsUtilsManager.onCreate(this /* context */); mStatsUtilsManager.onCreate(this /* context */);
BeanstalkManager.getInstance(this /* context */).onCreate();
super.onCreate(); super.onCreate();
mHandler.onCreate(); mHandler.onCreate();
@ -709,7 +707,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryPackInstallReceiver);
unregisterReceiver(mDictionaryDumpBroadcastReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver);
mStatsUtilsManager.onDestroy(); mStatsUtilsManager.onDestroy();
BeanstalkManager.getInstance(this /* context */).onDestroy();
super.onDestroy(); super.onDestroy();
} }

View File

@ -16,7 +16,12 @@
package com.android.inputmethod.latin.settings; package com.android.inputmethod.latin.settings;
import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ACCOUNT_NAME;
import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC;
import android.accounts.Account;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -33,7 +38,6 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.accounts.LoginAccountUtils; import com.android.inputmethod.latin.accounts.LoginAccountUtils;
import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.sync.BeanstalkManager;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -41,19 +45,18 @@ import javax.annotation.Nullable;
* "Accounts & Privacy" settings sub screen. * "Accounts & Privacy" settings sub screen.
* *
* This settings sub screen handles the following preferences: * This settings sub screen handles the following preferences:
* <li> Account selection/management for IME * <li> Account selection/management for IME </li>
* <li> TODO: Sync preferences * <li> Sync preferences </li>
* <li> TODO: Privacy preferences * <li> Privacy preferences </li>
* <li> Sync now
*/ */
public final class AccountsSettingsFragment extends SubScreenFragment { public final class AccountsSettingsFragment extends SubScreenFragment {
static final String PREF_ACCCOUNT_SWITCHER = "account_switcher"; private static final String PREF_SYNC_NOW = "pref_beanstalk";
static final String PREF_SYNC_NOW = "pref_beanstalk";
private final DialogInterface.OnClickListener mAccountSelectedListener = @UsedForTesting static final String AUTHORITY = "com.android.inputmethod.latin.provider";
new AccountSelectedListener(); static final String PREF_ACCCOUNT_SWITCHER = "account_switcher";
private final DialogInterface.OnClickListener mAccountSignedOutListener =
new AccountSignedOutListener(); private final DialogInterface.OnClickListener mAccountChangedListener =
new AccountChangedListener();
private final Preference.OnPreferenceClickListener mSyncNowListener = new SyncNowListener(); private final Preference.OnPreferenceClickListener mSyncNowListener = new SyncNowListener();
@Override @Override
@ -81,47 +84,55 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
removePreference(Settings.PREF_ENABLE_METRICS_LOGGING); removePreference(Settings.PREF_ENABLE_METRICS_LOGGING);
} }
if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
removePreference(PREF_ACCCOUNT_SWITCHER);
removePreference(PREF_ENABLE_CLOUD_SYNC);
removePreference(PREF_SYNC_NOW);
}
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
removePreference(PREF_ENABLE_CLOUD_SYNC);
removePreference(PREF_SYNC_NOW); removePreference(PREF_SYNC_NOW);
} else { } else {
final Preference syncNowPreference = findPreference(PREF_SYNC_NOW); final Preference syncNowPreference = findPreference(PREF_SYNC_NOW);
if (syncNowPreference != null) { syncNowPreference.setOnPreferenceClickListener(mSyncNowListener);
syncNowPreference.setOnPreferenceClickListener(mSyncNowListener);
}
} }
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
refreshUi(); refreshAccountAndDependentPreferences(getCurrentlySelectedAccount());
} }
@Override @Override
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
// TODO: Look at the preference that changed before refreshing the view. if (TextUtils.equals(key, PREF_ACCOUNT_NAME)) {
refreshUi(); refreshAccountAndDependentPreferences(
prefs.getString(PREF_ACCOUNT_NAME, null));
} else if (TextUtils.equals(key, PREF_ENABLE_CLOUD_SYNC)) {
final boolean syncEnabled = prefs.getBoolean(PREF_ENABLE_CLOUD_SYNC, false);
updateSyncPolicy(syncEnabled, LoginAccountUtils.getCurrentAccount(getActivity()));
}
} }
private void refreshUi() { private void refreshAccountAndDependentPreferences(@Nullable final String currentAccount) {
refreshAccountSelection();
refreshSyncNow();
}
private void refreshAccountSelection() {
if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) { if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
return; return;
} }
final String currentAccount = getCurrentlySelectedAccount();
final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER); final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
if (currentAccount == null) { if (currentAccount == null) {
// No account is currently selected. // No account is currently selected.
accountSwitcher.setSummary(getString(R.string.no_accounts_selected)); accountSwitcher.setSummary(getString(R.string.no_accounts_selected));
// Disable the sync preference UI.
disableSyncPreference();
} else { } else {
// Set the currently selected account. // Set the currently selected account.
accountSwitcher.setSummary(getString(R.string.account_selected, currentAccount)); accountSwitcher.setSummary(getString(R.string.account_selected, currentAccount));
// Enable the sync preference UI.
enableSyncPreference();
} }
// Set up onClick listener for the account picker preference.
final Context context = getActivity(); final Context context = getActivity();
final String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context); final String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context);
accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() { accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@ -129,39 +140,64 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (accountsForLogin.length == 0) { if (accountsForLogin.length == 0) {
// TODO: Handle account addition. // TODO: Handle account addition.
Toast.makeText(getActivity(), Toast.makeText(getActivity(), getString(R.string.account_select_cancel),
getString(R.string.account_select_cancel), Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
} else { } else {
createAccountPicker(accountsForLogin, currentAccount).show(); createAccountPicker(accountsForLogin, currentAccount).show();
} }
return true; return true;
} }
}); });
// TODO: Depending on the account selection, enable/disable preferences that
// depend on an account.
} }
/** /**
* Refreshes the "Sync Now" feature * Enables the Sync preference UI and updates its summary.
*/ */
private void refreshSyncNow() { private void enableSyncPreference() {
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return; return;
} }
final Preference syncNowPreference = findPreference(PREF_SYNC_NOW); final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
if (syncNowPreference == null) { syncPreference.setEnabled(true);
syncPreference.setSummary(R.string.cloud_sync_summary);
}
/**
* Disables the Sync preference UI and updates its summary to indicate
* the fact that an account needs to be selected for sync.
*/
private void disableSyncPreference() {
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return; return;
} }
final String currentAccount = getCurrentlySelectedAccount(); final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
if (currentAccount == null) { syncPreference.setEnabled(false);
syncNowPreference.setEnabled(false); syncPreference.setSummary(R.string.cloud_sync_summary_disabled_signed_out);
syncNowPreference.setSummary(R.string.sync_now_summary_disabled_signed_out); }
/**
* Given a non-null accountToUse, this method looks at the enabled value to either
* set or unset the syncable property of the sync authority.
* If the account is null, this method is a no-op currently, but we may want
* to perform some cleanup in the future.
*/
@UsedForTesting
void updateSyncPolicy(boolean enabled, Account accountToUse) {
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return;
}
if (accountToUse != null) {
final int syncable = enabled ? 1 : 0;
ContentResolver.setIsSyncable(accountToUse, AUTHORITY, syncable);
// TODO: Also add a periodic sync here.
// See ContentResolver.addPeriodicSync
} else { } else {
syncNowPreference.setEnabled(true); // Without an account, we cannot really set the sync to off.
syncNowPreference.setSummary(R.string.sync_now_summary); // Hopefully the account sign-out listener would have taken care of that for us.
// But cases such as clear data are still not handled cleanly.
} }
} }
@ -170,6 +206,10 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null); return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null);
} }
private boolean isSyncEnabled() {
return getSharedPreferences().getBoolean(PREF_ENABLE_CLOUD_SYNC, false);
}
/** /**
* Creates an account picker dialog showing the given accounts in a list and selecting * Creates an account picker dialog showing the given accounts in a list and selecting
* the selected account by default. * the selected account by default.
@ -200,51 +240,55 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(R.string.account_select_title) .setTitle(R.string.account_select_title)
.setSingleChoiceItems(accounts, index, null) .setSingleChoiceItems(accounts, index, null)
.setPositiveButton(R.string.account_select_ok, mAccountSelectedListener) .setPositiveButton(R.string.account_select_ok, mAccountChangedListener)
.setNegativeButton(R.string.account_select_cancel, null); .setNegativeButton(R.string.account_select_cancel, null);
if (isSignedIn) { if (isSignedIn) {
builder.setNeutralButton(R.string.account_select_sign_out, mAccountSignedOutListener); builder.setNeutralButton(R.string.account_select_sign_out, mAccountChangedListener);
} }
return builder.create(); return builder.create();
} }
/** /**
* Listener for an account being selected from the picker. * Listener for a account selection changes from the picker.
* Persists the account to shared preferences. * Persists/removes the account to/from shared preferences and sets up sync if required.
*/ */
class AccountSelectedListener implements DialogInterface.OnClickListener { class AccountChangedListener implements DialogInterface.OnClickListener {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
final ListView lv = ((AlertDialog)dialog).getListView(); switch (which) {
final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition()); case DialogInterface.BUTTON_POSITIVE: // Signed in
getSharedPreferences() final ListView lv = ((AlertDialog)dialog).getListView();
.edit() final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition());
.putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, (String) selectedItem) getSharedPreferences()
.apply(); .edit()
.putString(PREF_ACCOUNT_NAME, (String) selectedItem)
.apply();
// Attempt starting sync for the new account if sync was
// previously enabled.
// If not, stop it.
updateSyncPolicy(isSyncEnabled(),
LoginAccountUtils.getCurrentAccount(getActivity()));
break;
case DialogInterface.BUTTON_NEUTRAL: // Signed out
// Stop sync for the account that's being signed out of.
updateSyncPolicy(false, LoginAccountUtils.getCurrentAccount(getActivity()));
getSharedPreferences()
.edit()
.remove(PREF_ACCOUNT_NAME)
.apply();
break;
}
} }
} }
/** /**
* Listener for sign-out being initiated from from the picker. * Listener that initiates the process of sync in the background.
* Removed the account from shared preferences.
*/
class AccountSignedOutListener implements DialogInterface.OnClickListener {
@Override
public void onClick(DialogInterface dialog, int which) {
getSharedPreferences()
.edit()
.remove(LocalSettingsConstants.PREF_ACCOUNT_NAME)
.apply();
}
}
/**
* Listener that initates the process of sync in the background.
*/ */
class SyncNowListener implements Preference.OnPreferenceClickListener { class SyncNowListener implements Preference.OnPreferenceClickListener {
@Override @Override
public boolean onPreferenceClick(final Preference preference) { public boolean onPreferenceClick(final Preference preference) {
BeanstalkManager.getInstance(getActivity() /* context */).requestSync(); ContentResolver.requestSync(
LoginAccountUtils.getCurrentAccount(getActivity()), AUTHORITY, Bundle.EMPTY);
return true; return true;
} }
} }

View File

@ -27,6 +27,9 @@ public class LocalSettingsConstants {
// Preference key for the current account. // Preference key for the current account.
// Do not restore. // Do not restore.
public static final String PREF_ACCOUNT_NAME = "pref_account_name"; public static final String PREF_ACCOUNT_NAME = "pref_account_name";
// Preference key for enabling cloud sync feature.
// Do not restore.
public static final String PREF_ENABLE_CLOUD_SYNC = "pref_enable_cloud_sync";
// List of preference keys to skip from being restored by backup agent. // List of preference keys to skip from being restored by backup agent.
// These preferences are tied to a device and hence should not be restored. // These preferences are tied to a device and hence should not be restored.
@ -36,6 +39,7 @@ public class LocalSettingsConstants {
// shared preferences which makes it non-trivial to move these out to // shared preferences which makes it non-trivial to move these out to
// a different shared preferences file. // a different shared preferences file.
public static final String[] PREFS_TO_SKIP_RESTORING = new String[] { public static final String[] PREFS_TO_SKIP_RESTORING = new String[] {
PREF_ACCOUNT_NAME PREF_ACCOUNT_NAME,
PREF_ENABLE_CLOUD_SYNC
}; };
} }

View File

@ -16,14 +16,20 @@
package com.android.inputmethod.latin.settings; package com.android.inputmethod.latin.settings;
import static com.android.inputmethod.latin.settings.AccountsSettingsFragment.AUTHORITY;
import android.accounts.Account;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.ContentResolver;
import android.content.Intent; import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.MediumTest;
import android.view.View; import android.view.View;
import android.widget.ListView; import android.widget.ListView;
import com.android.inputmethod.latin.define.ProductionFlags;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -32,6 +38,7 @@ public class AccountsSettingsFragmentTests
extends ActivityInstrumentationTestCase2<TestFragmentActivity> { extends ActivityInstrumentationTestCase2<TestFragmentActivity> {
private static final String FRAG_NAME = AccountsSettingsFragment.class.getName(); private static final String FRAG_NAME = AccountsSettingsFragment.class.getName();
private static final long TEST_TIMEOUT_MILLIS = 5000; private static final long TEST_TIMEOUT_MILLIS = 5000;
private static final Account TEST_ACCOUNT = new Account("account-for-test", "account-type");
private AlertDialog mDialog; private AlertDialog mDialog;
@ -47,6 +54,13 @@ public class AccountsSettingsFragmentTests
setActivityIntent(intent); setActivityIntent(intent);
} }
@Override
protected void tearDown() throws Exception {
super.tearDown();
// reset the syncable state to unknown
ContentResolver.setIsSyncable(TEST_ACCOUNT, AUTHORITY, -1);
}
public void testEmptyAccounts() { public void testEmptyAccounts() {
final AccountsSettingsFragment fragment = final AccountsSettingsFragment fragment =
(AccountsSettingsFragment) getActivity().mFragment; (AccountsSettingsFragment) getActivity().mFragment;
@ -129,4 +143,57 @@ public class AccountsSettingsFragmentTests
assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_NEGATIVE).getVisibility()); assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_NEGATIVE).getVisibility());
assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_POSITIVE).getVisibility()); assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_POSITIVE).getVisibility());
} }
public void testUpdateSyncPolicy_enable() {
// This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return;
}
// Should be unknown by default.
assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0);
final AccountsSettingsFragment fragment =
(AccountsSettingsFragment) getActivity().mFragment;
fragment.updateSyncPolicy(true, TEST_ACCOUNT);
// Should be syncable now.
assertEquals(1, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY));
}
public void testUpdateSyncPolicy_disable() {
// This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return;
}
// Should be unknown by default.
assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0);
final AccountsSettingsFragment fragment =
(AccountsSettingsFragment) getActivity().mFragment;
fragment.updateSyncPolicy(false, TEST_ACCOUNT);
// Should not be syncable now.
assertEquals(0, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY));
}
public void testUpdateSyncPolicy_enableDisable() {
// This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled
if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
return;
}
// Should be unknown by default.
assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0);
final AccountsSettingsFragment fragment =
(AccountsSettingsFragment) getActivity().mFragment;
fragment.updateSyncPolicy(true, TEST_ACCOUNT);
// Should be syncable now.
assertEquals(1, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY));
fragment.updateSyncPolicy(false, TEST_ACCOUNT);
// Should not be syncable now.
assertEquals(0, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY));
}
} }