1b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato/*
2b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Copyright (C) 2009 The Android Open Source Project
3b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
4b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * you may not use this file except in compliance with the License.
6b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * You may obtain a copy of the License at
7b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
8b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
10b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Unless required by applicable law or agreed to in writing, software
11b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * See the License for the specific language governing permissions and
14b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * limitations under the License.
15b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato */
16b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup;
18b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
19b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport android.content.Context;
20b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport android.os.ParcelFileDescriptor;
21290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onoratoimport android.util.Log;
22b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
2323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoimport java.io.File;
24b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
25e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate/**
26d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A helper class that can be used in conjunction with
27cc84c69726507a85116f5664e20e2ebfac76edbeChristopher Tate * {@link android.app.backup.BackupAgentHelper} to manage the backup of a set of
285a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * files. Whenever backup is performed, all files changed since the last backup
29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * will be saved in their entirety. When backup first occurs,
30d17da43c82c4edb97514d6138bc208eeba321636Scott Main * every file in the list provided to {@link #FileBackupHelper} will be backed up.
315a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
324e14a829129feee14ebe453f61a124784c870610Christopher Tate * During restore, if the helper encounters data for a file that was not
334e14a829129feee14ebe453f61a124784c870610Christopher Tate * specified when the FileBackupHelper object was constructed, that data
344e14a829129feee14ebe453f61a124784c870610Christopher Tate * will be ignored.
35d17da43c82c4edb97514d6138bc208eeba321636Scott Main * <p class="note"><strong>Note:</strong> This should be
36d17da43c82c4edb97514d6138bc208eeba321636Scott Main * used only with small configuration files, not large binary files.
37e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */
3806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratopublic class FileBackupHelper extends FileBackupHelperBase implements BackupHelper {
39290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato    private static final String TAG = "FileBackupHelper";
40436344ae12c819f58306ceb94241a266141e1218Christopher Tate    private static final boolean DEBUG = false;
41290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato
421cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    Context mContext;
4306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    File mFilesDir;
4406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    String[] mFiles;
451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
46e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
47e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Construct a helper to manage backup/restore of entire files within the
48e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * application's data directory hierarchy.
49e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
50e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param context The backup agent's Context object
51e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param files A list of the files to be backed up or restored.
52e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
5306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    public FileBackupHelper(Context context, String... files) {
5406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        super(context);
551cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
561cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        mContext = context;
5706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        mFilesDir = context.getFilesDir();
5806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        mFiles = files;
591cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
601cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
61b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato    /**
625a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * Based on <code>oldState</code>, determine which of the files from the
635a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * application's data directory need to be backed up, write them to the data
645a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * stream, and fill in <code>newState</code> with the state as it exists
655a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * now. When <code>oldState</code> is <code>null</code>, all the files will
665a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * be backed up.
675a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * <p>
684e14a829129feee14ebe453f61a124784c870610Christopher Tate     * This should only be called directly from within the {@link BackupAgentHelper}
694e14a829129feee14ebe453f61a124784c870610Christopher Tate     * implementation. See
704528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate     * {@link android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
715a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root     * for a description of parameter meanings.
72b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato     */
731cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
7406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato            ParcelFileDescriptor newState) {
751cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        // file names
7606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        String[] files = mFiles;
771cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        File base = mContext.getFilesDir();
7823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        final int N = files.length;
7923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        String[] fullPaths = new String[N];
8023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        for (int i=0; i<N; i++) {
8123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            fullPaths[i] = (new File(base, files[i])).getAbsolutePath();
8223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
831cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
841cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        // go
8506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        performBackup_checked(oldState, data, newState, fullPaths, files);
861cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
871cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
88e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
89e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Restore one record [representing a single file] from the restore dataset.
904e14a829129feee14ebe453f61a124784c870610Christopher Tate     * <p>
914e14a829129feee14ebe453f61a124784c870610Christopher Tate     * This should only be called directly from within the {@link BackupAgentHelper}
924e14a829129feee14ebe453f61a124784c870610Christopher Tate     * implementation.
93e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
9406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    public void restoreEntity(BackupDataInputStream data) {
95436344ae12c819f58306ceb94241a266141e1218Christopher Tate        if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
9606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        String key = data.getKey();
9706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        if (isKeyInList(key, mFiles)) {
9806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato            File f = new File(mFilesDir, key);
9906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato            writeFile(f, data);
100b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato        }
101b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato    }
102b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato}
10306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato
104