blob: 82f83f9b7494fe6fc923ebea258ca8732f24063f [file] [log] [blame]
/*
* Copyright (C) 2019 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 com.android.server.backup.encryption.tasks;
import static com.android.internal.util.Preconditions.checkArgument;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.backup.encryption.FullRestoreDownloader;
import com.android.server.backup.encryption.FullRestoreDownloader.FinishType;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Reads a stream from a {@link FullRestoreDownloader} and writes it to a file for consumption by
* {@link BackupFileDecryptorTask}.
*/
public class FullRestoreToFileTask {
/**
* Maximum number of bytes which the framework can request from the full restore data stream in
* one call to {@link BackupTransport#getNextFullRestoreDataChunk}.
*/
public static final int MAX_BYTES_FULL_RESTORE_CHUNK = 1024 * 32;
/** Returned when the end of a backup stream has been reached. */
private static final int END_OF_STREAM = -1;
private final FullRestoreDownloader mFullRestoreDownloader;
private final int mBufferSize;
/**
* Constructs a new instance which reads from the given package wrapper, using a buffer of size
* {@link #MAX_BYTES_FULL_RESTORE_CHUNK}.
*/
public FullRestoreToFileTask(FullRestoreDownloader fullRestoreDownloader) {
this(fullRestoreDownloader, MAX_BYTES_FULL_RESTORE_CHUNK);
}
@VisibleForTesting
FullRestoreToFileTask(FullRestoreDownloader fullRestoreDownloader, int bufferSize) {
checkArgument(bufferSize > 0, "Buffer must have positive size");
this.mFullRestoreDownloader = fullRestoreDownloader;
this.mBufferSize = bufferSize;
}
/**
* Downloads the backup file from the server and writes it to the given file.
*
* <p>At the end of the download (success or failure), closes the connection and sends a
* Clearcut log.
*/
public void restoreToFile(File targetFile) throws IOException {
try (BufferedOutputStream outputStream =
new BufferedOutputStream(new FileOutputStream(targetFile))) {
byte[] buffer = new byte[mBufferSize];
int bytesRead = mFullRestoreDownloader.readNextChunk(buffer);
while (bytesRead != END_OF_STREAM) {
outputStream.write(buffer, /* off=*/ 0, bytesRead);
bytesRead = mFullRestoreDownloader.readNextChunk(buffer);
}
outputStream.flush();
mFullRestoreDownloader.finish(FinishType.FINISHED);
} catch (IOException e) {
mFullRestoreDownloader.finish(FinishType.TRANSFER_FAILURE);
throw e;
}
}
}