FileBackupHelperBase.java revision 3f64f8d8fc05189777e83b4efd3882cbc661fdeb
106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato/* 206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * Copyright (C) 2009 The Android Open Source Project 306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * 406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * you may not use this file except in compliance with the License. 606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * You may obtain a copy of the License at 706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * 806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * 1006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * Unless required by applicable law or agreed to in writing, software 1106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 1206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * See the License for the specific language governing permissions and 1406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato * limitations under the License. 1506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato */ 1606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup; 1806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 1906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoimport android.content.Context; 2006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoimport android.os.ParcelFileDescriptor; 2106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoimport android.util.Log; 2206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 2306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoimport java.io.File; 2406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoimport java.io.FileDescriptor; 2506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 265a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root/** 274528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * Base class for the {@link android.app.backup.FileBackupHelper} implementation. 285a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root */ 2906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onoratoclass FileBackupHelperBase { 305a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root private static final String TAG = "FileBackupHelperBase"; 3106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 3206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato int mPtr; 3306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato Context mContext; 3406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato boolean mExceptionLogged; 3506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 3606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato FileBackupHelperBase(Context context) { 3706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato mPtr = ctor(); 3806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato mContext = context; 3906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 4006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 4106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato protected void finalize() throws Throwable { 4206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato try { 4306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato dtor(mPtr); 4406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } finally { 4506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato super.finalize(); 4606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 4706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 4806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 4906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato /** 505a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * Check the parameters so the native code doesn't have to throw all the exceptions 515a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * since it's easier to do that from Java. 5206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato */ 5306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data, 5406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato ParcelFileDescriptor newState, String[] files, String[] keys) { 5506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (files.length == 0) { 5606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato return; 5706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 5806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // files must be all absolute paths 5906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato for (String f: files) { 6006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (f.charAt(0) != '/') { 6106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato throw new RuntimeException("files must have all absolute paths: " + f); 6206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 6306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 6406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // the length of files and keys must be the same 6506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (files.length != keys.length) { 6606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato throw new RuntimeException("files.length=" + files.length 6706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato + " keys.length=" + keys.length); 6806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 6906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // oldStateFd can be null 7006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null; 7106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato FileDescriptor newStateFd = newState.getFileDescriptor(); 7206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (newStateFd == null) { 7306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato throw new NullPointerException(); 7406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 7506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 7606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys); 7706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 7806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (err != 0) { 7906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // TODO: more here 8006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err)); 8106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 8206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 8306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 843f64f8d8fc05189777e83b4efd3882cbc661fdebChristopher Tate boolean writeFile(File f, BackupDataInputStream in) { 8506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato int result = -1; 8606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 8706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // Create the enclosing directory. 8806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato File parent = f.getParentFile(); 8906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato parent.mkdirs(); 9006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 91e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate result = writeFile_native(mPtr, f.getAbsolutePath(), in.mData.mBackupReader); 9206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (result != 0) { 9306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // Bail on this entity. Only log one failure per helper object. 9406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (!mExceptionLogged) { 9506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato Log.e(TAG, "Failed restoring file '" + f + "' for app '" 9606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato + mContext.getPackageName() + "\' result=0x" 9706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato + Integer.toHexString(result)); 9806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato mExceptionLogged = true; 9906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 10006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 1013f64f8d8fc05189777e83b4efd3882cbc661fdebChristopher Tate return (result == 0); 10206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 10306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 104e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate public void writeNewStateDescription(ParcelFileDescriptor fd) { 10506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato int result = writeSnapshot_native(mPtr, fd.getFileDescriptor()); 10606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato // TODO: Do something with the error. 10706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 10806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 10906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato boolean isKeyInList(String key, String[] list) { 11006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato for (String s: list) { 11106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato if (s.equals(key)) { 11206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato return true; 11306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 11406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 11506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato return false; 11606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 11706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 11806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato private static native int ctor(); 11906290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato private static native void dtor(int ptr); 12006290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 12106290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato native private static int performBackup_native(FileDescriptor oldState, 12206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato int data, FileDescriptor newState, String[] files, String[] keys); 12306290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 12406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato private static native int writeFile_native(int ptr, String filename, int backupReader); 12506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato private static native int writeSnapshot_native(int ptr, FileDescriptor fd); 12606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato} 12706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 12806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 129