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

Commit 4c44a2f1 authored by Ruslan Tkhakokhov's avatar Ruslan Tkhakokhov Committed by Android (Google) Code Review
Browse files

Merge changes from topic "async-transport"

* changes:
  Update BackupTransportCallback to use async AIDL
  Make IBackupTransport AIDL async
parents 67a92323 6aba9656
Loading
Loading
Loading
Loading
+104 −55
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;

import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.ITransportStatusCallback;
import com.android.internal.infra.AndroidFuture;

import java.util.Arrays;
import java.util.List;

/**
 * Concrete class that provides a stable-API bridge between IBackupTransport
@@ -659,141 +664,185 @@ public class BackupTransport {
    class TransportImpl extends IBackupTransport.Stub {

        @Override
        public String name() throws RemoteException {
            return BackupTransport.this.name();
        public void name(AndroidFuture<String> resultFuture) throws RemoteException {
            String result = BackupTransport.this.name();
            resultFuture.complete(result);
        }

        @Override
        public Intent configurationIntent() throws RemoteException {
            return BackupTransport.this.configurationIntent();
        public void configurationIntent(AndroidFuture<Intent> resultFuture)
                throws RemoteException {
            Intent result = BackupTransport.this.configurationIntent();
            resultFuture.complete(result);
        }

        @Override
        public String currentDestinationString() throws RemoteException {
            return BackupTransport.this.currentDestinationString();
        public void currentDestinationString(AndroidFuture<String> resultFuture)
                throws RemoteException {
            String result = BackupTransport.this.currentDestinationString();
            resultFuture.complete(result);
        }

        @Override
        public Intent dataManagementIntent() {
            return BackupTransport.this.dataManagementIntent();
        public void dataManagementIntent(AndroidFuture<Intent> resultFuture)
                throws RemoteException {
            Intent result = BackupTransport.this.dataManagementIntent();
            resultFuture.complete(result);
        }

        @Override
        public CharSequence dataManagementIntentLabel() {
            return BackupTransport.this.dataManagementIntentLabel();
        public void dataManagementIntentLabel(AndroidFuture<CharSequence> resultFuture)
                throws RemoteException {
            CharSequence result = BackupTransport.this.dataManagementIntentLabel();
            resultFuture.complete(result);
        }

        @Override
        public String transportDirName() throws RemoteException {
            return BackupTransport.this.transportDirName();
        public void transportDirName(AndroidFuture<String> resultFuture) throws RemoteException {
            String result = BackupTransport.this.transportDirName();
            resultFuture.complete(result);
        }

        @Override
        public long requestBackupTime() throws RemoteException {
            return BackupTransport.this.requestBackupTime();
        public void requestBackupTime(AndroidFuture<Long> resultFuture) throws RemoteException {
            long result = BackupTransport.this.requestBackupTime();
            resultFuture.complete(result);
        }

        @Override
        public int initializeDevice() throws RemoteException {
            return BackupTransport.this.initializeDevice();
        public void initializeDevice(ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.initializeDevice();
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags)
                throws RemoteException {
            return BackupTransport.this.performBackup(packageInfo, inFd, flags);
        public void performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags,
                ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.performBackup(packageInfo, inFd, flags);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int clearBackupData(PackageInfo packageInfo) throws RemoteException {
            return BackupTransport.this.clearBackupData(packageInfo);
        public void clearBackupData(PackageInfo packageInfo, ITransportStatusCallback callback)
                throws RemoteException {
            int result = BackupTransport.this.clearBackupData(packageInfo);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int finishBackup() throws RemoteException {
            return BackupTransport.this.finishBackup();
        public void finishBackup(ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.finishBackup();
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public RestoreSet[] getAvailableRestoreSets() throws RemoteException {
            return BackupTransport.this.getAvailableRestoreSets();
        public void getAvailableRestoreSets(AndroidFuture<List<RestoreSet>> resultFuture)
                throws RemoteException {
            RestoreSet[] result = BackupTransport.this.getAvailableRestoreSets();
            resultFuture.complete(Arrays.asList(result));
        }

        @Override
        public long getCurrentRestoreSet() throws RemoteException {
            return BackupTransport.this.getCurrentRestoreSet();
        public void getCurrentRestoreSet(AndroidFuture<Long> resultFuture)
                throws RemoteException {
            long result = BackupTransport.this.getCurrentRestoreSet();
            resultFuture.complete(result);
        }

        @Override
        public int startRestore(long token, PackageInfo[] packages) throws RemoteException {
            return BackupTransport.this.startRestore(token, packages);
        public void startRestore(long token, PackageInfo[] packages,
                ITransportStatusCallback callback)  throws RemoteException {
            int result = BackupTransport.this.startRestore(token, packages);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public RestoreDescription nextRestorePackage() throws RemoteException {
            return BackupTransport.this.nextRestorePackage();
        public void nextRestorePackage(AndroidFuture<RestoreDescription> resultFuture)
                throws RemoteException {
            RestoreDescription result = BackupTransport.this.nextRestorePackage();
            resultFuture.complete(result);
        }

        @Override
        public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException {
            return BackupTransport.this.getRestoreData(outFd);
        public void getRestoreData(ParcelFileDescriptor outFd,
                ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.getRestoreData(outFd);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public void finishRestore() throws RemoteException {
        public void finishRestore(ITransportStatusCallback callback)
                throws RemoteException {
            BackupTransport.this.finishRestore();
            callback.onOperationComplete();
        }

        @Override
        public long requestFullBackupTime() throws RemoteException {
            return BackupTransport.this.requestFullBackupTime();
        public void requestFullBackupTime(AndroidFuture<Long> resultFuture)
                throws RemoteException {
            long result = BackupTransport.this.requestFullBackupTime();
            resultFuture.complete(result);
        }

        @Override
        public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket,
                int flags) throws RemoteException {
            return BackupTransport.this.performFullBackup(targetPackage, socket, flags);
        public void performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket,
                int flags, ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.performFullBackup(targetPackage, socket, flags);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int checkFullBackupSize(long size) {
            return BackupTransport.this.checkFullBackupSize(size);
        public void checkFullBackupSize(long size, ITransportStatusCallback callback)
                throws RemoteException {
            int result = BackupTransport.this.checkFullBackupSize(size);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int sendBackupData(int numBytes) throws RemoteException {
            return BackupTransport.this.sendBackupData(numBytes);
        public void sendBackupData(int numBytes, ITransportStatusCallback callback)
                throws RemoteException {
            int result = BackupTransport.this.sendBackupData(numBytes);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public void cancelFullBackup() throws RemoteException {
        public void cancelFullBackup(ITransportStatusCallback callback) throws RemoteException {
            BackupTransport.this.cancelFullBackup();
            callback.onOperationComplete();
        }

        @Override
        public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup)
                throws RemoteException {
            return BackupTransport.this.isAppEligibleForBackup(targetPackage, isFullBackup);
        public void isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup,
                AndroidFuture<Boolean> resultFuture) throws RemoteException {
            boolean result = BackupTransport.this.isAppEligibleForBackup(targetPackage,
                    isFullBackup);
            resultFuture.complete(result);
        }

        @Override
        public long getBackupQuota(String packageName, boolean isFullBackup) {
            return BackupTransport.this.getBackupQuota(packageName, isFullBackup);
        public void getBackupQuota(String packageName, boolean isFullBackup,
                AndroidFuture<Long> resultFuture) throws RemoteException {
            long result = BackupTransport.this.getBackupQuota(packageName, isFullBackup);
            resultFuture.complete(result);
        }

        @Override
        public int getTransportFlags() {
            return BackupTransport.this.getTransportFlags();
        public void getTransportFlags(AndroidFuture<Integer> resultFuture) throws RemoteException {
            int result = BackupTransport.this.getTransportFlags();
            resultFuture.complete(result);
        }

        @Override
        public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
            return BackupTransport.this.getNextFullRestoreDataChunk(socket);
        public void getNextFullRestoreDataChunk(ParcelFileDescriptor socket,
                ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.getNextFullRestoreDataChunk(socket);
            callback.onOperationCompleteWithStatus(result);
        }

        @Override
        public int abortFullRestore() {
            return BackupTransport.this.abortFullRestore();
        public void abortFullRestore(ITransportStatusCallback callback) throws RemoteException {
            int result = BackupTransport.this.abortFullRestore();
            callback.onOperationCompleteWithStatus(result);
        }
    }
}
+185 −100

File changed.

Preview size limit exceeded, changes collapsed.

+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.internal.backup;

/**
* A callback class for {@link IBackupTransport}
*
* {@hide}
*/
oneway interface ITransportStatusCallback {
    /**
    * Callback for methods that complete with an {@code int} status.
    */
    void onOperationCompleteWithStatus(int status);

    /**
    * Callback for methods that complete without a value.
    */
    void onOperationComplete();
}
+195 −31

File changed.

Preview size limit exceeded, changes collapsed.

+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.transport;

import android.app.backup.BackupTransport;
import android.os.RemoteException;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.backup.ITransportStatusCallback;

public class TransportStatusCallback extends ITransportStatusCallback.Stub {
    private static final String TAG = "TransportStatusCallback";
    private static final int TIMEOUT_MILLIS = 600 * 1000; // 10 minutes.
    private static final int OPERATION_STATUS_DEFAULT = 0;

    private final int mOperationTimeout;

    @GuardedBy("this")
    private int mOperationStatus = OPERATION_STATUS_DEFAULT;
    @GuardedBy("this")
    private boolean mHasCompletedOperation = false;

    public TransportStatusCallback() {
        mOperationTimeout = TIMEOUT_MILLIS;
    }

    @VisibleForTesting
    TransportStatusCallback(int operationTimeout) {
        mOperationTimeout = operationTimeout;
    }

    @Override
    public synchronized void onOperationCompleteWithStatus(int status) throws RemoteException {
        mHasCompletedOperation = true;
        mOperationStatus = status;

        notifyAll();
    }

    @Override
    public synchronized void onOperationComplete() throws RemoteException {
        onOperationCompleteWithStatus(OPERATION_STATUS_DEFAULT);
    }

    synchronized int getOperationStatus() {
        if (mHasCompletedOperation) {
            return mOperationStatus;
        }

        long timeoutLeft = mOperationTimeout;
        try {
            while (!mHasCompletedOperation && timeoutLeft > 0) {
                long waitStartTime = System.currentTimeMillis();
                wait(timeoutLeft);
                if (mHasCompletedOperation) {
                    return mOperationStatus;
                }
                timeoutLeft -= System.currentTimeMillis() - waitStartTime;
            }

            Slog.w(TAG, "Couldn't get operation status from transport");
            return BackupTransport.TRANSPORT_ERROR;
        } catch (InterruptedException e) {
            Slog.w(TAG, "Couldn't get operation status from transport: ", e);
            return BackupTransport.TRANSPORT_ERROR;
        } finally {
            reset();
        }
    }

    synchronized void reset() {
        mHasCompletedOperation = false;
        mOperationStatus = OPERATION_STATUS_DEFAULT;
    }
}
Loading