1d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy/*
2d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * Copyright (C) 2012 Google Inc.
3d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * Licensed to The Android Open Source Project.
4d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy *
5d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * Licensed under the Apache License, Version 2.0 (the "License");
6d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * you may not use this file except in compliance with the License.
7d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * You may obtain a copy of the License at
8d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy *
9d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy *      http://www.apache.org/licenses/LICENSE-2.0
10d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy *
11d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * Unless required by applicable law or agreed to in writing, software
12d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * distributed under the License is distributed on an "AS IS" BASIS,
13d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * See the License for the specific language governing permissions and
15d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * limitations under the License.
16d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy */
17d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
18d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedypackage com.android.mail.preferences;
19d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
20d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport com.google.common.annotations.VisibleForTesting;
21d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport com.google.common.collect.Lists;
22d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
23f9024cc52785c8740654dc89296a10a18da83077Scott Kennedyimport android.app.backup.BackupManager;
24d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport android.content.Context;
25d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport android.content.SharedPreferences;
26d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport android.content.SharedPreferences.Editor;
27d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
28f9024cc52785c8740654dc89296a10a18da83077Scott Kennedyimport com.android.mail.MailIntentService;
29d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport com.android.mail.utils.LogTag;
30d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport com.android.mail.utils.LogUtils;
31d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
32d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport java.util.List;
33d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport java.util.Map;
34d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedyimport java.util.Set;
35d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
36d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy/**
37d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * A high-level API to store and retrieve preferences, that can be versioned in a similar manner as
38d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * SQLite databases. You must not use the preference key
39d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * {@value VersionedPrefs#PREFS_VERSION_NUMBER}
40d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy */
41d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedypublic abstract class VersionedPrefs {
42d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private final Context mContext;
43d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private final String mSharedPreferencesName;
44d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private final SharedPreferences mSharedPreferences;
45d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private final Editor mEditor;
46d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
47d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /** The key for the version number of the {@link SharedPreferences} file. */
48d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private static final String PREFS_VERSION_NUMBER = "prefs-version-number";
49d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
50d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
51d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * The current version number for {@link SharedPreferences}. This is a constant for all
52d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * applications based on UnifiedEmail.
53d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
54b3ffbbc2730c9cd0f8f0d4bedb3539762a27348dTony Mantler    protected static final int CURRENT_VERSION_NUMBER = 4;
55d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
56d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected static final String LOG_TAG = LogTag.getLogTag();
57d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
58d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
59d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param sharedPrefsName The name of the {@link SharedPreferences} file to use
60d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
61d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected VersionedPrefs(final Context context, final String sharedPrefsName) {
62d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        mContext = context.getApplicationContext();
63d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        mSharedPreferencesName = sharedPrefsName;
64d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        mSharedPreferences = context.getSharedPreferences(sharedPrefsName, Context.MODE_PRIVATE);
65d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        mEditor = mSharedPreferences.edit();
66d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
67d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        final int oldVersion = getCurrentVersion();
68d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
69d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        performUpgrade(oldVersion, CURRENT_VERSION_NUMBER);
70d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        setCurrentVersion(CURRENT_VERSION_NUMBER);
71d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
72d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        if (!hasMigrationCompleted()) {
739b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler            final BasePreferenceMigrator preferenceMigrator =
749b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler                    PreferenceMigratorHolder.createPreferenceMigrator();
759b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler            final boolean migrationComplete;
769b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler            if (preferenceMigrator != null) {
779b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler                migrationComplete = preferenceMigrator
789b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler                        .performMigration(context, oldVersion, CURRENT_VERSION_NUMBER);
799b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler            } else {
809b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler                LogUtils.w(LogUtils.TAG, "No preference migrator found, not migrating preferences");
819b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler                migrationComplete = false;
829b4df381c0a1197d8381134181c6c12087a90e2fTony Mantler            }
83d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
842b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein            if (migrationComplete) {
852b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein                setMigrationComplete();
862b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein            }
87d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        }
88d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
89d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
90d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected Context getContext() {
91d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return mContext;
92d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
93d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
94d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public String getSharedPreferencesName() {
95d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return mSharedPreferencesName;
96d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
97d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
98d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected SharedPreferences getSharedPreferences() {
99d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return mSharedPreferences;
100d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
101d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
102d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected Editor getEditor() {
103d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return mEditor;
104d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
105d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
10623baff67c8ec1c794494a6170375abafec29f592Tony Mantler    public void registerOnSharedPreferenceChangeListener(
10723baff67c8ec1c794494a6170375abafec29f592Tony Mantler            SharedPreferences.OnSharedPreferenceChangeListener listener) {
10823baff67c8ec1c794494a6170375abafec29f592Tony Mantler        mSharedPreferences.registerOnSharedPreferenceChangeListener(listener);
10923baff67c8ec1c794494a6170375abafec29f592Tony Mantler    }
11023baff67c8ec1c794494a6170375abafec29f592Tony Mantler
11123baff67c8ec1c794494a6170375abafec29f592Tony Mantler    public void unregisterOnSharedPreferenceChangeListener(
11223baff67c8ec1c794494a6170375abafec29f592Tony Mantler            SharedPreferences.OnSharedPreferenceChangeListener listener) {
11323baff67c8ec1c794494a6170375abafec29f592Tony Mantler        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(listener);
11423baff67c8ec1c794494a6170375abafec29f592Tony Mantler    }
11523baff67c8ec1c794494a6170375abafec29f592Tony Mantler
116d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
117d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Returns the current version of the {@link SharedPreferences} file.
118d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
119d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private int getCurrentVersion() {
120d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return mSharedPreferences.getInt(PREFS_VERSION_NUMBER, 0);
121d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
122d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
123d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    private void setCurrentVersion(final int versionNumber) {
124d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        getEditor().putInt(PREFS_VERSION_NUMBER, versionNumber);
125d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
126d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        /*
127d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy         * If the only preference we have is the version number, we do not want to commit it.
128d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy         * Instead, we will wait for some other preference to be written. This prevents us from
129d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy         * creating a file with only the version number.
130d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy         */
131d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        if (shouldBackUp()) {
132d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            getEditor().apply();
133d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        }
134d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
135d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
136d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected boolean hasMigrationCompleted() {
137d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return MailPrefs.get(mContext).hasMigrationCompleted();
138d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
139d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
140d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected void setMigrationComplete() {
141d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        MailPrefs.get(mContext).setMigrationComplete();
142d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
143d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
144d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
1452b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein     * Commits all pending changes to the preferences.
1462b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein     */
1472b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein    public void commit() {
1482b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein        getEditor().commit();
1492b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein    }
1502b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein
1512b1b87f90cb776e95f66aa5514505a0b21dc3d9dAndrew Sapperstein    /**
152d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Upgrades the {@link SharedPreferences} file.
153d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     *
154d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param oldVersion The current version
155d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param newVersion The new version
156d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
157d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected abstract void performUpgrade(int oldVersion, int newVersion);
158d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
159d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    @VisibleForTesting
160d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public void clearAllPreferences() {
161d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        getEditor().clear().commit();
162d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
163d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
164d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected abstract boolean canBackup(String key);
165d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
166d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
167d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Gets the value to backup for a given key-value pair. By default, returns the passed in value.
168d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     *
169d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param key The key to backup
170d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param value The locally stored value for the given key
171d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @return The value to backup
172d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
173d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected Object getBackupValue(final String key, final Object value) {
174d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return value;
175d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
176d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
177d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
178d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Gets the value to restore for a given key-value pair. By default, returns the passed in
179d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * value.
180d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     *
181d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param key The key to restore
182d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @param value The backed up value for the given key
183d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @return The value to restore
184d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
185d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    protected Object getRestoreValue(final String key, final Object value) {
186d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return value;
187d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
188d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
189d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
190d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Return a list of shared preferences that should be backed up.
191d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
192d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public List<BackupSharedPreference> getBackupPreferences() {
193d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        final List<BackupSharedPreference> backupPreferences = Lists.newArrayList();
194d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        final SharedPreferences sharedPreferences = getSharedPreferences();
195d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        final Map<String, ?> preferences = sharedPreferences.getAll();
196d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
197d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        for (final Map.Entry<String, ?> entry : preferences.entrySet()) {
198d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final String key = entry.getKey();
199d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
200d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            if (!canBackup(key)) {
201d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                continue;
202d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            }
203d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
204d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final Object value = entry.getValue();
205d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final Object backupValue = getBackupValue(key, value);
206d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
207d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            if (backupValue != null) {
208d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                backupPreferences.add(new SimpleBackupSharedPreference(key, backupValue));
209d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            }
210d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        }
211d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
212d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return backupPreferences;
213d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
214d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
215d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
216d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Restores preferences from a backup.
217d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
218d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public void restorePreferences(final List<BackupSharedPreference> preferences) {
219d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        for (final BackupSharedPreference preference : preferences) {
220d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final String key = preference.getKey();
221d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final Object value = preference.getValue();
222d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
223d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            if (!canBackup(key) || value == null) {
224d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                continue;
225d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            }
226d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
227d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            final Object restoreValue = getRestoreValue(key, value);
228d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
229d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            if (restoreValue instanceof Boolean) {
230d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putBoolean(key, (Boolean) restoreValue);
231d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference);
232d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else if (restoreValue instanceof Float) {
233d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putFloat(key, (Float) restoreValue);
234d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference);
235d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else if (restoreValue instanceof Integer) {
236d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putInt(key, (Integer) restoreValue);
237d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference);
238d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else if (restoreValue instanceof Long) {
239d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putLong(key, (Long) restoreValue);
240d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference);
241d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else if (restoreValue instanceof String) {
242d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putString(key, (String) restoreValue);
243d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference);
244d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else if (restoreValue instanceof Set) {
245d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                getEditor().putStringSet(key, (Set<String>) restoreValue);
246d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            } else {
247d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                LogUtils.e(LOG_TAG, "Unknown MailPrefs preference data type: %s", value.getClass());
248d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            }
249d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        }
250d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
251d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        getEditor().apply();
252d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
253d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
254d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
255d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * <p>
256d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * Checks if any of the preferences eligible for backup have been modified from their default
257d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * values, and therefore should be backed up.
258d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * </p>
259d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     *
260d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @return <code>true</code> if anything has been modified, <code>false</code> otherwise
261d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
262d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean shouldBackUp() {
263d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        final Map<String, ?> allPrefs = getSharedPreferences().getAll();
264d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
265d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        for (final String key : allPrefs.keySet()) {
266d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            if (canBackup(key)) {
267d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy                return true;
268d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            }
269d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        }
270d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
271d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        return false;
272d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    }
273f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy
274f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy    /**
275f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy     * Notifies {@link BackupManager} that we have new data to back up.
276f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy     */
277f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy    protected void notifyBackupPreferenceChanged() {
278f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy        MailIntentService.broadcastBackupDataChanged(getContext());
279f9024cc52785c8740654dc89296a10a18da83077Scott Kennedy    }
280d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy}
281