FileDocCategorySizeDatePackage
BackupHelperDispatcher.javaAPI DocAndroid 5.1 API5718Thu Mar 12 22:22:10 GMT 2015android.app.backup

BackupHelperDispatcher

public class BackupHelperDispatcher extends Object
hide

Fields Summary
private static final String
TAG
TreeMap
mHelpers
Constructors Summary
public BackupHelperDispatcher()

    
      
    
Methods Summary
public voidaddHelper(java.lang.String keyPrefix, BackupHelper helper)

        mHelpers.put(keyPrefix, helper);
    
private static native intallocateHeader_native(android.app.backup.BackupHelperDispatcher$Header h, java.io.FileDescriptor fd)

private voiddoOneBackup(android.os.ParcelFileDescriptor oldState, BackupDataOutput data, android.os.ParcelFileDescriptor newState, android.app.backup.BackupHelperDispatcher$Header header, BackupHelper helper)

        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 + ")");
        }
    
public voidperformBackup(android.os.ParcelFileDescriptor oldState, BackupDataOutput data, android.os.ParcelFileDescriptor newState)

        // 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;

        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);
        }
    
public voidperformRestore(BackupDataInput input, int appVersionCode, android.os.ParcelFileDescriptor newState)

        boolean alreadyComplained = false;

        BackupDataInputStream stream = new BackupDataInputStream(input);
        while (input.readNextHeader()) {

            String rawKey = input.getKey();
            int pos = rawKey.indexOf(':");
            if (pos > 0) {
                String prefix = rawKey.substring(0, pos);
                BackupHelper helper = mHelpers.get(prefix);
                if (helper != null) {
                    stream.dataSize = input.getDataSize();
                    stream.key = rawKey.substring(pos+1);
                    helper.restoreEntity(stream);
                } else {
                    if (!alreadyComplained) {
                        Log.w(TAG, "Couldn't find helper for: '" + rawKey + "'");
                        alreadyComplained = true;
                    }
                }
            } else {
                if (!alreadyComplained) {
                    Log.w(TAG, "Entity with no prefix: '" + rawKey + "'");
                    alreadyComplained = true;
                }
            }
            input.skipEntityData(); // In case they didn't consume the data.
        }

        // Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
        for (BackupHelper helper: mHelpers.values()) {
            helper.writeNewStateDescription(newState);
        }
    
private static native intreadHeader_native(android.app.backup.BackupHelperDispatcher$Header h, java.io.FileDescriptor fd)

private static native intskipChunk_native(java.io.FileDescriptor fd, int bytesToSkip)

private static native intwriteHeader_native(android.app.backup.BackupHelperDispatcher$Header h, java.io.FileDescriptor fd, int pos)