From 1e10d29bc8975ea45ca5e3bdf1936aa418161bcb Mon Sep 17 00:00:00 2001 From: Sandeep Siddhartha Date: Thu, 9 Oct 2014 12:21:56 -0700 Subject: [PATCH] Don't restore device specific preferences There are two categories of preferences: 1. That are part of the default shared preference They were all getting backed up and restored. Added a blacklist to not restore some of these. e.g. current account 2. That are in a non-default shared preference file. These are not getting backed up currently, but added a specific local preference file for all such preferences. Bug: 17288591 Change-Id: I2f748be971a2337543e5014434aa39313fd1e1d8 --- .../inputmethod/latin/BackupAgent.java | 31 +++++++++++- .../accounts/AccountsChangedReceiver.java | 47 +++++++++++-------- .../settings/AccountsSettingsFragment.java | 6 +-- .../settings/LocalSettingsConstants.java | 41 ++++++++++++++++ .../inputmethod/latin/settings/Settings.java | 2 - .../latin/settings/SettingsValues.java | 4 -- .../AccountsChangedReceiverTests.java | 11 +++-- 7 files changed, 107 insertions(+), 35 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java diff --git a/java/src/com/android/inputmethod/latin/BackupAgent.java b/java/src/com/android/inputmethod/latin/BackupAgent.java index 1f044618a..fb672e14b 100644 --- a/java/src/com/android/inputmethod/latin/BackupAgent.java +++ b/java/src/com/android/inputmethod/latin/BackupAgent.java @@ -17,15 +17,42 @@ package com.android.inputmethod.latin; import android.app.backup.BackupAgentHelper; +import android.app.backup.BackupDataInput; import android.app.backup.SharedPreferencesBackupHelper; +import android.content.SharedPreferences; +import android.os.ParcelFileDescriptor; + +import com.android.inputmethod.latin.settings.LocalSettingsConstants; + +import java.io.IOException; /** - * Backs up the Latin IME shared preferences. + * Backup/restore agent for LatinIME. + * Currently it backs up the default shared preferences. */ public final class BackupAgent extends BackupAgentHelper { + private static final String PREF_SUFFIX = "_preferences"; + @Override public void onCreate() { addHelper("shared_pref", new SharedPreferencesBackupHelper(this, - getPackageName() + "_preferences")); + getPackageName() + PREF_SUFFIX)); + } + + @Override + public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) + throws IOException { + // Let the restore operation go through + super.onRestore(data, appVersionCode, newState); + + // Remove the preferences that we don't want restored. + final SharedPreferences.Editor prefEditor = getSharedPreferences( + getPackageName() + PREF_SUFFIX, MODE_PRIVATE).edit(); + final String[] prefsToRemove = LocalSettingsConstants.PREFS_TO_SKIP_RESTORING; + for (final String key : prefsToRemove) { + prefEditor.remove(key); + } + // Flush the changes to disk. + prefEditor.commit(); } } diff --git a/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java b/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java index 9445ce4c3..00bcecf52 100644 --- a/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java +++ b/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java @@ -26,7 +26,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.settings.Settings; +import com.android.inputmethod.latin.settings.LocalSettingsConstants; /** * {@link BroadcastReceiver} for {@link AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION}. @@ -41,25 +41,14 @@ public class AccountsChangedReceiver extends BroadcastReceiver { return; } + // Ideally the account preference could live in a different preferences file + // that wasn't being backed up and restored, however the preference fragments + // currently only deal with the default shared preferences which is why + // separating this out into a different file is not trivial currently. final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - final String currentAccount = prefs.getString(Settings.PREF_ACCOUNT_NAME, null); - if (currentAccount != null) { - final String[] accounts = getAccountsForLogin(context); - boolean accountFound = false; - for (String account : accounts) { - if (TextUtils.equals(currentAccount, account)) { - accountFound = true; - break; - } - } - // The current account was not found in the list of accounts, remove it. - if (!accountFound) { - Log.i(TAG, "The current account was removed from the system: " + currentAccount); - prefs.edit() - .remove(Settings.PREF_ACCOUNT_NAME) - .apply(); - } - } + final String currentAccount = prefs.getString( + LocalSettingsConstants.PREF_ACCOUNT_NAME, null); + removeUnknownAccountFromPreference(prefs, getAccountsForLogin(context), currentAccount); } /** @@ -69,4 +58,24 @@ public class AccountsChangedReceiver extends BroadcastReceiver { protected String[] getAccountsForLogin(Context context) { return LoginAccountUtils.getAccountsForLogin(context); } + + /** + * Removes the currentAccount from preferences if it's not found + * in the list of current accounts. + */ + private static void removeUnknownAccountFromPreference(final SharedPreferences prefs, + final String[] accounts, final String currentAccount) { + if (currentAccount == null) { + return; + } + for (final String account : accounts) { + if (TextUtils.equals(currentAccount, account)) { + return; + } + } + Log.i(TAG, "The current account was removed from the system: " + currentAccount); + prefs.edit() + .remove(LocalSettingsConstants.PREF_ACCOUNT_NAME) + .apply(); + } } diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java index 45792fe0e..fa716457c 100644 --- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java @@ -167,7 +167,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment { @Nullable private String getCurrentlySelectedAccount() { - return getSharedPreferences().getString(Settings.PREF_ACCOUNT_NAME, null); + return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null); } /** @@ -219,7 +219,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment { final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition()); getSharedPreferences() .edit() - .putString(Settings.PREF_ACCOUNT_NAME, (String) selectedItem) + .putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, (String) selectedItem) .apply(); } } @@ -233,7 +233,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment { public void onClick(DialogInterface dialog, int which) { getSharedPreferences() .edit() - .remove(Settings.PREF_ACCOUNT_NAME) + .remove(LocalSettingsConstants.PREF_ACCOUNT_NAME) .apply(); } } diff --git a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java new file mode 100644 index 000000000..71d6065e0 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java @@ -0,0 +1,41 @@ +/* + * 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.settings; + +/** + * Collection of device specific preference constants. + */ +public class LocalSettingsConstants { + // Preference file for storing preferences that are tied to a device + // and are not backed up. + public static final String PREFS_FILE = "local_prefs"; + + // Preference key for the current account. + // Do not restore. + public static final String PREF_ACCOUNT_NAME = "pref_account_name"; + + // 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. + // e.g. account name. + // Ideally they could have been kept in a separate file that wasn't backed up + // however the preference UI currently only deals with the default + // shared preferences which makes it non-trivial to move these out to + // a different shared preferences file. + public static final String[] PREFS_TO_SKIP_RESTORING = new String[] { + PREF_ACCOUNT_NAME + }; +} diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 84596b4ad..103033c16 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -106,8 +106,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal"; public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging"; - public static final String PREF_ACCOUNT_NAME = "pref_account_name"; - // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead. // This is being used only for the backward compatibility. private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index ce8a0ab9c..660b4e095 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -64,7 +64,6 @@ public class SettingsValues { public final boolean mSoundOn; public final boolean mKeyPreviewPopupOn; public final boolean mShowsVoiceInputKey; - public final String mAccountName; public final boolean mIncludesOtherImesInLanguageSwitchList; public final boolean mShowsLanguageSwitchKey; public final boolean mUseContactsDict; @@ -141,7 +140,6 @@ public class SettingsValues { mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res) && mInputAttributes.mShouldShowVoiceInputKey && SubtypeSwitcher.getInstance().isShortcutImeEnabled(); - mAccountName = prefs.getString(Settings.PREF_ACCOUNT_NAME, null); final String autoCorrectionThresholdRawValue = prefs.getString( Settings.PREF_AUTO_CORRECTION_THRESHOLD, res.getString(R.string.auto_correction_threshold_mode_index_modest)); @@ -385,8 +383,6 @@ public class SettingsValues { sb.append("" + mKeyPreviewPopupOn); sb.append("\n mShowsVoiceInputKey = "); sb.append("" + mShowsVoiceInputKey); - sb.append("\n mAccountName = "); - sb.append("" + mAccountName); sb.append("\n mIncludesOtherImesInLanguageSwitchList = "); sb.append("" + mIncludesOtherImesInLanguageSwitchList); sb.append("\n mShowsLanguageSwitchKey = "); diff --git a/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java index 00857e54e..832817967 100644 --- a/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java +++ b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java @@ -23,7 +23,7 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.test.AndroidTestCase; -import com.android.inputmethod.latin.settings.Settings; +import com.android.inputmethod.latin.settings.LocalSettingsConstants; /** * Tests for {@link AccountsChangedReceiver}. @@ -40,7 +40,7 @@ public class AccountsChangedReceiverTests extends AndroidTestCase { super.setUp(); mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); // Keep track of the current account so that we restore it when the test finishes. - mLastKnownAccount = mPrefs.getString(Settings.PREF_ACCOUNT_NAME, null); + mLastKnownAccount = mPrefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null); } @Override @@ -99,13 +99,14 @@ public class AccountsChangedReceiverTests extends AndroidTestCase { private void updateAccountName(String accountName) { if (accountName == null) { - mPrefs.edit().remove(Settings.PREF_ACCOUNT_NAME).apply(); + mPrefs.edit().remove(LocalSettingsConstants.PREF_ACCOUNT_NAME).apply(); } else { - mPrefs.edit().putString(Settings.PREF_ACCOUNT_NAME, accountName).apply(); + mPrefs.edit().putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, accountName).apply(); } } private void assertAccountName(String expectedAccountName) { - assertEquals(expectedAccountName, mPrefs.getString(Settings.PREF_ACCOUNT_NAME, null)); + assertEquals(expectedAccountName, + mPrefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null)); } }