blob: f14ce243696f62f1d270b55c2e83bbae27b42dc5 [file] [log] [blame]
Anton Philippovc1319132017-06-01 20:31:21 +01001/*
2 * Copyright (C) 2017 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
17package android.cts.backup.fullbackuponlyapp;
18
19import android.app.backup.BackupAgent;
20import android.app.backup.BackupDataInput;
21import android.app.backup.BackupDataOutput;
22
23import android.os.ParcelFileDescriptor;
24import android.util.Log;
25
26import java.io.BufferedInputStream;
27import java.io.BufferedOutputStream;
28import java.io.DataOutputStream;
29import java.io.File;
30import java.io.FileInputStream;
31import java.io.FileNotFoundException;
32import java.io.FileOutputStream;
33import java.io.IOException;
34
35/**
36 * BackupAgent for test apps in {@link android.cts.backup.fullbackuponlyapp} package.
37 * Performs backup/restore of the file provided by {@link FullBackupOnlyTest}.
38 *
39 * Implementation of key/value backup methods is based on the examples from
40 * https://developer.android.com/guide/topics/data/keyvaluebackup.html
41 */
42public class FullBackupOnlyBackupAgent extends BackupAgent {
43 private static final String TAG = "FullBackupOnlyBA";
44
45 private static final String BACKUP_KEY = "full_backup_only_key";
46 private static final int DEFAULT_VALUE = -1;
47
48 /** Get the value saved in the shared preference and back it up. */
49 @Override
50 public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
51 ParcelFileDescriptor newState) throws IOException {
52 Log.i(TAG, "onBackup");
53
54 File fileToBackup = FullBackupOnlyTest.getKeyValueBackupFile(this);
55 byte[] buffer = readFileToBytes(fileToBackup);
56
57 // Send the data to the Backup Manager via the BackupDataOutput
58 int len = buffer.length;
59 data.writeEntityHeader(BACKUP_KEY, len);
60 data.writeEntityData(buffer, len);
61 }
62
63 /** Get the value from backup and save it in the shared preference. */
64 @Override
65 public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
66 throws IOException {
67 Log.i(TAG, "onRestore");
68 int value = DEFAULT_VALUE;
69
70 // There should be only one entity, but the safest
71 // way to consume it is using a while loop
72 while (data.readNextHeader()) {
73 String key = data.getKey();
74 int dataSize = data.getDataSize();
75
76 // If the key is ours (for saving top score). Note this key was used when
77 // we wrote the backup entity header
78 if (BACKUP_KEY.equals(key)) {
79 // Copy data from BackupDataInput and write it into the file.
80 byte[] dataBuf = new byte[dataSize];
81 data.readEntityData(dataBuf, 0, dataSize);
82
83 File fileToRestore = FullBackupOnlyTest.getKeyValueBackupFile(this);
84
85 try (BufferedOutputStream bos = new BufferedOutputStream(
86 new FileOutputStream(fileToRestore))) {
87 bos.write(dataBuf, 0, dataBuf.length);
88 }
89 } else {
90 // We don't know this entity key. Shouldn't happen.
91 throw new RuntimeException("Unexpected key in the backup data");
92 }
93 }
94
95 // Finally, write to the state blob (newState) that describes the restored data
96 FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor());
97 DataOutputStream out = new DataOutputStream(outstream);
98 out.writeInt(value);
99 }
100
101
102 private byte[] readFileToBytes(File file) {
103 int size = (int) file.length();
104 byte[] bytes = new byte[size];
105 try {
106 BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
107 buf.read(bytes, 0, bytes.length);
108 buf.close();
109 } catch (FileNotFoundException e) {
110 throw new RuntimeException("Key/value file not found", e);
111 } catch (IOException e) {
112 throw new RuntimeException("Error reading key/value file", e);
113 }
114 return bytes;
115 }
116}