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

Commit e6f7493b authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Provide stable concrete wrapper for backup transport API"

parents 2cfc0e54 74318c98
Loading
Loading
Loading
Loading
+334 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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 android.app.backup;

import android.content.Intent;
import android.content.pm.PackageInfo;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;

import com.android.internal.backup.BackupConstants;
import com.android.internal.backup.IBackupTransport;

/**
 * Concrete class that provides a stable-API bridge between IBackupTransport
 * and its implementations.
 *
 * @hide
 */
public class BackupTransport {
    IBackupTransport mBinderImpl = new TransportImpl();
    /** @hide */
    public IBinder getBinder() {
        return mBinderImpl.asBinder();
    }

    // ------------------------------------------------------------------------------------
    // Transport self-description and general configuration interfaces
    //

    /**
     * Ask the transport for the name under which it should be registered.  This will
     * typically be its host service's component name, but need not be.
     */
    public String name() {
        throw new UnsupportedOperationException("Transport name() not implemented");
    }

    /**
     * Ask the transport for an Intent that can be used to launch any internal
     * configuration Activity that it wishes to present.  For example, the transport
     * may offer a UI for allowing the user to supply login credentials for the
     * transport's off-device backend.
     *
     * If the transport does not supply any user-facing configuration UI, it should
     * return null from this method.
     *
     * @return An Intent that can be passed to Context.startActivity() in order to
     *         launch the transport's configuration UI.  This method will return null
     *         if the transport does not offer any user-facing configuration UI.
     */
    public Intent configurationIntent() {
        return null;
    }

    /**
     * On demand, supply a one-line string that can be shown to the user that
     * describes the current backend destination.  For example, a transport that
     * can potentially associate backup data with arbitrary user accounts should
     * include the name of the currently-active account here.
     *
     * @return A string describing the destination to which the transport is currently
     *         sending data.  This method should not return null.
     */
    public String currentDestinationString() {
        throw new UnsupportedOperationException(
                "Transport currentDestinationString() not implemented");
    }

    /**
     * Ask the transport where, on local device storage, to keep backup state blobs.
     * This is per-transport so that mock transports used for testing can coexist with
     * "live" backup services without interfering with the live bookkeeping.  The
     * returned string should be a name that is expected to be unambiguous among all
     * available backup transports; the name of the class implementing the transport
     * is a good choice.
     *
     * @return A unique name, suitable for use as a file or directory name, that the
     *         Backup Manager could use to disambiguate state files associated with
     *         different backup transports.
     */
    public String transportDirName() {
        throw new UnsupportedOperationException(
                "Transport transportDirName() not implemented");
    }

    // ------------------------------------------------------------------------------------
    // Key/value incremental backup support interfaces

    /**
     * Verify that this is a suitable time for a backup pass.  This should return zero
     * if a backup is reasonable right now, some positive value otherwise.  This method
     * will be called outside of the {@link #performBackup}/{@link #finishBackup} pair.
     *
     * <p>If this is not a suitable time for a backup, the transport should return a
     * backoff delay, in milliseconds, after which the Backup Manager should try again.
     *
     * @return Zero if this is a suitable time for a backup pass, or a positive time delay
     *   in milliseconds to suggest deferring the backup pass for a while.
     */
    public long requestBackupTime() {
        return 0;
    }

    /**
     * Initialize the server side storage for this device, erasing all stored data.
     * The transport may send the request immediately, or may buffer it.  After
     * this is called, {@link #finishBackup} will be called to ensure the request
     * is sent and received successfully.
     *
     * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far) or
     *   {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure).
     */
    public int initializeDevice() {
        return BackupConstants.TRANSPORT_ERROR;
    }

    /**
     * Send one application's key/value data update to the backup destination.  The
     * transport may send the data immediately, or may buffer it.  After this is called,
     * {@link #finishBackup} will be called to ensure the data is sent and recorded successfully.
     *
     * @param packageInfo The identity of the application whose data is being backed up.
     *   This specifically includes the signature list for the package.
     * @param data The data stream that resulted from invoking the application's
     *   BackupService.doBackup() method.  This may be a pipe rather than a file on
     *   persistent media, so it may not be seekable.
     * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
     *   must be erased prior to the storage of the data provided here.  The purpose of this
     *   is to provide a guarantee that no stale data exists in the restore set when the
     *   device begins providing incremental backups.
     * @return one of {@link BackupConstants#TRANSPORT_OK} (OK so far),
     *  {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure), or
     *  {@link BackupConstants#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
     *  become lost due to inactivity purge or some other reason and needs re-initializing)
     */
    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd) {
        return BackupConstants.TRANSPORT_ERROR;
    }

    /**
     * Erase the give application's data from the backup destination.  This clears
     * out the given package's data from the current backup set, making it as though
     * the app had never yet been backed up.  After this is called, {@link finishBackup}
     * must be called to ensure that the operation is recorded successfully.
     *
     * @return the same error codes as {@link #performBackup}.
     */
    public int clearBackupData(PackageInfo packageInfo) {
        return BackupConstants.TRANSPORT_ERROR;
    }

    /**
     * Finish sending application data to the backup destination.  This must be
     * called after {@link #performBackup} or {@link clearBackupData} to ensure that
     * all data is sent.  Only when this method returns true can a backup be assumed
     * to have succeeded.
     *
     * @return the same error codes as {@link #performBackup}.
     */
    public int finishBackup() {
        return BackupConstants.TRANSPORT_ERROR;
    }

    // ------------------------------------------------------------------------------------
    // Key/value dataset restore interfaces

    /**
     * Get the set of all backups currently available over this transport.
     *
     * @return Descriptions of the set of restore images available for this device,
     *   or null if an error occurred (the attempt should be rescheduled).
     **/
    public RestoreSet[] getAvailableRestoreSets() {
        return null;
    }

    /**
     * Get the identifying token of the backup set currently being stored from
     * this device.  This is used in the case of applications wishing to restore
     * their last-known-good data.
     *
     * @return A token that can be passed to {@link #startRestore}, or 0 if there
     *   is no backup set available corresponding to the current device state.
     */
    public long getCurrentRestoreSet() {
        return 0;
    }

    /**
     * Start restoring application data from backup.  After calling this function,
     * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData}
     * to walk through the actual application data.
     *
     * @param token A backup token as returned by {@link #getAvailableRestoreSets}
     *   or {@link #getCurrentRestoreSet}.
     * @param packages List of applications to restore (if data is available).
     *   Application data will be restored in the order given.
     * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far, call
     *   {@link #nextRestorePackage}) or {@link BackupConstants#TRANSPORT_ERROR}
     *   (an error occurred, the restore should be aborted and rescheduled).
     */
    public int startRestore(long token, PackageInfo[] packages) {
        return BackupConstants.TRANSPORT_ERROR;
    }

    /**
     * Get the package name of the next application with data in the backup store.
     *
     * @return The name of one of the packages supplied to {@link #startRestore},
     *   or "" (the empty string) if no more backup data is available,
     *   or null if an error occurred (the restore should be aborted and rescheduled).
     */
    public String nextRestorePackage() {
        return null;
    }

    /**
     * Get the data for the application returned by {@link #nextRestorePackage}.
     * @param data An open, writable file into which the backup data should be stored.
     * @return the same error codes as {@link #startRestore}.
     */
    public int getRestoreData(ParcelFileDescriptor outFd) {
        return BackupConstants.TRANSPORT_ERROR;
    }

    /**
     * End a restore session (aborting any in-process data transfer as necessary),
     * freeing any resources and connections used during the restore process.
     */
    public void finishRestore() {
        throw new UnsupportedOperationException(
                "Transport finishRestore() not implemented");
    }

    /**
     * Bridge between the actual IBackupTransport implementation and the stable API.  If the
     * binder interface needs to change, we use this layer to translate so that we can
     * (if appropriate) decouple those framework-side changes from the BackupTransport
     * implementations.
     */
    class TransportImpl extends IBackupTransport.Stub {

        @Override
        public String name() throws RemoteException {
            return BackupTransport.this.name();
        }

        @Override
        public Intent configurationIntent() throws RemoteException {
            return BackupTransport.this.configurationIntent();
        }

        @Override
        public String currentDestinationString() throws RemoteException {
            return BackupTransport.this.currentDestinationString();
        }

        @Override
        public String transportDirName() throws RemoteException {
            return BackupTransport.this.transportDirName();
        }

        @Override
        public long requestBackupTime() throws RemoteException {
            return BackupTransport.this.requestBackupTime();
        }

        @Override
        public int initializeDevice() throws RemoteException {
            return BackupTransport.this.initializeDevice();
        }

        @Override
        public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
                throws RemoteException {
            return BackupTransport.this.performBackup(packageInfo, inFd);
        }

        @Override
        public int clearBackupData(PackageInfo packageInfo) throws RemoteException {
            return BackupTransport.this.clearBackupData(packageInfo);
        }

        @Override
        public int finishBackup() throws RemoteException {
            return BackupTransport.this.finishBackup();
        }

        @Override
        public RestoreSet[] getAvailableRestoreSets() throws RemoteException {
            return BackupTransport.this.getAvailableRestoreSets();
        }

        @Override
        public long getCurrentRestoreSet() throws RemoteException {
            return BackupTransport.this.getCurrentRestoreSet();
        }

        @Override
        public int startRestore(long token, PackageInfo[] packages) throws RemoteException {
            return BackupTransport.this.startRestore(token, packages);
        }

        @Override
        public String nextRestorePackage() throws RemoteException {
            return BackupTransport.this.nextRestorePackage();
        }

        @Override
        public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException {
            return BackupTransport.this.getRestoreData(outFd);
        }

        @Override
        public void finishRestore() throws RemoteException {
            BackupTransport.this.finishRestore();
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ interface IBackupTransport {
    /**
     * Get the data for the application returned by {@link #nextRestorePackage}.
     * @param data An open, writable file into which the backup data should be stored.
     * @return the same error codes as {@link #nextRestorePackage}.
     * @return the same error codes as {@link #startRestore}.
     */
    int getRestoreData(in ParcelFileDescriptor outFd);

+3 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.backup;

import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupTransport;
import android.app.backup.RestoreSet;
import android.content.ComponentName;
import android.content.Context;
@@ -47,7 +48,7 @@ import static android.system.OsConstants.*;
 * later restoring from there.  For testing only.
 */

public class LocalTransport extends IBackupTransport.Stub {
public class LocalTransport extends BackupTransport {
    private static final String TAG = "LocalTransport";
    private static final boolean DEBUG = true;

@@ -217,7 +218,7 @@ public class LocalTransport extends IBackupTransport.Stub {

    // Restore handling
    static final long[] POSSIBLE_SETS = { 2, 3, 4, 5, 6, 7, 8, 9 }; 
    public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
    public RestoreSet[] getAvailableRestoreSets() {
        long[] existing = new long[POSSIBLE_SETS.length + 1];
        int num = 0;

+1 −1
Original line number Diff line number Diff line
@@ -32,6 +32,6 @@ public class LocalTransportService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return sTransport;
        return sTransport.getBinder();
    }
}