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