FullBackuppublic class FullBackup extends Object Global constant definitions et cetera related to the full-backup-to-fd
binary format. Nothing in this namespace is part of any API; it's all
hidden details of the current implementation gathered into one location. |
Fields Summary |
---|
static final String | TAG | public static final String | APK_TREE_TOKEN | public static final String | OBB_TREE_TOKEN | public static final String | ROOT_TREE_TOKEN | public static final String | DATA_TREE_TOKEN | public static final String | NO_BACKUP_TREE_TOKEN | public static final String | DATABASE_TREE_TOKEN | public static final String | SHAREDPREFS_TREE_TOKEN | public static final String | MANAGED_EXTERNAL_TREE_TOKEN | public static final String | CACHE_TREE_TOKEN | public static final String | SHARED_STORAGE_TOKEN | public static final String | APPS_PREFIX | public static final String | SHARED_PREFIX | public static final String | FULL_BACKUP_INTENT_ACTION | public static final String | FULL_RESTORE_INTENT_ACTION | public static final String | CONF_TOKEN_INTENT_EXTRA |
Methods Summary |
---|
public static native int | backupToTar(java.lang.String packageName, java.lang.String domain, java.lang.String linkdomain, java.lang.String rootpath, java.lang.String path, BackupDataOutput output)
| public static void | restoreFile(android.os.ParcelFileDescriptor data, long size, int type, long mode, long mtime, java.io.File outFile)Copy data from a socket to the given File location on permanent storage. The
modification time and access mode of the resulting file will be set if desired,
although group/all rwx modes will be stripped: the restored file will not be
accessible from outside the target application even if the original file was.
If the {@code type} parameter indicates that the result should be a directory,
the socket parameter may be {@code null}; even if it is valid, no data will be
read from it in this case.
If the {@code mode} argument is negative, then the resulting output file will not
have its access mode or last modification time reset as part of this operation.
if (type == BackupAgent.TYPE_DIRECTORY) {
// Canonically a directory has no associated content, so we don't need to read
// anything from the pipe in this case. Just create the directory here and
// drop down to the final metadata adjustment.
if (outFile != null) outFile.mkdirs();
} else {
FileOutputStream out = null;
// Pull the data from the pipe, copying it to the output file, until we're done
try {
if (outFile != null) {
File parent = outFile.getParentFile();
if (!parent.exists()) {
// in practice this will only be for the default semantic directories,
// and using the default mode for those is appropriate.
parent.mkdirs();
}
out = new FileOutputStream(outFile);
}
} catch (IOException e) {
Log.e(TAG, "Unable to create/open file " + outFile.getPath(), e);
}
byte[] buffer = new byte[32 * 1024];
final long origSize = size;
FileInputStream in = new FileInputStream(data.getFileDescriptor());
while (size > 0) {
int toRead = (size > buffer.length) ? buffer.length : (int)size;
int got = in.read(buffer, 0, toRead);
if (got <= 0) {
Log.w(TAG, "Incomplete read: expected " + size + " but got "
+ (origSize - size));
break;
}
if (out != null) {
try {
out.write(buffer, 0, got);
} catch (IOException e) {
// Problem writing to the file. Quit copying data and delete
// the file, but of course keep consuming the input stream.
Log.e(TAG, "Unable to write to file " + outFile.getPath(), e);
out.close();
out = null;
outFile.delete();
}
}
size -= got;
}
if (out != null) out.close();
}
// Now twiddle the state to match the backup, assuming all went well
if (mode >= 0 && outFile != null) {
try {
// explicitly prevent emplacement of files accessible by outside apps
mode &= 0700;
Os.chmod(outFile.getPath(), (int)mode);
} catch (ErrnoException e) {
e.rethrowAsIOException();
}
outFile.setLastModified(mtime);
}
|
|