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

Commit d3665f1f authored by Sergey Poromov's avatar Sergey Poromov Committed by Android (Google) Code Review
Browse files

Merge "Introduce BackupManager#requestBackup & BackupObserver API"

parents 3bcf800c fe06bf64
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ LOCAL_SRC_FILES += \
	core/java/android/app/trust/ITrustManager.aidl \
	core/java/android/app/trust/ITrustListener.aidl \
	core/java/android/app/backup/IBackupManager.aidl \
	core/java/android/app/backup/IBackupObserver.aidl \
	core/java/android/app/backup/IFullBackupRestoreObserver.aidl \
	core/java/android/app/backup/IRestoreObserver.aidl \
	core/java/android/app/backup/IRestoreSession.aidl \
+26 −0
Original line number Diff line number Diff line
@@ -6294,10 +6294,33 @@ package android.app.backup {
    method public java.lang.String getCurrentTransport();
    method public boolean isBackupEnabled();
    method public java.lang.String[] listAllTransports();
    method public int requestBackup(java.lang.String[], android.app.backup.BackupObserver);
    method public int requestRestore(android.app.backup.RestoreObserver);
    method public java.lang.String selectBackupTransport(java.lang.String);
    method public void setAutoRestore(boolean);
    method public void setBackupEnabled(boolean);
    field public static final int ERROR_AGENT_FAILURE = -1003; // 0xfffffc15
    field public static final int ERROR_BACKUP_NOT_ALLOWED = -2001; // 0xfffff82f
    field public static final int ERROR_PACKAGE_NOT_FOUND = -2002; // 0xfffff82e
    field public static final int ERROR_TRANSPORT_ABORTED = -1000; // 0xfffffc18
    field public static final int ERROR_TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
    field public static final int SUCCESS = 0; // 0x0
  }
  public abstract class BackupObserver {
    ctor public BackupObserver();
    method public void backupFinished(int);
    method public void onResult(java.lang.String, int);
    method public void onUpdate(java.lang.String, android.app.backup.BackupProgress);
  }
  public class BackupProgress implements android.os.Parcelable {
    ctor public BackupProgress(long, long);
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.app.backup.BackupProgress> CREATOR;
    field public final long bytesExpected;
    field public final long bytesTransferred;
  }
  public class BackupTransport {
@@ -6320,7 +6343,9 @@ package android.app.backup {
    method public int initializeDevice();
    method public java.lang.String name();
    method public android.app.backup.RestoreDescription nextRestorePackage();
    method public int performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int);
    method public int performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor);
    method public int performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int);
    method public int performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor);
    method public long requestBackupTime();
    method public long requestFullBackupTime();
@@ -6329,6 +6354,7 @@ package android.app.backup {
    method public java.lang.String transportDirName();
    field public static final int AGENT_ERROR = -1003; // 0xfffffc15
    field public static final int AGENT_UNKNOWN = -1004; // 0xfffffc14
    field public static final int FLAG_USER_INITIATED = 1; // 0x1
    field public static final int NO_MORE_DATA = -1; // 0xffffffff
    field public static final int TRANSPORT_ERROR = -1000; // 0xfffffc18
    field public static final int TRANSPORT_NOT_INITIALIZED = -1001; // 0xfffffc17
+152 −3
Original line number Diff line number Diff line
@@ -17,13 +17,13 @@
package android.app.backup;

import android.annotation.SystemApi;
import android.app.backup.RestoreSession;
import android.app.backup.IBackupManager;
import android.app.backup.IRestoreSession;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Pair;

/**
 * The interface through which an application interacts with the Android backup service to
@@ -59,6 +59,65 @@ import android.util.Log;
public class BackupManager {
    private static final String TAG = "BackupManager";

    // BackupObserver status codes
    /**
     * Indicates that backup succeeded.
     *
     * @hide
     */
    @SystemApi
    public static final int SUCCESS = 0;

    /**
     * Indicates that backup is either not enabled at all or
     * backup for the package was rejected by backup service
     * or backup transport,
     *
     * @hide
     */
    @SystemApi
    public static final int ERROR_BACKUP_NOT_ALLOWED = -2001;

    /**
     * The requested app is not installed on the device.
     *
     * @hide
     */
    @SystemApi
    public static final int ERROR_PACKAGE_NOT_FOUND = -2002;

    /**
     * The transport for some reason was not in a good state and
     * aborted the entire backup request. This is a transient
     * failure and should not be retried immediately.
     *
     * @hide
     */
    @SystemApi
    public static final int ERROR_TRANSPORT_ABORTED = BackupTransport.TRANSPORT_ERROR;

    /**
     * Returned when the transport was unable to process the
     * backup request for a given package, for example if the
     * transport hit a transient network failure. The remaining
     * packages provided to {@link #requestBackup(String[], BackupObserver)}
     * will still be attempted.
     *
     * @hide
     */
    @SystemApi
    public static final int ERROR_TRANSPORT_PACKAGE_REJECTED =
            BackupTransport.TRANSPORT_PACKAGE_REJECTED;

    /**
     * The {@link BackupAgent} for the requested package failed for some reason
     * and didn't provide appropriate backup data.
     *
     * @hide
     */
    @SystemApi
    public static final int ERROR_AGENT_FAILURE = BackupTransport.AGENT_ERROR;

    private Context mContext;
    private static IBackupManager sService;

@@ -365,4 +424,94 @@ public class BackupManager {
        }
        return 0;
    }

    /**
     * Request an immediate backup, providing an observer to which results of the backup operation
     * will be published. The Android backup system will decide for each package whether it will
     * be full app data backup or key/value-pair-based backup.
     *
     * <p>If this method returns {@link BackupManager#SUCCESS}, the OS will attempt to backup all
     * provided packages using the remote transport.
     *
     * @param packages List of package names to backup.
     * @param observer The {@link BackupObserver} to receive callbacks during the backup
     * operation.
     * @return {@link BackupManager#SUCCESS} on success; nonzero on error.
     * @exception  IllegalArgumentException on null or empty {@code packages} param.
     *
     * @hide
     */
    @SystemApi
    public int requestBackup(String[] packages, BackupObserver observer) {
        checkServiceBinder();
        if (sService != null) {
            try {
                BackupObserverWrapper observerWrapper =
                    new BackupObserverWrapper(mContext, observer);
                return sService.requestBackup(packages, observerWrapper);
            } catch (RemoteException e) {
                Log.e(TAG, "requestBackup() couldn't connect");
            }
        }
        return -1;
    }

    /*
     * We wrap incoming binder calls with a private class implementation that
     * redirects them into main-thread actions.  This serializes the backup
     * progress callbacks nicely within the usual main-thread lifecycle pattern.
     */
    @SystemApi
    private class BackupObserverWrapper extends IBackupObserver.Stub {
        final Handler mHandler;
        final BackupObserver mObserver;

        static final int MSG_UPDATE = 1;
        static final int MSG_RESULT = 2;
        static final int MSG_FINISHED = 3;

        BackupObserverWrapper(Context context, BackupObserver observer) {
            mHandler = new Handler(context.getMainLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                        case MSG_UPDATE:
                            Pair<String, BackupProgress> obj =
                                (Pair<String, BackupProgress>) msg.obj;
                            mObserver.onUpdate(obj.first, obj.second);
                            break;
                        case MSG_RESULT:
                            mObserver.onResult((String)msg.obj, msg.arg1);
                            break;
                        case MSG_FINISHED:
                            mObserver.backupFinished(msg.arg1);
                            break;
                        default:
                            Log.w(TAG, "Unknown message: " + msg);
                            break;
                    }
                }
            };
            mObserver = observer;
        }

        // Binder calls into this object just enqueue on the main-thread handler
        @Override
        public void onUpdate(String currentPackage, BackupProgress backupProgress) {
            mHandler.sendMessage(
                mHandler.obtainMessage(MSG_UPDATE, Pair.create(currentPackage, backupProgress)));
        }

        @Override
        public void onResult(String currentPackage, int status) {
            mHandler.sendMessage(
                mHandler.obtainMessage(MSG_FINISHED, status, 0, currentPackage));
        }

        @Override
        public void backupFinished(int status) {
            mHandler.sendMessage(
                mHandler.obtainMessage(MSG_FINISHED, status, 0));
        }
    }
}
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.annotation.SystemApi;

/**
 * Callback class for receiving progress reports during a backup operation.  These
 * methods will all be called on your application's main thread.
 *
 * @hide
 */
@SystemApi
public abstract class BackupObserver {
    /**
     * This method could be called several times for packages with full data backup.
     * It will tell how much of backup data is already saved and how much is expected.
     *
     * @param currentBackupPackage The name of the package that now being backuped.
     * @param backupProgress Current progress of backup for the package.
     */
    public void onUpdate(String currentBackupPackage, BackupProgress backupProgress) {
    }

    /**
     * The backup of single package has completed.  This method will be called at most one time
     * for each package and could be not called if backup is failed before and
     * backupFinished() is called.
     *
     * @param currentBackupPackage The name of the package that was backuped.
     * @param status Zero on success; a nonzero error code if the backup operation failed.
     */
    public void onResult(String currentBackupPackage, int status) {
    }

    /**
     * The backup process has completed.  This method will always be called,
     * even if no individual package backup operations were attempted.
     *
     * @param status Zero on success; a nonzero error code if the backup operation
     *   as a whole failed.
     */
    public void backupFinished(int status) {
    }
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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;

parcelable BackupProgress;
 No newline at end of file
Loading