Merge "Binding on-demand #2: PerformFullTransportBackupTask usage"

This commit is contained in:
TreeHugger Robot
2017-11-24 13:31:05 +00:00
committed by Android (Google) Code Review
6 changed files with 117 additions and 29 deletions

View File

@@ -2158,8 +2158,17 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter
mFullBackupQueue.remove(0);
CountDownLatch latch = new CountDownLatch(1);
String[] pkg = new String[]{entry.packageName};
mRunningFullBackupTask = new PerformFullTransportBackupTask(this, null, pkg, true,
scheduledJob, latch, null, null, false /* userInitiated */);
mRunningFullBackupTask = PerformFullTransportBackupTask.newWithCurrentTransport(
this,
/* observer */ null,
pkg,
/* updateSchedule */ true,
scheduledJob,
latch,
/* backupObserver */ null,
/* monitor */ null,
/* userInitiated */ false,
"BMS.beginFullBackup()");
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
mWakelock.acquire();
(new Thread(mRunningFullBackupTask)).start();
@@ -2513,8 +2522,17 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter
final long oldId = Binder.clearCallingIdentity();
try {
CountDownLatch latch = new CountDownLatch(1);
PerformFullTransportBackupTask task = new PerformFullTransportBackupTask(this, null,
pkgNames, false, null, latch, null, null, false /* userInitiated */);
Runnable task = PerformFullTransportBackupTask.newWithCurrentTransport(
this,
/* observer */ null,
pkgNames,
/* updateSchedule */ false,
/* runningJob */ null,
latch,
/* backupObserver */ null,
/* monitor */ null,
/* userInitiated */ false,
"BMS.fullTransportBackup()");
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
mWakelock.acquire();
(new Thread(task, "full-transport-master")).start();

View File

@@ -24,6 +24,7 @@ import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_B
import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
import android.annotation.Nullable;
import android.app.IBackupAgent;
import android.app.backup.BackupManager;
import android.app.backup.BackupManagerMonitor;
@@ -46,7 +47,11 @@ import com.android.server.EventLogTags;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.FullBackupJob;
import com.android.server.backup.RefactoredBackupManagerService;
import com.android.server.backup.TransportManager;
import com.android.server.backup.internal.OnTaskFinishedListener;
import com.android.server.backup.internal.Operation;
import com.android.server.backup.transport.TransportClient;
import com.android.server.backup.transport.TransportNotAvailableException;
import com.android.server.backup.utils.AppBackupUtils;
import com.android.server.backup.utils.BackupManagerMonitorUtils;
import com.android.server.backup.utils.BackupObserverUtils;
@@ -89,6 +94,36 @@ import java.util.concurrent.atomic.AtomicLong;
* mBackupRunner.getBackupResultBlocking().
*/
public class PerformFullTransportBackupTask extends FullBackupTask implements BackupRestoreTask {
public static PerformFullTransportBackupTask newWithCurrentTransport(
RefactoredBackupManagerService backupManagerService,
IFullBackupRestoreObserver observer,
String[] whichPackages,
boolean updateSchedule,
FullBackupJob runningJob,
CountDownLatch latch,
IBackupObserver backupObserver,
IBackupManagerMonitor monitor,
boolean userInitiated,
String caller) {
TransportManager transportManager = backupManagerService.getTransportManager();
TransportClient transportClient = transportManager.getCurrentTransportClient(caller);
OnTaskFinishedListener listener =
listenerCaller ->
transportManager.disposeOfTransportClient(transportClient, listenerCaller);
return new PerformFullTransportBackupTask(
backupManagerService,
transportClient,
observer,
whichPackages,
updateSchedule,
runningJob,
latch,
backupObserver,
monitor,
listener,
userInitiated);
}
private static final String TAG = "PFTBT";
private RefactoredBackupManagerService backupManagerService;
@@ -102,9 +137,10 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
IBackupObserver mBackupObserver;
IBackupManagerMonitor mMonitor;
boolean mUserInitiated;
private volatile IBackupTransport mTransport;
SinglePackageBackupRunner mBackupRunner;
private final int mBackupRunnerOpToken;
private final OnTaskFinishedListener mListener;
private final TransportClient mTransportClient;
// This is true when a backup operation for some package is in progress.
private volatile boolean mIsDoingBackup;
@@ -112,18 +148,22 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
private final int mCurrentOpToken;
public PerformFullTransportBackupTask(RefactoredBackupManagerService backupManagerService,
TransportClient transportClient,
IFullBackupRestoreObserver observer,
String[] whichPackages, boolean updateSchedule,
FullBackupJob runningJob, CountDownLatch latch, IBackupObserver backupObserver,
IBackupManagerMonitor monitor, boolean userInitiated) {
IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
boolean userInitiated) {
super(observer);
this.backupManagerService = backupManagerService;
mTransportClient = transportClient;
mUpdateSchedule = updateSchedule;
mLatch = latch;
mJob = runningJob;
mPackages = new ArrayList<>(whichPackages.length);
mBackupObserver = backupObserver;
mMonitor = monitor;
mListener = (listener != null) ? listener : OnTaskFinishedListener.NOP;
mUserInitiated = userInitiated;
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
@@ -241,8 +281,11 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
if (mIsDoingBackup) {
backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
try {
mTransport.cancelFullBackup();
} catch (RemoteException e) {
// If we're running a backup we should be connected to a transport
IBackupTransport transport =
mTransportClient.getConnectedTransport("PFTBT.handleCancel()");
transport.cancelFullBackup();
} catch (RemoteException | TransportNotAvailableException e) {
Slog.w(TAG, "Error calling cancelFullBackup() on transport: " + e);
// Can't do much.
}
@@ -291,8 +334,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
return;
}
mTransport = backupManagerService.getTransportManager().getCurrentTransportBinder();
if (mTransport == null) {
IBackupTransport transport = mTransportClient.connect("PFTBT.run()");
if (transport == null) {
Slog.w(TAG, "Transport not present; full data backup not performed");
backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -325,17 +368,17 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
if (mCancelAll) {
break;
}
backupPackageStatus = mTransport.performFullBackup(currentPackage,
backupPackageStatus = transport.performFullBackup(currentPackage,
transportPipes[0], flags);
if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
quota = mTransport.getBackupQuota(currentPackage.packageName,
quota = transport.getBackupQuota(currentPackage.packageName,
true /* isFullBackup */);
// Now set up the backup engine / data source end of things
enginePipes = ParcelFileDescriptor.createPipe();
mBackupRunner =
new SinglePackageBackupRunner(enginePipes[1], currentPackage,
mTransport, quota, mBackupRunnerOpToken);
mTransportClient, quota, mBackupRunnerOpToken);
// The runner dup'd the pipe half, so we close it here
enginePipes[1].close();
enginePipes[1] = null;
@@ -389,7 +432,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
out.write(buffer, 0, nRead);
synchronized (mCancelLock) {
if (!mCancelAll) {
backupPackageStatus = mTransport.sendBackupData(nRead);
backupPackageStatus = transport.sendBackupData(nRead);
}
}
totalRead += nRead;
@@ -425,12 +468,12 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
// result based on what finishBackup() returns. If we're in a
// failure case already, preserve that result and ignore whatever
// finishBackup() reports.
final int finishResult = mTransport.finishBackup();
final int finishResult = transport.finishBackup();
if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
backupPackageStatus = finishResult;
}
} else {
mTransport.cancelFullBackup();
transport.cancelFullBackup();
}
}
}
@@ -469,7 +512,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
// Also ask the transport how long it wants us to wait before
// moving on to the next package, if any.
backoff = mTransport.requestFullBackupTime();
backoff = transport.requestFullBackupTime();
if (DEBUG_SCHEDULING) {
Slog.i(TAG, "Transport suggested backoff=" + backoff);
}
@@ -591,6 +634,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
backupManagerService.setRunningFullBackupTask(null);
}
mListener.onFinished("PFTBT.run()");
mLatch.countDown();
// Now that we're actually done with schedule-driven work, reschedule
@@ -633,12 +678,13 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
class SinglePackageBackupPreflight implements BackupRestoreTask, FullBackupPreflight {
final AtomicLong mResult = new AtomicLong(BackupTransport.AGENT_ERROR);
final CountDownLatch mLatch = new CountDownLatch(1);
final IBackupTransport mTransport;
final TransportClient mTransportClient;
final long mQuota;
private final int mCurrentOpToken;
SinglePackageBackupPreflight(IBackupTransport transport, long quota, int currentOpToken) {
mTransport = transport;
SinglePackageBackupPreflight(
TransportClient transportClient, long quota, int currentOpToken) {
mTransportClient = transportClient;
mQuota = quota;
mCurrentOpToken = currentOpToken;
}
@@ -672,7 +718,9 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
Slog.v(TAG, "Got preflight response; size=" + totalSize);
}
result = mTransport.checkFullBackupSize(totalSize);
IBackupTransport transport =
mTransportClient.connectOrThrow("PFTBT$SPBP.preflightFullBackup()");
result = transport.checkFullBackupSize(totalSize);
if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
if (MORE_DEBUG) {
Slog.d(TAG, "Package hit quota limit on preflight " +
@@ -739,12 +787,13 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
private volatile boolean mIsCancelled;
SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
IBackupTransport transport, long quota, int currentOpToken) throws IOException {
TransportClient transportClient, long quota, int currentOpToken)
throws IOException {
mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
mTarget = target;
mCurrentOpToken = currentOpToken;
mEphemeralToken = backupManagerService.generateRandomIntegerToken();
mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
mPreflight = new SinglePackageBackupPreflight(transportClient, quota, mEphemeralToken);
mPreflightLatch = new CountDownLatch(1);
mBackupLatch = new CountDownLatch(1);
mPreflightResult = BackupTransport.AGENT_ERROR;

View File

@@ -184,11 +184,11 @@ public class PerformBackupTask implements BackupRestoreTask {
mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
mFullBackupTask =
new PerformFullTransportBackupTask(backupManagerService,
/*fullBackupRestoreObserver*/
null,
transportClient,
/*fullBackupRestoreObserver*/ null,
fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
latch,
mObserver, mMonitor, mUserInitiated);
mObserver, mMonitor, mListener, mUserInitiated);
registerTask();
backupManagerService.addBackupTrace("STATE => INITIAL");
@@ -585,11 +585,11 @@ public class PerformBackupTask implements BackupRestoreTask {
if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
// TODO(brufino): Move the onFinish() call to the full-backup task
mListener.onFinished(callerLogString);
Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
backupManagerService.getWakelock().acquire();
// The full-backup task is now responsible for calling onFinish() on mListener, which
// was the listener we passed it.
(new Thread(mFullBackupTask, "full-transport-requested")).start();
} else if (mCancelAll) {
mListener.onFinished(callerLogString);

View File

@@ -367,6 +367,25 @@ public class TransportClient {
return transport;
}
/**
* If the {@link TransportClient} is already connected to the transport, returns the transport,
* otherwise throws {@link TransportNotAvailableException}.
*
* @param caller A {@link String} identifying the caller for logging/debugging purposes. Check
* {@link #connectAsync(TransportConnectionListener, String)} for more details.
* @return A {@link IBackupTransport} transport binder instance.
* @throws TransportNotAvailableException if not connected.
*/
public IBackupTransport getConnectedTransport(String caller)
throws TransportNotAvailableException {
IBackupTransport transport = mTransport;
if (transport == null) {
log(Log.ERROR, caller, "Transport not connected");
throw new TransportNotAvailableException();
}
return transport;
}
@Override
public String toString() {
return "TransportClient{"

View File

@@ -25,7 +25,7 @@ import com.android.internal.backup.IBackupTransport;
*
* @see TransportClient#connectAsync(TransportConnectionListener, String)
*/
class TransportNotAvailableException extends Exception {
public class TransportNotAvailableException extends Exception {
TransportNotAvailableException() {
super("Transport not available");
}

View File

@@ -25,6 +25,7 @@ import com.android.internal.backup.IBackupTransport;
/** Utility methods for transport-related operations. */
public class TransportUtils {
private static final String TAG = "TransportUtils";
/**
* Throws {@link TransportNotAvailableException} if {@param transport} is null. The semantics is
@@ -33,6 +34,7 @@ public class TransportUtils {
public static IBackupTransport checkTransport(@Nullable IBackupTransport transport)
throws TransportNotAvailableException {
if (transport == null) {
log(Log.ERROR, TAG, "Transport not available");
throw new TransportNotAvailableException();
}
return transport;