1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.backup;
18 
19 import android.app.QueuedWork;
20 import android.content.Context;
21 import android.os.ParcelFileDescriptor;
22 import android.util.Log;
23 
24 import java.io.File;
25 
26 /**
27  * A helper class that can be used in conjunction with
28  * {@link android.app.backup.BackupAgentHelper} to manage the backup of
29  * {@link android.content.SharedPreferences}. Whenever a backup is performed, it
30  * will back up all named shared preferences that have changed since the last
31  * backup operation.
32  * <p>
33  * To use this class, the application's backup agent class should extend
34  * {@link android.app.backup.BackupAgentHelper}.  Then, in the agent's
35  * {@link BackupAgent#onCreate()} method, an instance of this class should be
36  * allocated and installed as a backup/restore handler within the BackupAgentHelper
37  * framework.  For example, an agent supporting backup and restore for
38  * an application with two groups of {@link android.content.SharedPreferences}
39  * data might look something like this:
40  * <pre>
41  * import android.app.backup.BackupAgentHelper;
42  * import android.app.backup.SharedPreferencesBackupHelper;
43  *
44  * public class MyBackupAgent extends BackupAgentHelper {
45  *     // The names of the SharedPreferences groups that the application maintains.  These
46  *     // are the same strings that are passed to {@link Context#getSharedPreferences(String, int)}.
47  *     static final String PREFS_DISPLAY = "displayprefs";
48  *     static final String PREFS_SCORES = "highscores";
49  *
50  *     // An arbitrary string used within the BackupAgentHelper implementation to
51  *     // identify the SharedPreferenceBackupHelper's data.
52  *     static final String MY_PREFS_BACKUP_KEY = "myprefs";
53  *
54  *     // Allocate a helper and install it.
55  *     public void onCreate() {
56  *         SharedPreferencesBackupHelper helper =
57  *                 new SharedPreferencesBackupHelper(this, PREFS_DISPLAY, PREFS_SCORES);
58  *         addHelper(MY_PREFS_BACKUP_KEY, helper);
59  *     }
60  * }</pre>
61  * <p>
62  * No further implementation is needed; the {@link BackupAgentHelper} mechanism automatically
63  * dispatches the
64  * {@link BackupAgent#onBackup(android.os.ParcelFileDescriptor, BackupDataOutput, android.os.ParcelFileDescriptor) BackupAgent.onBackup()}
65  * and
66  * {@link BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) BackupAgent.onRestore()}
67  * callbacks to the SharedPreferencesBackupHelper as appropriate.
68  */
69 public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper {
70     private static final String TAG = "SharedPreferencesBackupHelper";
71     private static final boolean DEBUG = false;
72 
73     private Context mContext;
74     private String[] mPrefGroups;
75 
76     /**
77      * Construct a helper for backing up and restoring the
78      * {@link android.content.SharedPreferences} under the given names.
79      *
80      * @param context The application {@link android.content.Context}
81      * @param prefGroups The names of each {@link android.content.SharedPreferences} file to
82      * back up
83      */
SharedPreferencesBackupHelper(Context context, String... prefGroups)84     public SharedPreferencesBackupHelper(Context context, String... prefGroups) {
85         super(context);
86 
87         mContext = context;
88         mPrefGroups = prefGroups;
89     }
90 
91     /**
92      * Backs up the configured {@link android.content.SharedPreferences} groups.
93      */
performBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)94     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
95             ParcelFileDescriptor newState) {
96         Context context = mContext;
97 
98         // If a SharedPreference has an outstanding write in flight,
99         // wait for it to finish flushing to disk.
100         QueuedWork.waitToFinish();
101 
102         // make filenames for the prefGroups
103         String[] prefGroups = mPrefGroups;
104         final int N = prefGroups.length;
105         String[] files = new String[N];
106         for (int i=0; i<N; i++) {
107             files[i] = context.getSharedPrefsFile(prefGroups[i]).getAbsolutePath();
108         }
109 
110         // go
111         performBackup_checked(oldState, data, newState, files, prefGroups);
112     }
113 
114     /**
115      * Restores one entity from the restore data stream to its proper shared
116      * preferences file store.
117      */
restoreEntity(BackupDataInputStream data)118     public void restoreEntity(BackupDataInputStream data) {
119         Context context = mContext;
120 
121         String key = data.getKey();
122         if (DEBUG) Log.d(TAG, "got entity '" + key + "' size=" + data.size());
123 
124         if (isKeyInList(key, mPrefGroups)) {
125             File f = context.getSharedPrefsFile(key).getAbsoluteFile();
126             writeFile(f, data);
127         }
128     }
129 }
130