/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package android.cts.backup.fullbackuponlyapp; import android.app.backup.BackupAgent; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.os.ParcelFileDescriptor; import android.util.Log; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * BackupAgent for test apps in {@link android.cts.backup.fullbackuponlyapp} package. * Performs backup/restore of the file provided by {@link FullBackupOnlyTest}. * * Implementation of key/value backup methods is based on the examples from * https://developer.android.com/guide/topics/data/keyvaluebackup.html */ public class FullBackupOnlyBackupAgent extends BackupAgent { private static final String TAG = "FullBackupOnlyBA"; private static final String BACKUP_KEY = "full_backup_only_key"; private static final int DEFAULT_VALUE = -1; /** Get the value saved in the shared preference and back it up. */ @Override public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { Log.i(TAG, "onBackup"); File fileToBackup = FullBackupOnlyTest.getKeyValueBackupFile(this); byte[] buffer = readFileToBytes(fileToBackup); // Send the data to the Backup Manager via the BackupDataOutput int len = buffer.length; data.writeEntityHeader(BACKUP_KEY, len); data.writeEntityData(buffer, len); } /** Get the value from backup and save it in the shared preference. */ @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { Log.i(TAG, "onRestore"); int value = DEFAULT_VALUE; // There should be only one entity, but the safest // way to consume it is using a while loop while (data.readNextHeader()) { String key = data.getKey(); int dataSize = data.getDataSize(); // If the key is ours (for saving top score). Note this key was used when // we wrote the backup entity header if (BACKUP_KEY.equals(key)) { // Copy data from BackupDataInput and write it into the file. byte[] dataBuf = new byte[dataSize]; data.readEntityData(dataBuf, 0, dataSize); File fileToRestore = FullBackupOnlyTest.getKeyValueBackupFile(this); try (BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(fileToRestore))) { bos.write(dataBuf, 0, dataBuf.length); } } else { // We don't know this entity key. Shouldn't happen. throw new RuntimeException("Unexpected key in the backup data"); } } // Finally, write to the state blob (newState) that describes the restored data FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); out.writeInt(value); } private byte[] readFileToBytes(File file) { int size = (int) file.length(); byte[] bytes = new byte[size]; try { BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); buf.read(bytes, 0, bytes.length); buf.close(); } catch (FileNotFoundException e) { throw new RuntimeException("Key/value file not found", e); } catch (IOException e) { throw new RuntimeException("Error reading key/value file", e); } return bytes; } }