Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2df7c15a authored by Android (Google) Code Review's avatar Android (Google) Code Review Committed by The Android Open Source Project
Browse files

am b505ae41: Merge change 5459 into donut

Merge commit 'b505ae41'

* commit 'b505ae41':
  Make the BackupHelperDispatcher properly handle multiple helpers.
parents 6d65c230 b505ae41
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public abstract class BackupAgent extends ContextWrapper {
     *                 here after writing the requested data to dataFd.
     */
    public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState);
             ParcelFileDescriptor newState) throws IOException;
    
    /**
     * The application is being restored from backup, and should replace any
@@ -120,6 +120,9 @@ public abstract class BackupAgent extends ContextWrapper {
            BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor());
            try {
                BackupAgent.this.onBackup(oldState, output, newState);
            } catch (IOException ex) {
                Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
                throw new RuntimeException(ex);
            } catch (RuntimeException ex) {
                Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
                throw ex;
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ public class BackupHelperAgent extends BackupAgent {

    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) {
             ParcelFileDescriptor newState) throws IOException {
        mDispatcher.performBackup(oldState, data, newState);
    }

+70 −6
Original line number Diff line number Diff line
@@ -19,7 +19,10 @@ package android.backup;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.FileDescriptor;
import java.util.TreeMap;
import java.util.Map;

@@ -27,6 +30,11 @@ import java.util.Map;
public class BackupHelperDispatcher {
    private static final String TAG = "BackupHelperDispatcher";

    private static class Header {
        int chunkSize; // not including the header
        String keyPrefix;
    }

    TreeMap<String,BackupHelper> mHelpers = new TreeMap<String,BackupHelper>();
    
    public BackupHelperDispatcher() {
@@ -36,13 +44,63 @@ public class BackupHelperDispatcher {
        mHelpers.put(keyPrefix, helper);
    }

    /** TODO: Make this save and restore the key prefix. */
    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) {
        // Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
        for (Map.Entry<String,BackupHelper> entry: mHelpers.entrySet()) {
            data.setKeyPrefix(entry.getKey());
            entry.getValue().performBackup(oldState, data, newState);
             ParcelFileDescriptor newState) throws IOException {
        // First, do the helpers that we've already done, since they're already in the state
        // file.
        int err;
        Header header = new Header();
        TreeMap<String,BackupHelper> helpers = (TreeMap<String,BackupHelper>)mHelpers.clone();
        FileDescriptor oldStateFD = null;
        FileDescriptor newStateFD = newState.getFileDescriptor();

        if (oldState != null) {
            oldStateFD = oldState.getFileDescriptor();
            while ((err = readHeader_native(header, oldStateFD)) >= 0) {
                if (err == 0) {
                    BackupHelper helper = helpers.get(header.keyPrefix);
                    Log.d(TAG, "handling existing helper '" + header.keyPrefix + "' " + helper);
                    if (helper != null) {
                        doOneBackup(oldState, data, newState, header, helper);
                        helpers.remove(header.keyPrefix);
                    } else {
                        skipChunk_native(oldStateFD, header.chunkSize);
                    }
                }
            }
        }

        // Then go through and do the rest that we haven't done.
        for (Map.Entry<String,BackupHelper> entry: helpers.entrySet()) {
            header.keyPrefix = entry.getKey();
            Log.d(TAG, "handling new helper '" + header.keyPrefix + "'");
            BackupHelper helper = entry.getValue();
            doOneBackup(oldState, data, newState, header, helper);
        }
    }

    private void doOneBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState, Header header, BackupHelper helper) 
            throws IOException {
        int err;
        FileDescriptor newStateFD = newState.getFileDescriptor();

        // allocate space for the header in the file
        int pos = allocateHeader_native(header, newStateFD);
        if (pos < 0) {
            throw new IOException("allocateHeader_native failed (error " + pos + ")");
        }

        data.setKeyPrefix(header.keyPrefix);

        // do the backup
        helper.performBackup(oldState, data, newState);

        // fill in the header (seeking back to pos).  The file pointer will be returned to
        // where it was at the end of performBackup.  Header.chunkSize will not be filled in.
        err = writeHeader_native(header, newStateFD, pos);
        if (err != 0) {
            throw new IOException("writeHeader_native failed (error " + err + ")");
        }
    }

@@ -83,5 +141,11 @@ public class BackupHelperDispatcher {
            helper.writeRestoreSnapshot(newState);
        }
    }

    private static native int readHeader_native(Header h, FileDescriptor fd);
    private static native int skipChunk_native(FileDescriptor fd, int bytesToSkip);

    private static native int allocateHeader_native(Header h, FileDescriptor fd);
    private static native int writeHeader_native(Header h, FileDescriptor fd, int pos);
}
+2 −1
Original line number Diff line number Diff line
@@ -122,7 +122,8 @@ LOCAL_SRC_FILES:= \
	com_android_internal_graphics_NativeUtils.cpp \
	android_backup_BackupDataInput.cpp \
	android_backup_BackupDataOutput.cpp \
	android_backup_FileBackupHelperBase.cpp
	android_backup_FileBackupHelperBase.cpp \
	android_backup_BackupHelperDispatcher.cpp

LOCAL_C_INCLUDES += \
	$(JNI_H_INCLUDE) \
+2 −0
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ extern int register_android_location_GpsLocationProvider(JNIEnv* env);
extern int register_android_backup_BackupDataInput(JNIEnv *env);
extern int register_android_backup_BackupDataOutput(JNIEnv *env);
extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);

static AndroidRuntime* gCurRuntime = NULL;

@@ -1241,6 +1242,7 @@ static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_android_backup_BackupDataInput),
    REG_JNI(register_android_backup_BackupDataOutput),
    REG_JNI(register_android_backup_FileBackupHelperBase),
    REG_JNI(register_android_backup_BackupHelperDispatcher),
};

/*
Loading