class PerformInitializeTask implements Runnable {

    public void run() {
        // mWakelock is *acquired* when execution begins here
        String callerLogString = "PerformInitializeTask.run()";
        List<TransportClient> transportClientsToDisposeOf = new ArrayList<>(mQueue.length);
        int result = BackupTransport.TRANSPORT_OK;
        try {
            for (String transportName : mQueue) {
                TransportClient transportClient =
                        mTransportManager.getTransportClient(transportName, callerLogString);
                if (transportClient == null) {
                    Slog.e(TAG, "Requested init for " + transportName + " but not found");
                    continue;
                }
                transportClientsToDisposeOf.add(transportClient);

                Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName);
                String transportDirName =
                        mTransportManager.getTransportDirName(
                                transportClient.getTransportComponent());
                EventLog.writeEvent(EventLogTags.BACKUP_START, transportDirName);
                long startRealtime = SystemClock.elapsedRealtime();

                IBackupTransport transport = transportClient.connectOrThrow(callerLogString);
                int status = transport.initializeDevice();
                if (status != BackupTransport.TRANSPORT_OK) {
                    Slog.e(TAG, "Transport error in initializeDevice()");
                } else {
                    status = transport.finishBackup();
                    if (status != BackupTransport.TRANSPORT_OK) {
                        Slog.e(TAG, "Transport error in finishBackup()");
                    }
                }

                // Okay, the wipe really happened.  Clean up our local bookkeeping.
                if (status == BackupTransport.TRANSPORT_OK) {
                    Slog.i(TAG, "Device init successful");
                    int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
                    EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
                    File stateFileDir = new File(mBaseStateDir, transportDirName);
                    mBackupManagerService.resetBackupState(stateFileDir);
                    EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis);
                    mBackupManagerService.recordInitPending(false, transportName, transportDirName);
                    notifyResult(transportName, BackupTransport.TRANSPORT_OK);
                } else {
                    // If this didn't work, requeue this one and try again
                    // after a suitable interval
                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
                    mBackupManagerService.recordInitPending(true, transportName, transportDirName);
                    notifyResult(transportName, status);
                    result = status;

                    // do this via another alarm to make sure of the wakelock states
                    long delay = transport.requestBackupTime();
                    Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay);
                    mBackupManagerService.getAlarmManager().set(
                            AlarmManager.RTC_WAKEUP,
                            System.currentTimeMillis() + delay,
                            mBackupManagerService.getRunInitIntent());
                }
            }
        } catch (Exception e) {
            Slog.e(TAG, "Unexpected error performing init", e);
            result = BackupTransport.TRANSPORT_ERROR;
        } finally {
            for (TransportClient transportClient : transportClientsToDisposeOf) {
                mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
            }
            notifyFinished(result);
            mListener.onFinished(callerLogString);
        }
    }

    public  PerformInitializeTask(
            UserBackupManagerService backupManagerService,
            String[] transportNames,
            @Nullable IBackupObserver observer,
            OnTaskFinishedListener listener);
    @VisibleForTesting  PerformInitializeTask(
            UserBackupManagerService backupManagerService,
            TransportManager transportManager,
            String[] transportNames,
            @Nullable IBackupObserver observer,
            OnTaskFinishedListener listener,
            File baseStateDir);

}