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
diff --git a/java/src/com/android/inputmethod/latin/BackupAgent.java b/java/src/com/android/inputmethod/latin/BackupAgent.java
index 1f04461..fb672e1 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 9445ce4..00bcecf 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.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 @@
             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 @@
     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 45792fe..fa71645 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 @@
 
     @Nullable
     private String getCurrentlySelectedAccount() {
-        return getSharedPreferences().getString(Settings.PREF_ACCOUNT_NAME, null);
+        return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null);
     }
 
     /**
@@ -219,7 +219,7 @@
             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 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 0000000..71d6065
--- /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 84596b4..103033c 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 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 ce8a0ab..660b4e0 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 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 @@
         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 @@
         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 00857e5..8328179 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.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 @@
         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 @@
 
     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));
     }
 }