aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJatin Matani <jatinm@google.com>2015-02-24 09:59:02 -0800
committerJatin Matani <jatinm@google.com>2015-02-26 11:43:42 -0800
commit8ec328fb2e454c2c9e353b6aec0bc613a1846c88 (patch)
tree69662a0182bc15a7bde97f5860635ee7d227d782
parent1d5ec6136cf2d2c84453120407957ddb64c7b2b7 (diff)
downloadlatinime-8ec328fb2e454c2c9e353b6aec0bc613a1846c88.tar.gz
latinime-8ec328fb2e454c2c9e353b6aec0bc613a1846c88.tar.xz
latinime-8ec328fb2e454c2c9e353b6aec0bc613a1846c88.zip
Refresh pref settings for cloud sync
- Show the opt-in text - Show the account picker if user presses 'enable sync'. Previously we disabled the sync pref which was confusing. - Remove the debug tags from some prefs; and improve messaging overall General rules; - sync is turned ON : user checks 'enable sync' pref AND accepts the opt-in AND chooses an account - sync is turned OFF: when user signs out Demo link https://drive.google.com/a/google.com/file/d/0B9tNQOWdRuiWSUdVVE5rVDJudlk/view?usp=sharing Change-Id: I2e7933796b15e47005ba9970a8c1294416ef31a0
-rw-r--r--java/res/values/strings.xml42
-rw-r--r--java/res/xml/prefs_screen_accounts.xml11
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java219
-rw-r--r--tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java6
4 files changed, 169 insertions, 109 deletions
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 2e9c8ea1f..50aa4a782 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -39,11 +39,9 @@
<!-- Settings screen title for preferences [CHAR LIMIT=33]-->
<string name="settings_screen_preferences">Preferences</string>
<!-- Settings screen title for accounts and privacy preferences [CHAR LIMIT=33]-->
- <string name="settings_screen_accounts">Accounts &amp; privacy</string>
+ <string name="settings_screen_accounts">Accounts &amp; Privacy</string>
<!-- Settings screen title for appearance & layouts preferences [CHAR LIMIT=33] -->
- <string name="settings_screen_appearance">Appearance &amp; layouts</string>
- <!-- Settings screen title for multilingual options [CHAR_LIMIT=33] -->
- <string name="settings_screen_multilingual">Multilingual options</string>
+ <string name="settings_screen_appearance">Appearance &amp; Layouts</string>
<!-- Settings screen title for gesture typing preferences [CHAR_LIMIT=33] -->
<string name="settings_screen_gesture">Gesture Typing</string>
<!-- Settings screen title for text correction options [CHAR_LIMIT=33] -->
@@ -56,17 +54,31 @@
<!-- Option for enabling or disabling the split keyboard layout. [CHAR LIMIT=65]-->
<string name="enable_split_keyboard">Enable split keyboard</string>
- <!-- TODO: Enable translation for user-visible strings -->
- <string name="cloud_sync_title" translatable="false">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>
- <string name="clear_sync_data_title" translatable="false">[DEBUG] Delete Google Keyboard cloud data</string>
- <string name="clear_sync_data_summary" translable="false">Deletes your synced data from Google</string>
- <string name="clear_sync_data_confirmation" translable="false">Your synced data will be deleted. Are you sure?</string>
- <string name="clear_sync_data_ok" translable="false">Delete</string>
- <string name="clear_sync_data_cancel" translable="false">Cancel</string>
-
+ <!-- Option title for enabling cloud sync feature [CHAR LIMIT=33]-->
+ <string name="cloud_sync_title">Google Keyboard Sync</string>
+ <!-- Option summary when cloud sync feature is enabled [CHAR LIMIT=65] -->
+ <string name="cloud_sync_summary">Sync is turned on</string>
+ <!-- Option summary when cloud sync feature is disabled [CHAR LIMIT=65] -->
+ <string name="cloud_sync_summary_disabled">Sync your personal dictionary across devices</string>
+ <!-- Option title for starting the sync cycle now. [CHAR LIMIT=33]-->
+ <string name="sync_now_title">Sync Now</string>
+ <!-- Option title for letting user delete data from Google servers. [CHAR LIMIT=33] -->
+ <string name="clear_sync_data_title">Delete Keyboard Cloud data</string>
+ <!-- Option summary for letting user delete data from Google servers. [CHAR LIMIT=65] -->
+ <string name="clear_sync_data_summary">Deletes your synced data from Google</string>
+ <!-- Text for confirmation dialog box asking user to confirm deletion of cloud data. [CHAR LIMIT=65] -->
+ <string name="clear_sync_data_confirmation">Your synced data will be deleted from the cloud. Are you sure?</string>
+ <!-- Option to confirm deleting of user data from cloud [CHAR LIMIT=20] -->
+ <string name="clear_sync_data_ok">Delete</string>
+ <!-- Option to cancel the deletion of user data from cloud [CHAR LIMIT=20] -->
+ <string name="cloud_sync_cancel">Cancel</string>
+ <!-- Option to agree to terms and conditions for enabling cloud sync feature. -->
+ <string name="cloud_sync_opt_in_text">Your personal dictionary will be synced &amp; backed up to
+ Google servers. The statistical information of word frequency may be collected to help
+ improve our products. The collection and usage of all the information will be compliant with
+ <a href="https://www.google.com/policies/privacy">Google\'s Privacy Policy</a>.
+ </string>
+
<!-- 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>
<!-- Option summary for including other IMEs in the language switch list [CHAR LIMIT=65] -->
diff --git a/java/res/xml/prefs_screen_accounts.xml b/java/res/xml/prefs_screen_accounts.xml
index 462488547..e4baf7984 100644
--- a/java/res/xml/prefs_screen_accounts.xml
+++ b/java/res/xml/prefs_screen_accounts.xml
@@ -36,21 +36,14 @@
android:persistent="true"
android:disableDependentsState="false" />
- <!-- Title will be set programmatically to embed application name -->
- <CheckBoxPreference
- android:key="pref_enable_metrics_logging"
- android:summary="@string/enable_metrics_logging_summary"
- android:defaultValue="true"
- android:persistent="true" />
-
<!-- This preference (acts like a button) enables the user to initiate an one time sync. -->
- <Preference android:key="pref_beanstalk"
+ <Preference android:key="pref_sync_now"
android:persistent="false"
android:title="@string/sync_now_title"
android:dependency="pref_enable_cloud_sync" />
<!-- This preference (acts like a button) enables the user to clear data from the cloud. -->
- <Preference android:key="pref_beanstalk_clear_data"
+ <Preference android:key="pref_clear_sync_data"
android:persistent="false"
android:title="@string/clear_sync_data_title"
android:summary="@string/clear_sync_data_summary"
diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
index 10d570cbf..3a4826043 100644
--- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
@@ -23,8 +23,8 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
-import android.content.res.Resources;
import android.os.Bundle;
+import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.TextUtils;
@@ -48,36 +48,50 @@ import javax.annotation.Nullable;
* <li> Privacy preferences </li>
*/
public final class AccountsSettingsFragment extends SubScreenFragment {
- private static final String PREF_SYNC_NOW = "pref_beanstalk";
- private static final String PREF_CLEAR_SYNC_DATA = "pref_beanstalk_clear_data";
+ private static final String PREF_ENABLE_SYNC_NOW = "pref_enable_cloud_sync";
+ private static final String PREF_SYNC_NOW = "pref_sync_now";
+ private static final String PREF_CLEAR_SYNC_DATA = "pref_clear_sync_data";
static final String PREF_ACCCOUNT_SWITCHER = "account_switcher";
- private final DialogInterface.OnClickListener mAccountChangedListener =
- new AccountChangedListener();
- private final Preference.OnPreferenceClickListener mSyncNowListener = new SyncNowListener();
- private final Preference.OnPreferenceClickListener mClearSyncDataListener =
- new ClearSyncDataListener();
+ /**
+ * Onclick listener for sync now pref.
+ */
+ private final Preference.OnPreferenceClickListener mSyncNowListener =
+ new SyncNowListener();
+ /**
+ * Onclick listener for delete sync pref.
+ */
+ private final Preference.OnPreferenceClickListener mDeleteSyncDataListener =
+ new DeleteSyncDataListener();
+
+ /**
+ * Onclick listener for enable sync pref.
+ */
+ private final Preference.OnPreferenceClickListener mEnableSyncClickListener =
+ new EnableSyncClickListener();
+
+ /**
+ * Enable sync checkbox pref.
+ */
+ private CheckBoxPreference mEnableSyncPreference;
+
+ /**
+ * Enable sync checkbox pref.
+ */
+ private Preference mSyncNowPreference;
+
+ /**
+ * Clear sync data pref.
+ */
+ private Preference mClearSyncDataPreference;
+
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_accounts);
- final Resources res = getResources();
-
- if (ProductionFlags.IS_METRICS_LOGGING_SUPPORTED) {
- final Preference enableMetricsLogging =
- findPreference(Settings.PREF_ENABLE_METRICS_LOGGING);
- if (enableMetricsLogging != null) {
- final String enableMetricsLoggingTitle = res.getString(
- R.string.enable_metrics_logging, getApplicationName());
- enableMetricsLogging.setTitle(enableMetricsLoggingTitle);
- }
- } else {
- removePreference(Settings.PREF_ENABLE_METRICS_LOGGING);
- }
-
if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
removePreference(PREF_ACCCOUNT_SWITCHER);
removePreference(PREF_ENABLE_CLOUD_SYNC);
@@ -89,11 +103,14 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
removePreference(PREF_SYNC_NOW);
removePreference(PREF_CLEAR_SYNC_DATA);
} else {
- final Preference syncNowPreference = findPreference(PREF_SYNC_NOW);
- syncNowPreference.setOnPreferenceClickListener(mSyncNowListener);
+ mEnableSyncPreference = (CheckBoxPreference) findPreference(PREF_ENABLE_SYNC_NOW);
+ mEnableSyncPreference.setOnPreferenceClickListener(mEnableSyncClickListener);
+
+ mSyncNowPreference = findPreference(PREF_SYNC_NOW);
+ mSyncNowPreference.setOnPreferenceClickListener(mSyncNowListener);
- final Preference clearSyncDataPreference = findPreference(PREF_CLEAR_SYNC_DATA);
- clearSyncDataPreference.setOnPreferenceClickListener(mClearSyncDataListener);
+ mClearSyncDataPreference = findPreference(PREF_CLEAR_SYNC_DATA);
+ mClearSyncDataPreference.setOnPreferenceClickListener(mDeleteSyncDataListener);
}
}
@@ -106,15 +123,25 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
@Override
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
if (TextUtils.equals(key, PREF_ACCOUNT_NAME)) {
- refreshAccountAndDependentPreferences(
- prefs.getString(PREF_ACCOUNT_NAME, null));
+ 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);
- AccountStateChangedListener.onSyncPreferenceChanged(
- getSignedInAccountName(), syncEnabled);
+ mEnableSyncPreference = (CheckBoxPreference)findPreference(PREF_ENABLE_SYNC_NOW);
+ mEnableSyncPreference.setChecked(syncEnabled);
+ if (syncEnabled) {
+ mEnableSyncPreference.setSummary(R.string.cloud_sync_summary);
+ } else {
+ mEnableSyncPreference.setSummary(R.string.cloud_sync_summary_disabled);
+ }
+ AccountStateChangedListener.onSyncPreferenceChanged(getSignedInAccountName(),
+ syncEnabled);
}
}
+ /**
+ * Summarizes what account is being used and turns off dependent preferences if no account
+ * is currently selected.
+ */
private void refreshAccountAndDependentPreferences(@Nullable final String currentAccount) {
if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
return;
@@ -122,61 +149,33 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
if (currentAccount == null) {
- // No account is currently selected.
+ // No account is currently selected; switch enable sync preference off.
accountSwitcher.setSummary(getString(R.string.no_accounts_selected));
- // Disable the sync preference UI.
- disableSyncPreference();
+ mEnableSyncPreference.setChecked(false);
} else {
- // Set the currently selected account.
+ // Set the currently selected account as the summary text.
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 String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context);
+
+ // Set up on click listener for the account picker preference.
accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(final Preference preference) {
- if (accountsForLogin.length == 0) {
- // TODO: Handle account addition.
- Toast.makeText(getActivity(), getString(R.string.account_select_cancel),
- Toast.LENGTH_SHORT).show();
- } else {
- createAccountPicker(accountsForLogin, currentAccount).show();
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ final String[] accountsForLogin =
+ LoginAccountUtils.getAccountsForLogin(getActivity());
+ if (accountsForLogin.length == 0) {
+ // TODO: Handle account addition.
+ Toast.makeText(getActivity(), getString(R.string.account_select_cancel),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ createAccountPicker(accountsForLogin, currentAccount,
+ new AccountChangedListener(null)).show();
+ }
+ return true;
}
- return true;
- }
});
}
- /**
- * Enables the Sync preference UI and updates its summary.
- */
- private void enableSyncPreference() {
- if (!ProductionFlags.ENABLE_USER_HISTORY_DICTIONARY_SYNC) {
- return;
- }
-
- final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
- 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_USER_HISTORY_DICTIONARY_SYNC) {
- return;
- }
-
- final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
- syncPreference.setEnabled(false);
- syncPreference.setSummary(R.string.cloud_sync_summary_disabled_signed_out);
- }
-
@Nullable
String getSignedInAccountName() {
return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null);
@@ -188,14 +187,19 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
/**
* Creates an account picker dialog showing the given accounts in a list and selecting
- * the selected account by default.
- * The list of accounts must not be null/empty.
+ * the selected account by default. The list of accounts must not be null/empty.
*
* Package-private for testing.
+ *
+ * @param accounts list of accounts on the device.
+ * @param selectedAccount currently selected account
+ * @param positiveButtonClickListener listener that gets called when positive button is
+ * clicked
*/
@UsedForTesting
AlertDialog createAccountPicker(final String[] accounts,
- final String selectedAccount) {
+ final String selectedAccount,
+ final DialogInterface.OnClickListener positiveButtonClickListener) {
if (accounts == null || accounts.length == 0) {
throw new IllegalArgumentException("List of accounts must not be empty");
}
@@ -216,10 +220,10 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(R.string.account_select_title)
.setSingleChoiceItems(accounts, index, null)
- .setPositiveButton(R.string.account_select_ok, mAccountChangedListener)
+ .setPositiveButton(R.string.account_select_ok, positiveButtonClickListener)
.setNegativeButton(R.string.account_select_cancel, null);
if (isSignedIn) {
- builder.setNeutralButton(R.string.account_select_sign_out, mAccountChangedListener);
+ builder.setNeutralButton(R.string.account_select_sign_out, positiveButtonClickListener);
}
return builder.create();
}
@@ -229,6 +233,15 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
* Persists/removes the account to/from shared preferences and sets up sync if required.
*/
class AccountChangedListener implements DialogInterface.OnClickListener {
+ /**
+ * Represents preference that should be changed based on account chosen.
+ */
+ private CheckBoxPreference mDependentPreference;
+
+ AccountChangedListener(final CheckBoxPreference dependentPreference) {
+ mDependentPreference = dependentPreference;
+ }
+
@Override
public void onClick(final DialogInterface dialog, final int which) {
final String oldAccount = getSignedInAccountName();
@@ -242,6 +255,9 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
.putString(PREF_ACCOUNT_NAME, newAccount)
.apply();
AccountStateChangedListener.onAccountSignedIn(oldAccount, newAccount);
+ if (mDependentPreference != null) {
+ mDependentPreference.setChecked(true);
+ }
break;
case DialogInterface.BUTTON_NEUTRAL: // Signed out
AccountStateChangedListener.onAccountSignedOut(oldAccount);
@@ -268,7 +284,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
/**
* Listener that initiates the process of deleting user's data from the cloud.
*/
- class ClearSyncDataListener implements Preference.OnPreferenceClickListener {
+ class DeleteSyncDataListener implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(final Preference preference) {
final AlertDialog confirmationDialog = new AlertDialog.Builder(getActivity())
@@ -290,4 +306,43 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
return true;
}
}
+
+ /**
+ * Listens to events when user clicks on "Enable sync" feature.
+ */
+ class EnableSyncClickListener implements Preference.OnPreferenceClickListener {
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ final CheckBoxPreference syncPreference = (CheckBoxPreference) preference;
+ if (syncPreference.isChecked()) {
+ // Uncheck for now.
+ syncPreference.setChecked(false);
+
+ // Show opt-in.
+ final AlertDialog optInDialog = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.cloud_sync_title)
+ .setMessage(R.string.cloud_sync_opt_in_text)
+ .setPositiveButton(R.string.account_select_ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(final DialogInterface dialog,
+ final int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ final Context context = getActivity();
+ final String[] accountsForLogin =
+ LoginAccountUtils.getAccountsForLogin(context);
+ createAccountPicker(accountsForLogin,
+ getSignedInAccountName(),
+ new AccountChangedListener(syncPreference))
+ .show();
+ }
+ }
+ })
+ .setNegativeButton(R.string.cloud_sync_cancel, null)
+ .create();
+ optInDialog.show();
+ }
+ return true;
+ }
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java
index 36e967275..81a0f6934 100644
--- a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java
+++ b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java
@@ -49,7 +49,7 @@ public class AccountsSettingsFragmentTests
final AccountsSettingsFragment fragment =
(AccountsSettingsFragment) getActivity().mFragment;
try {
- fragment.createAccountPicker(new String[0], null);
+ fragment.createAccountPicker(new String[0], null, null /* listener */);
fail("Expected IllegalArgumentException, never thrown");
} catch (IllegalArgumentException expected) {
// Expected.
@@ -76,7 +76,7 @@ public class AccountsSettingsFragmentTests
"2@example.com",
"3@example.com",
"4@example.com"},
- null);
+ null, null /* positiveButtonListner */);
dialog.show();
dialogHolder.mDialog = dialog;
latch.countDown();
@@ -118,7 +118,7 @@ public class AccountsSettingsFragmentTests
"2@example.com",
"3@example.com",
"4@example.com"},
- "3@example.com");
+ "3@example.com", null /* positiveButtonListner */);
dialog.show();
dialogHolder.mDialog = dialog;
latch.countDown();