Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adf8288a authored by Artem Iglikov's avatar Artem Iglikov
Browse files

Introduce BackupManagerServiceInteface in remaining parts of the code.

Use it in Trampoline, KeyValueAdbBackupEngine, KeyValueAdbRestoreEngine
where it wasn't used automatically, because of using package-private
methods and fields. To be able to do this, also make couple of methods
public and move them to the interface and add getBackupManagerBinder()
method to use instead of directly accessing the field.

Test: not required as behaviour is not modified.

Bug: 36850431

Change-Id: Ia7a26f93f8dba37ece87305979c922acb58a271f
parent 06d6b4d9
Loading
Loading
Loading
Loading
+35 −59
Original line number Original line Diff line number Diff line
@@ -306,6 +306,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    private PowerManager mPowerManager;
    private PowerManager mPowerManager;
    private AlarmManager mAlarmManager;
    private AlarmManager mAlarmManager;
    private IStorageManager mStorageManager;
    private IStorageManager mStorageManager;
    IBackupManager mBackupManagerBinder;
    IBackupManager mBackupManagerBinder;
    private final TransportManager mTransportManager;
    private final TransportManager mTransportManager;
@@ -763,7 +764,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    ArrayList<FullBackupEntry> mFullBackupQueue;
    ArrayList<FullBackupEntry> mFullBackupQueue;
    // Utility: build a new random integer token
    // Utility: build a new random integer token
    int generateToken() {
    @Override
    public int generateRandomIntegerToken() {
        int token;
        int token;
        do {
        do {
            synchronized (mTokenGenerator) {
            synchronized (mTokenGenerator) {
@@ -2274,7 +2276,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    }
    }
    // fire off a backup agent, blocking until it attaches or times out
    // fire off a backup agent, blocking until it attaches or times out
    IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
    @Override
    public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
        IBackupAgent agent = null;
        IBackupAgent agent = null;
        synchronized(mAgentConnectLock) {
        synchronized(mAgentConnectLock) {
            mConnecting = true;
            mConnecting = true;
@@ -2495,21 +2498,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
        }
        }
    }
    }
    // -----
    @Override
    // Interface and methods used by the asynchronous-with-timeout backup/restore operations
    public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
    interface BackupRestoreTask {
        // Execute one tick of whatever state machine the task implements
        void execute();
        // An operation that wanted a callback has completed
        void operationComplete(long result);
        // An operation that wanted a callback has timed out
        void handleCancel(boolean cancelAll);
    }
    void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
        int operationType) {
        int operationType) {
        if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
        if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
            Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
            Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
@@ -2554,7 +2544,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    }
    }
    // synchronous waiter case
    // synchronous waiter case
    boolean waitUntilOperationComplete(int token) {
    @Override
    public boolean waitUntilOperationComplete(int token) {
        if (MORE_DEBUG) Slog.i(TAG, "Blocking until operation complete for "
        if (MORE_DEBUG) Slog.i(TAG, "Blocking until operation complete for "
                + Integer.toHexString(token));
                + Integer.toHexString(token));
        int finalState = OP_PENDING;
        int finalState = OP_PENDING;
@@ -2716,7 +2707,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
            mNonIncremental = nonIncremental;
            mNonIncremental = nonIncremental;
            mStateDir = new File(mBaseStateDir, dirName);
            mStateDir = new File(mBaseStateDir, dirName);
            mCurrentOpToken = generateToken();
            mCurrentOpToken = generateRandomIntegerToken();
            mFinished = false;
            mFinished = false;
@@ -3174,7 +3165,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
            mNewState = null;
            mNewState = null;
            boolean callingAgent = false;
            boolean callingAgent = false;
            mEphemeralOpToken = generateToken();
            mEphemeralOpToken = generateRandomIntegerToken();
            try {
            try {
                // Look up the package info & signatures.  This is first so that if it
                // Look up the package info & signatures.  This is first so that if it
                // throws an exception, there's no file setup yet that would need to
                // throws an exception, there's no file setup yet that would need to
@@ -3671,7 +3662,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
            ParcelFileDescriptor[] pipes = null;
            ParcelFileDescriptor[] pipes = null;
            try {
            try {
                pipes = ParcelFileDescriptor.createPipe();
                pipes = ParcelFileDescriptor.createPipe();
                int token = generateToken();
                int token = generateRandomIntegerToken();
                prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
                prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
                        null, OP_TYPE_BACKUP_WAIT);
                        null, OP_TYPE_BACKUP_WAIT);
                mService.backupObbs(pkg.packageName, pipes[1], token, mBackupManagerBinder);
                mService.backupObbs(pkg.packageName, pipes[1], token, mBackupManagerBinder);
@@ -3757,7 +3748,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
        }
        }
    }
    }
    void tearDownAgentAndKill(ApplicationInfo app) {
    @Override
    public void tearDownAgentAndKill(ApplicationInfo app) {
        if (app == null) {
        if (app == null) {
            // Null means the system package, so just quietly move on.  :)
            // Null means the system package, so just quietly move on.  :)
            return;
            return;
@@ -4204,7 +4196,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
                String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
                String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
                boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
                boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
            super(observer);
            super(observer);
            mCurrentOpToken = generateToken();
            mCurrentOpToken = generateRandomIntegerToken();
            mLatch = latch;
            mLatch = latch;
            mOutputFile = fd;
            mOutputFile = fd;
@@ -4654,8 +4646,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
            mBackupObserver = backupObserver;
            mBackupObserver = backupObserver;
            mMonitor = monitor;
            mMonitor = monitor;
            mUserInitiated = userInitiated;
            mUserInitiated = userInitiated;
            mCurrentOpToken = generateToken();
            mCurrentOpToken = generateRandomIntegerToken();
            mBackupRunnerOpToken = generateToken();
            mBackupRunnerOpToken = generateRandomIntegerToken();
            if (isBackupOperationInProgress()) {
            if (isBackupOperationInProgress()) {
                if (DEBUG) {
                if (DEBUG) {
@@ -5248,7 +5240,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
                mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                mTarget = target;
                mTarget = target;
                mCurrentOpToken = currentOpToken;
                mCurrentOpToken = currentOpToken;
                mEphemeralToken = generateToken();
                mEphemeralToken = generateRandomIntegerToken();
                mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
                mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
                mPreflightLatch = new CountDownLatch(1);
                mPreflightLatch = new CountDownLatch(1);
                mBackupLatch = new CountDownLatch(1);
                mBackupLatch = new CountDownLatch(1);
@@ -5478,7 +5470,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
     * @return Whether ongoing work will continue.  The return value here will be passed
     * @return Whether ongoing work will continue.  The return value here will be passed
     *         along as the return value to the scheduled job's onStartJob() callback.
     *         along as the return value to the scheduled job's onStartJob() callback.
     */
     */
    boolean beginFullBackup(FullBackupJob scheduledJob) {
    @Override
    public boolean beginFullBackup(FullBackupJob scheduledJob) {
        long now = System.currentTimeMillis();
        long now = System.currentTimeMillis();
        FullBackupEntry entry = null;
        FullBackupEntry entry = null;
        long latency = MIN_FULL_BACKUP_INTERVAL;
        long latency = MIN_FULL_BACKUP_INTERVAL;
@@ -5636,7 +5629,8 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    // The job scheduler says our constraints don't hold any more,
    // The job scheduler says our constraints don't hold any more,
    // so tear down any ongoing backup task right away.
    // so tear down any ongoing backup task right away.
    void endFullBackup() {
    @Override
    public void endFullBackup() {
        synchronized (mQueueLock) {
        synchronized (mQueueLock) {
            if (mRunningFullBackupTask != null) {
            if (mRunningFullBackupTask != null) {
                if (DEBUG_SCHEDULING) {
                if (DEBUG_SCHEDULING) {
@@ -5694,30 +5688,6 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    // ----- Full restore from a file/socket -----
    // ----- Full restore from a file/socket -----
    // Description of a file in the restore datastream
    static class FileMetadata {
        String packageName;             // name of the owning app
        String installerPackageName;    // name of the market-type app that installed the owner
        int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
        String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
        String path;                    // subpath within the semantic domain
        long mode;                      // e.g. 0666 (actually int)
        long mtime;                     // last mod time, UTC time_t (actually int)
        long size;                      // bytes of content
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(128);
            sb.append("FileMetadata{");
            sb.append(packageName); sb.append(',');
            sb.append(type); sb.append(',');
            sb.append(domain); sb.append(':'); sb.append(path); sb.append(',');
            sb.append(size);
            sb.append('}');
            return sb.toString();
        }
    }
    enum RestorePolicy {
    enum RestorePolicy {
        IGNORE,
        IGNORE,
        ACCEPT,
        ACCEPT,
@@ -7564,7 +7534,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
                        if (okay) {
                        if (okay) {
                            boolean agentSuccess = true;
                            boolean agentSuccess = true;
                            long toCopy = info.size;
                            long toCopy = info.size;
                            final int token = generateToken();
                            final int token = generateRandomIntegerToken();
                            try {
                            try {
                                prepareOperationTimeout(token, TIMEOUT_RESTORE_INTERVAL, null,
                                prepareOperationTimeout(token, TIMEOUT_RESTORE_INTERVAL, null,
                                        OP_TYPE_RESTORE_WAIT);
                                        OP_TYPE_RESTORE_WAIT);
@@ -7708,7 +7678,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
                try {
                try {
                    // In the adb restore case, we do restore-finished here
                    // In the adb restore case, we do restore-finished here
                    if (doRestoreFinished) {
                    if (doRestoreFinished) {
                        final int token = generateToken();
                        final int token = generateRandomIntegerToken();
                        final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(token);
                        final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(token);
                        prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch,
                        prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch,
                                OP_TYPE_RESTORE_WAIT);
                                OP_TYPE_RESTORE_WAIT);
@@ -8587,7 +8557,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
        PerformUnifiedRestoreTask(IBackupTransport transport, IRestoreObserver observer,
        PerformUnifiedRestoreTask(IBackupTransport transport, IRestoreObserver observer,
                IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
                IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
                int pmToken, boolean isFullSystemRestore, String[] filterSet) {
                int pmToken, boolean isFullSystemRestore, String[] filterSet) {
            mEphemeralOpToken = generateToken();
            mEphemeralOpToken = generateRandomIntegerToken();
            mState = UnifiedRestoreState.INITIAL;
            mState = UnifiedRestoreState.INITIAL;
            mStartRealtime = SystemClock.elapsedRealtime();
            mStartRealtime = SystemClock.elapsedRealtime();
@@ -9217,7 +9187,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
            private final int mEphemeralOpToken;
            private final int mEphemeralOpToken;
            public StreamFeederThread() throws IOException {
            public StreamFeederThread() throws IOException {
                mEphemeralOpToken = generateToken();
                mEphemeralOpToken = generateRandomIntegerToken();
                mTransportPipes = ParcelFileDescriptor.createPipe();
                mTransportPipes = ParcelFileDescriptor.createPipe();
                mEnginePipes = ParcelFileDescriptor.createPipe();
                mEnginePipes = ParcelFileDescriptor.createPipe();
                setRunning(true);
                setRunning(true);
@@ -10039,7 +10009,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
            AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
            AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
                    includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
                    includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
                    pkgList);
                    pkgList);
            final int token = generateToken();
            final int token = generateRandomIntegerToken();
            synchronized (mAdbBackupRestoreConfirmations) {
            synchronized (mAdbBackupRestoreConfirmations) {
                mAdbBackupRestoreConfirmations.put(token, params);
                mAdbBackupRestoreConfirmations.put(token, params);
            }
            }
@@ -10147,7 +10117,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
            Slog.i(TAG, "Beginning restore...");
            Slog.i(TAG, "Beginning restore...");
            AdbRestoreParams params = new AdbRestoreParams(fd);
            AdbRestoreParams params = new AdbRestoreParams(fd);
            final int token = generateToken();
            final int token = generateRandomIntegerToken();
            synchronized (mAdbBackupRestoreConfirmations) {
            synchronized (mAdbBackupRestoreConfirmations) {
                mAdbBackupRestoreConfirmations.put(token, params);
                mAdbBackupRestoreConfirmations.put(token, params);
            }
            }
@@ -11397,4 +11367,10 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
        }
        }
        return null;
        return null;
    }
    }
    @Override
    public IBackupManager getBackupManagerBinder() {
        return mBackupManagerBinder;
    }
}
}
+25 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.backup;
package com.android.server.backup;


import android.app.IBackupAgent;
import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IFullBackupRestoreObserver;
@@ -23,6 +25,7 @@ import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
import android.app.backup.ISelectBackupTransportCallback;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.IBinder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
@@ -36,10 +39,16 @@ import java.io.PrintWriter;
 */
 */
public interface BackupManagerServiceInterface {
public interface BackupManagerServiceInterface {


  // Utility: build a new random integer token
  int generateRandomIntegerToken();

  boolean setBackupPassword(String currentPw, String newPw);
  boolean setBackupPassword(String currentPw, String newPw);


  boolean hasBackupPassword();
  boolean hasBackupPassword();


  // fire off a backup agent, blocking until it attaches or times out
  IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode);

  // Get the restore-set token for the best-available restore set for this package:
  // Get the restore-set token for the best-available restore set for this package:
  // the active set if possible, else the ancestral one.  Returns zero if none available.
  // the active set if possible, else the ancestral one.  Returns zero if none available.
  long getAvailableRestoreToken(String packageName);
  long getAvailableRestoreToken(String packageName);
@@ -52,6 +61,20 @@ public interface BackupManagerServiceInterface {
  // Cancel all running backups.
  // Cancel all running backups.
  void cancelBackups();
  void cancelBackups();


  void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
      int operationType);

  // synchronous waiter case
  boolean waitUntilOperationComplete(int token);

  void tearDownAgentAndKill(ApplicationInfo app);

  boolean beginFullBackup(FullBackupJob scheduledJob);

  // The job scheduler says our constraints don't hold any more,
  // so tear down any ongoing backup task right away.
  void endFullBackup();

  void dataChanged(String packageName);
  void dataChanged(String packageName);


  // Clear the given package's backup data from the current transport
  // Clear the given package's backup data from the current transport
@@ -150,4 +173,6 @@ public interface BackupManagerServiceInterface {
  boolean isAppEligibleForBackup(String packageName);
  boolean isAppEligibleForBackup(String packageName);


  void dump(FileDescriptor fd, PrintWriter pw, String[] args);
  void dump(FileDescriptor fd, PrintWriter pw, String[] args);

  IBackupManager getBackupManagerBinder();
}
}
+32 −0
Original line number Original line Diff line number Diff line
/*
 * 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 com.android.server.backup;

/**
 * Interface and methods used by the asynchronous-with-timeout backup/restore operations.
 */
interface BackupRestoreTask {

    // Execute one tick of whatever state machine the task implements
    void execute();

    // An operation that wanted a callback has completed
    void operationComplete(long result);

    // An operation that wanted a callback has timed out
    void handleCancel(boolean cancelAll);
}
+49 −0
Original line number Original line Diff line number Diff line
/*
 * 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 com.android.server.backup;

/**
 * Description of a file in the restore datastream.
 */
class FileMetadata {
    String packageName;             // name of the owning app
    String installerPackageName;    // name of the market-type app that installed the owner
    int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
    String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
    String path;                    // subpath within the semantic domain
    long mode;                      // e.g. 0666 (actually int)
    long mtime;                     // last mod time, UTC time_t (actually int)
    long size;                      // bytes of content

    @Override
    public String toString() {
        // TODO: Clean this up.
        StringBuilder sb = new StringBuilder(128);
        sb.append("FileMetadata{");
        sb.append(packageName);
        sb.append(',');
        sb.append(type);
        sb.append(',');
        sb.append(domain);
        sb.append(':');
        sb.append(path);
        sb.append(',');
        sb.append(size);
        sb.append('}');
        return sb.toString();
    }
}
+6 −6
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ class KeyValueAdbBackupEngine {
    private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
    private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
    private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";
    private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";


    private BackupManagerService mBackupManagerService;
    private BackupManagerServiceInterface mBackupManagerService;
    private final PackageManager mPackageManager;
    private final PackageManager mPackageManager;
    private final OutputStream mOutput;
    private final OutputStream mOutput;
    private final PackageInfo mCurrentPackage;
    private final PackageInfo mCurrentPackage;
@@ -59,7 +59,7 @@ class KeyValueAdbBackupEngine {
    private ParcelFileDescriptor mNewState;
    private ParcelFileDescriptor mNewState;


    KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
    KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
            BackupManagerService backupManagerService, PackageManager packageManager,
        BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
            File baseStateDir, File dataDir) {
            File baseStateDir, File dataDir) {
        mOutput = output;
        mOutput = output;
        mCurrentPackage = packageInfo;
        mCurrentPackage = packageInfo;
@@ -145,14 +145,14 @@ class KeyValueAdbBackupEngine {


    // Return true on backup success, false otherwise
    // Return true on backup success, false otherwise
    private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
    private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
        int token = mBackupManagerService.generateToken();
        int token = mBackupManagerService.generateRandomIntegerToken();
        try {
        try {
            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
                    OP_TYPE_BACKUP_WAIT);
                    OP_TYPE_BACKUP_WAIT);


            // Start backup and wait for BackupManagerService to get callback for success or timeout
            // Start backup and wait for BackupManagerService to get callback for success or timeout
            agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
            agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
                    mBackupManagerService.mBackupManagerBinder);
                    mBackupManagerService.getBackupManagerBinder());
            if (!mBackupManagerService.waitUntilOperationComplete(token)) {
            if (!mBackupManagerService.waitUntilOperationComplete(token)) {
                Slog.e(TAG, "Key-value backup failed on package " + packageName);
                Slog.e(TAG, "Key-value backup failed on package " + packageName);
                return false;
                return false;
@@ -214,7 +214,7 @@ class KeyValueAdbBackupEngine {
                }
                }


                try {
                try {
                    mBackupManagerService.mBackupManagerBinder.opComplete(mToken, 0);
                    mBackupManagerService.getBackupManagerBinder().opComplete(mToken, 0);
                } catch (RemoteException e) {
                } catch (RemoteException e) {
                    // we'll time out anyway, so we're safe
                    // we'll time out anyway, so we're safe
                }
                }
@@ -229,7 +229,7 @@ class KeyValueAdbBackupEngine {


    private void writeBackupData() throws IOException {
    private void writeBackupData() throws IOException {


        int token = mBackupManagerService.generateToken();
        int token = mBackupManagerService.generateRandomIntegerToken();


        ParcelFileDescriptor[] pipes = null;
        ParcelFileDescriptor[] pipes = null;
        try {
        try {
Loading