summaryrefslogtreecommitdiffstats
path: root/src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java')
-rw-r--r--src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java b/src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java
new file mode 100644
index 0000000..77ed6a3
--- /dev/null
+++ b/src/com/google/android/libraries/backup/shadow/FileBackupHelperSimulator.java
@@ -0,0 +1,157 @@
+package com.google.android.libraries.backup.shadow;
+
+import android.app.backup.FileBackupHelper;
+import android.content.Context;
+import android.util.Log;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Files;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Representation of {@link FileBackupHelper} configuration used for testing. This class simulates
+ * backing up and restoring files by storing their contents in memory.
+ *
+ * <p>{@see BackupAgentHelperShadow}
+ */
+public class FileBackupHelperSimulator extends BackupHelperSimulator {
+ private static final String TAG = "FileBackupHelperSimulat";
+
+ /** Filenames which should be backed up/restored. */
+ private final Set<String> fileNames;
+
+ private FileBackupHelperSimulator(String keyPrefix, Set<String> fileNames) {
+ super(keyPrefix);
+ this.fileNames = Preconditions.checkNotNull(fileNames);
+ }
+
+ public static FileBackupHelperSimulator fromFileNames(String keyPrefix, Set<String> fileNames) {
+ return new FileBackupHelperSimulator(keyPrefix, fileNames);
+ }
+
+ public static FileBackupHelperSimulator fromHelper(String keyPrefix, FileBackupHelper helper) {
+ return new FileBackupHelperSimulator(keyPrefix, extractFileNamesFromHelper(helper));
+ }
+
+ @VisibleForTesting
+ static Set<String> extractFileNamesFromHelper(FileBackupHelper helper) {
+ try {
+ Field filesField = FileBackupHelper.class.getDeclaredField("mFiles");
+ filesField.setAccessible(true);
+ return ImmutableSet.copyOf((String[]) filesField.get(helper));
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /** Collection of backed up files. */
+ public static class FilesBackupData {
+ /** Map from file names to their backed up contents. */
+ private final Map<String, FileBackupContents> files;
+
+ public FilesBackupData(Map<String, FileBackupContents> files) {
+ this.files = Preconditions.checkNotNull(files);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof FilesBackupData && files.equals(((FilesBackupData) obj).files);
+ }
+
+ @Override
+ public int hashCode() {
+ return files.hashCode();
+ }
+
+ public Map<String, FileBackupContents> getFiles() {
+ return files;
+ }
+ }
+
+ /** Single backed up file. */
+ public static class FileBackupContents {
+ private final byte[] bytes;
+
+ public FileBackupContents(byte[] bytes) {
+ this.bytes = Preconditions.checkNotNull(bytes);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof FileBackupContents
+ && Arrays.equals(bytes, ((FileBackupContents) obj).bytes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(bytes);
+ }
+
+ public static FileBackupContents readFromFile(File file) {
+ return new FileBackupContents(readBytesFromFile(file));
+ }
+
+ public void writeToFile(File file) {
+ writeBytesToFile(file, bytes);
+ }
+
+ public static byte[] readBytesFromFile(File file) {
+ try {
+ return Files.toByteArray(file);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public static void writeBytesToFile(File file, byte[] bytes) {
+ try {
+ Files.write(bytes, file);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ @Override
+ public Object backup(Context context) {
+ File base = context.getFilesDir();
+ ImmutableMap.Builder<String, FileBackupContents> dataToBackupBuilder = ImmutableMap.builder();
+ for (String fileName : fileNames) {
+ File file = new File(base, fileName);
+ if (!file.exists()) {
+ Log.w(TAG, "File \"" + fileName + "\" not found by helper \"" + keyPrefix + "\".");
+ continue;
+ }
+ dataToBackupBuilder.put(fileName, FileBackupContents.readFromFile(file));
+ }
+ return new FilesBackupData(dataToBackupBuilder.build());
+ }
+
+ @Override
+ public void restore(Context context, Object data) {
+ if (!(data instanceof FilesBackupData)) {
+ throw new IllegalArgumentException("Invalid type of files to restore in helper \""
+ + keyPrefix + "\": " + data.getClass());
+ }
+
+ File base = context.getFilesDir();
+ Map<String, FileBackupContents> dataToRestore = ((FilesBackupData) data).getFiles();
+ for (Map.Entry<String, FileBackupContents> restoreEntry : dataToRestore.entrySet()) {
+ String fileName = restoreEntry.getKey();
+ if (!fileNames.contains(fileName)) {
+ Log.w(TAG, "File \"" + fileName + "\" ignored by helper \"" + keyPrefix + "\".");
+ continue;
+ }
+ FileBackupContents contents = restoreEntry.getValue();
+ File file = new File(base, fileName);
+ contents.writeToFile(file);
+ }
+ }
+}