Home | History | Annotate | Download | only in backup
      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 
     36     FileBackupHelperBase(Context context) {
     37         mPtr = ctor();
     38         mContext = context;
     39     }
     40 
     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      */
     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 
     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 
    104     public void writeNewStateDescription(ParcelFileDescriptor fd) {
    105         int result = writeSnapshot_native(mPtr, fd.getFileDescriptor());
    106         // TODO: Do something with the error.
    107     }
    108 
    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 
    118     private static native long ctor();
    119     private static native void dtor(long ptr);
    120 
    121     native private static int performBackup_native(FileDescriptor oldState,
    122             long data, FileDescriptor newState, String[] files, String[] keys);
    123     private static native int writeFile_native(long ptr, String filename, long backupReader);
    124     private static native int writeSnapshot_native(long ptr, FileDescriptor fd);
    125 }
    126 
    127 
    128