The output file descriptor was not being closed after each chunk was written.
1. The output stream will no longer be stored in the restore state.
2. The output file descriptor will be closed after a chunk is transferred.
This commit is contained in:
Steve Soltys 2017-11-08 23:21:27 -05:00
parent 09ff3ba493
commit 0bd1596056
3 changed files with 17 additions and 37 deletions

View file

@ -13,14 +13,7 @@ public class ConfigurableBackupTransportService extends Service {
private static ConfigurableBackupTransport backupTransport; private static ConfigurableBackupTransport backupTransport;
public ConfigurableBackupTransportService() { public ConfigurableBackupTransportService() {
backupTransport = null; backupTransport = new ConfigurableBackupTransport();
}
@Override
public void onCreate() {
if (backupTransport == null) {
backupTransport = new ConfigurableBackupTransport();
}
} }
@Override @Override

View file

@ -85,7 +85,8 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
ZipInputStream inputStream = buildInputStream(inputFileDescriptor); ZipInputStream inputStream = buildInputStream(inputFileDescriptor);
Optional<ZipEntry> zipEntry = seekToEntry(inputStream, fileName); Optional<ZipEntry> zipEntry = seekToEntry(inputStream, fileName);
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(inputFileDescriptor);
IoUtils.closeQuietly(inputStream);
return zipEntry.isPresent(); return zipEntry.isPresent();
} }
@ -120,10 +121,9 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
"getRestoreData() for non-key/value dataset"); "getRestoreData() for non-key/value dataset");
PackageInfo packageInfo = restoreState.getPackages()[restoreState.getPackageIndex()]; PackageInfo packageInfo = restoreState.getPackages()[restoreState.getPackageIndex()];
BackupDataOutput backupDataOutput = new BackupDataOutput(outputFileDescriptor.getFileDescriptor());
try { try {
return transferIncrementalRestoreData(packageInfo.packageName, backupDataOutput); return transferIncrementalRestoreData(packageInfo.packageName, outputFileDescriptor);
} catch (Exception ex) { } catch (Exception ex) {
Log.e(TAG, "Unable to read backup records: ", ex); Log.e(TAG, "Unable to read backup records: ", ex);
@ -131,10 +131,12 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
} }
} }
private int transferIncrementalRestoreData(String packageName, BackupDataOutput backupDataOutput) private int transferIncrementalRestoreData(String packageName, ParcelFileDescriptor outputFileDescriptor)
throws IOException, InvalidAlgorithmParameterException, InvalidKeyException { throws IOException, InvalidAlgorithmParameterException, InvalidKeyException {
ParcelFileDescriptor inputFileDescriptor = buildInputFileDescriptor(); ParcelFileDescriptor inputFileDescriptor = buildInputFileDescriptor();
ZipInputStream inputStream = buildInputStream(inputFileDescriptor); ZipInputStream inputStream = buildInputStream(inputFileDescriptor);
BackupDataOutput backupDataOutput = new BackupDataOutput(outputFileDescriptor.getFileDescriptor());
Optional<ZipEntry> zipEntryOptional = seekToEntry(inputStream, Optional<ZipEntry> zipEntryOptional = seekToEntry(inputStream,
configuration.getIncrementalBackupDirectory() + packageName); configuration.getIncrementalBackupDirectory() + packageName);
@ -150,7 +152,8 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
zipEntryOptional = seekToEntry(inputStream, configuration.getIncrementalBackupDirectory() + packageName); zipEntryOptional = seekToEntry(inputStream, configuration.getIncrementalBackupDirectory() + packageName);
} }
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(inputFileDescriptor);
IoUtils.closeQuietly(outputFileDescriptor);
return TRANSPORT_OK; return TRANSPORT_OK;
} }
@ -172,30 +175,26 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
restoreState.setInputStream(inputStream); restoreState.setInputStream(inputStream);
if (!seekToEntry(inputStream, configuration.getFullBackupDirectory() + name).isPresent()) { if (!seekToEntry(inputStream, configuration.getFullBackupDirectory() + name).isPresent()) {
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(inputFileDescriptor);
IoUtils.closeQuietly(outputFileDescriptor);
return TRANSPORT_PACKAGE_REJECTED; return TRANSPORT_PACKAGE_REJECTED;
} }
} catch (IOException ex) { } catch (IOException ex) {
Log.e(TAG, "Unable to read archive for " + name, ex); Log.e(TAG, "Unable to read archive for " + name, ex);
if (inputFileDescriptor != null) { IoUtils.closeQuietly(inputFileDescriptor);
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(outputFileDescriptor);
}
return TRANSPORT_PACKAGE_REJECTED; return TRANSPORT_PACKAGE_REJECTED;
} }
} }
if (restoreState.getOutputStream() == null) {
restoreState.setOutputStream(new FileOutputStream(outputFileDescriptor.getFileDescriptor()));
}
return transferFullRestoreData(outputFileDescriptor); return transferFullRestoreData(outputFileDescriptor);
} }
private int transferFullRestoreData(ParcelFileDescriptor outputFileDescriptor) { private int transferFullRestoreData(ParcelFileDescriptor outputFileDescriptor) {
ZipInputStream inputStream = restoreState.getInputStream(); ZipInputStream inputStream = restoreState.getInputStream();
OutputStream outputStream = restoreState.getOutputStream(); OutputStream outputStream = new FileOutputStream(outputFileDescriptor.getFileDescriptor());
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int bytesRead = NO_MORE_DATA; int bytesRead = NO_MORE_DATA;
@ -217,14 +216,14 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
if (bytesRead == NO_MORE_DATA) { if (bytesRead == NO_MORE_DATA) {
if (restoreState.getInputFileDescriptor() != null) { if (restoreState.getInputFileDescriptor() != null) {
IoUtils.closeQuietly(restoreState.getInputFileDescriptor().getFileDescriptor()); IoUtils.closeQuietly(restoreState.getInputFileDescriptor());
} }
IoUtils.closeQuietly(outputFileDescriptor.getFileDescriptor());
restoreState.setInputFileDescriptor(null); restoreState.setInputFileDescriptor(null);
restoreState.setInputStream(null); restoreState.setInputStream(null);
restoreState.setOutputStream(null);
} }
IoUtils.closeQuietly(outputFileDescriptor);
} }
return bytesRead; return bytesRead;
@ -260,7 +259,6 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
Preconditions.checkState(restoreState.getRestoreType() == TYPE_FULL_STREAM); Preconditions.checkState(restoreState.getRestoreType() == TYPE_FULL_STREAM);
IoUtils.closeQuietly(restoreState.getInputFileDescriptor()); IoUtils.closeQuietly(restoreState.getInputFileDescriptor());
IoUtils.closeQuietly(restoreState.getOutputStream());
restoreState = null; restoreState = null;
} }
} }

View file

@ -3,7 +3,6 @@ package com.stevesoltys.backup.transport.component.provider;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import java.io.OutputStream;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
/** /**
@ -21,8 +20,6 @@ class ContentProviderRestoreState {
private ZipInputStream inputStream; private ZipInputStream inputStream;
private OutputStream outputStream;
PackageInfo[] getPackages() { PackageInfo[] getPackages() {
return packages; return packages;
} }
@ -47,14 +44,6 @@ class ContentProviderRestoreState {
this.restoreType = restoreType; this.restoreType = restoreType;
} }
OutputStream getOutputStream() {
return outputStream;
}
void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
ZipInputStream getInputStream() { ZipInputStream getInputStream() {
return inputStream; return inputStream;
} }