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: I2f748be971a2337543e5014434aa39313fd1e1d8main
parent
6e565332df
commit
1e10d29bc8
|
@ -17,15 +17,42 @@
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.app.backup.BackupAgentHelper;
|
import android.app.backup.BackupAgentHelper;
|
||||||
|
import android.app.backup.BackupDataInput;
|
||||||
import android.app.backup.SharedPreferencesBackupHelper;
|
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 {
|
public final class BackupAgent extends BackupAgentHelper {
|
||||||
|
private static final String PREF_SUFFIX = "_preferences";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
addHelper("shared_pref", new SharedPreferencesBackupHelper(this,
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.inputmethod.annotations.UsedForTesting;
|
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}.
|
* {@link BroadcastReceiver} for {@link AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION}.
|
||||||
|
@ -41,25 +41,14 @@ public class AccountsChangedReceiver extends BroadcastReceiver {
|
||||||
return;
|
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 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
final String currentAccount = prefs.getString(Settings.PREF_ACCOUNT_NAME, null);
|
final String currentAccount = prefs.getString(
|
||||||
if (currentAccount != null) {
|
LocalSettingsConstants.PREF_ACCOUNT_NAME, null);
|
||||||
final String[] accounts = getAccountsForLogin(context);
|
removeUnknownAccountFromPreference(prefs, getAccountsForLogin(context), currentAccount);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,4 +58,24 @@ public class AccountsChangedReceiver extends BroadcastReceiver {
|
||||||
protected String[] getAccountsForLogin(Context context) {
|
protected String[] getAccountsForLogin(Context context) {
|
||||||
return LoginAccountUtils.getAccountsForLogin(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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getCurrentlySelectedAccount() {
|
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());
|
final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition());
|
||||||
getSharedPreferences()
|
getSharedPreferences()
|
||||||
.edit()
|
.edit()
|
||||||
.putString(Settings.PREF_ACCOUNT_NAME, (String) selectedItem)
|
.putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, (String) selectedItem)
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
getSharedPreferences()
|
getSharedPreferences()
|
||||||
.edit()
|
.edit()
|
||||||
.remove(Settings.PREF_ACCOUNT_NAME)
|
.remove(LocalSettingsConstants.PREF_ACCOUNT_NAME)
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
|
@ -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_KEY_IS_INTERNAL = "pref_key_is_internal";
|
||||||
|
|
||||||
public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
|
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 preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead.
|
||||||
// This is being used only for the backward compatibility.
|
// This is being used only for the backward compatibility.
|
||||||
private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
|
private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
|
||||||
|
|
|
@ -64,7 +64,6 @@ public class SettingsValues {
|
||||||
public final boolean mSoundOn;
|
public final boolean mSoundOn;
|
||||||
public final boolean mKeyPreviewPopupOn;
|
public final boolean mKeyPreviewPopupOn;
|
||||||
public final boolean mShowsVoiceInputKey;
|
public final boolean mShowsVoiceInputKey;
|
||||||
public final String mAccountName;
|
|
||||||
public final boolean mIncludesOtherImesInLanguageSwitchList;
|
public final boolean mIncludesOtherImesInLanguageSwitchList;
|
||||||
public final boolean mShowsLanguageSwitchKey;
|
public final boolean mShowsLanguageSwitchKey;
|
||||||
public final boolean mUseContactsDict;
|
public final boolean mUseContactsDict;
|
||||||
|
@ -141,7 +140,6 @@ public class SettingsValues {
|
||||||
mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res)
|
mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res)
|
||||||
&& mInputAttributes.mShouldShowVoiceInputKey
|
&& mInputAttributes.mShouldShowVoiceInputKey
|
||||||
&& SubtypeSwitcher.getInstance().isShortcutImeEnabled();
|
&& SubtypeSwitcher.getInstance().isShortcutImeEnabled();
|
||||||
mAccountName = prefs.getString(Settings.PREF_ACCOUNT_NAME, null);
|
|
||||||
final String autoCorrectionThresholdRawValue = prefs.getString(
|
final String autoCorrectionThresholdRawValue = prefs.getString(
|
||||||
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
|
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
|
||||||
res.getString(R.string.auto_correction_threshold_mode_index_modest));
|
res.getString(R.string.auto_correction_threshold_mode_index_modest));
|
||||||
|
@ -385,8 +383,6 @@ public class SettingsValues {
|
||||||
sb.append("" + mKeyPreviewPopupOn);
|
sb.append("" + mKeyPreviewPopupOn);
|
||||||
sb.append("\n mShowsVoiceInputKey = ");
|
sb.append("\n mShowsVoiceInputKey = ");
|
||||||
sb.append("" + mShowsVoiceInputKey);
|
sb.append("" + mShowsVoiceInputKey);
|
||||||
sb.append("\n mAccountName = ");
|
|
||||||
sb.append("" + mAccountName);
|
|
||||||
sb.append("\n mIncludesOtherImesInLanguageSwitchList = ");
|
sb.append("\n mIncludesOtherImesInLanguageSwitchList = ");
|
||||||
sb.append("" + mIncludesOtherImesInLanguageSwitchList);
|
sb.append("" + mIncludesOtherImesInLanguageSwitchList);
|
||||||
sb.append("\n mShowsLanguageSwitchKey = ");
|
sb.append("\n mShowsLanguageSwitchKey = ");
|
||||||
|
|
|
@ -23,7 +23,7 @@ import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.settings.Settings;
|
import com.android.inputmethod.latin.settings.LocalSettingsConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link AccountsChangedReceiver}.
|
* Tests for {@link AccountsChangedReceiver}.
|
||||||
|
@ -40,7 +40,7 @@ public class AccountsChangedReceiverTests extends AndroidTestCase {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||||
// Keep track of the current account so that we restore it when the test finishes.
|
// 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
|
@Override
|
||||||
|
@ -99,13 +99,14 @@ public class AccountsChangedReceiverTests extends AndroidTestCase {
|
||||||
|
|
||||||
private void updateAccountName(String accountName) {
|
private void updateAccountName(String accountName) {
|
||||||
if (accountName == null) {
|
if (accountName == null) {
|
||||||
mPrefs.edit().remove(Settings.PREF_ACCOUNT_NAME).apply();
|
mPrefs.edit().remove(LocalSettingsConstants.PREF_ACCOUNT_NAME).apply();
|
||||||
} else {
|
} else {
|
||||||
mPrefs.edit().putString(Settings.PREF_ACCOUNT_NAME, accountName).apply();
|
mPrefs.edit().putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, accountName).apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAccountName(String expectedAccountName) {
|
private void assertAccountName(String expectedAccountName) {
|
||||||
assertEquals(expectedAccountName, mPrefs.getString(Settings.PREF_ACCOUNT_NAME, null));
|
assertEquals(expectedAccountName,
|
||||||
|
mPrefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue