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