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.content.Context; 20 import android.os.ParcelFileDescriptor; 21 import android.util.Log; 22 23 import java.io.File; 24 import java.io.FileDescriptor; 25 26 /** 27 * Base class for the {@link android.app.backup.FileBackupHelper} implementation. 28 */ 29 class FileBackupHelperBase { 30 private static final String TAG = "FileBackupHelperBase"; 31 32 long mPtr; 33 Context mContext; 34 boolean mExceptionLogged; 35 FileBackupHelperBase(Context context)36 FileBackupHelperBase(Context context) { 37 mPtr = ctor(); 38 mContext = context; 39 } 40 finalize()41 protected void finalize() throws Throwable { 42 try { 43 dtor(mPtr); 44 } finally { 45 super.finalize(); 46 } 47 } 48 49 /** 50 * Check the parameters so the native code doesn't have to throw all the exceptions 51 * since it's easier to do that from Java. 52 */ performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState, String[] files, String[] keys)53 static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data, 54 ParcelFileDescriptor newState, String[] files, String[] keys) { 55 if (files.length == 0) { 56 return; 57 } 58 // files must be all absolute paths 59 for (String f: files) { 60 if (f.charAt(0) != '/') { 61 throw new RuntimeException("files must have all absolute paths: " + f); 62 } 63 } 64 // the length of files and keys must be the same 65 if (files.length != keys.length) { 66 throw new RuntimeException("files.length=" + files.length 67 + " keys.length=" + keys.length); 68 } 69 // oldStateFd can be null 70 FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null; 71 FileDescriptor newStateFd = newState.getFileDescriptor(); 72 if (newStateFd == null) { 73 throw new NullPointerException(); 74 } 75 76 int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys); 77 78 if (err != 0) { 79 // TODO: more here 80 throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err)); 81 } 82 } 83 writeFile(File f, BackupDataInputStream in)84 boolean writeFile(File f, BackupDataInputStream in) { 85 int result = -1; 86 87 // Create the enclosing directory. 88 File parent = f.getParentFile(); 89 parent.mkdirs(); 90 91 result = writeFile_native(mPtr, f.getAbsolutePath(), in.mData.mBackupReader); 92 if (result != 0) { 93 // Bail on this entity. Only log one failure per helper object. 94 if (!mExceptionLogged) { 95 Log.e(TAG, "Failed restoring file '" + f + "' for app '" 96 + mContext.getPackageName() + "\' result=0x" 97 + Integer.toHexString(result)); 98 mExceptionLogged = true; 99 } 100 } 101 return (result == 0); 102 } 103 writeNewStateDescription(ParcelFileDescriptor fd)104 public void writeNewStateDescription(ParcelFileDescriptor fd) { 105 int result = writeSnapshot_native(mPtr, fd.getFileDescriptor()); 106 // TODO: Do something with the error. 107 } 108 isKeyInList(String key, String[] list)109 boolean isKeyInList(String key, String[] list) { 110 for (String s: list) { 111 if (s.equals(key)) { 112 return true; 113 } 114 } 115 return false; 116 } 117 ctor()118 private static native long ctor(); dtor(long ptr)119 private static native void dtor(long ptr); 120 performBackup_native(FileDescriptor oldState, long data, FileDescriptor newState, String[] files, String[] keys)121 native private static int performBackup_native(FileDescriptor oldState, 122 long data, FileDescriptor newState, String[] files, String[] keys); writeFile_native(long ptr, String filename, long backupReader)123 private static native int writeFile_native(long ptr, String filename, long backupReader); writeSnapshot_native(long ptr, FileDescriptor fd)124 private static native int writeSnapshot_native(long ptr, FileDescriptor fd); 125 } 126 127 128