RestoreSession.java revision 2d449afe3d075020bdd1115bcc15c9383cbce122
180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate/*
280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * Copyright (C) 2010 The Android Open Source Project
380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate *
480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License");
580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * you may not use this file except in compliance with the License.
680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * You may obtain a copy of the License at
780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate *
880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate *      http://www.apache.org/licenses/LICENSE-2.0
980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate *
1080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * Unless required by applicable law or agreed to in writing, software
1180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS,
1280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * See the License for the specific language governing permissions and
1480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * limitations under the License.
1580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate */
1680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup;
1880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
194528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.RestoreObserver;
204528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.RestoreSet;
214528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IRestoreObserver;
224528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IRestoreSession;
2380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tateimport android.content.Context;
2480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tateimport android.os.Handler;
25d3cd359122348ebc72fcf699de871ad084908622Christopher Tateimport android.os.Message;
2680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tateimport android.os.RemoteException;
2780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tateimport android.util.Log;
2880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
2980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate/**
309c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * Interface for managing a restore session.
319c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * @hide
3280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate */
3380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tatepublic class RestoreSession {
3480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    static final String TAG = "RestoreSession";
3580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
3680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    final Context mContext;
3780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    IRestoreSession mBinder;
3880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    RestoreObserverWrapper mObserver = null;
3980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
4080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /**
4180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * Ask the current transport what the available restore sets are.
4280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *
432d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     * @param observer a RestoreObserver object whose restoreSetsAvailable() method will
442d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     *   be called on the application's main thread in order to supply the results of
452d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     *   the restore set lookup by the backup transport.  This parameter must not be
462d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     *   null.
472d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     * @return Zero on success, nonzero on error.  The observer's restoreSetsAvailable()
482d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate     *   method will only be called if this method returned zero.
4980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
502d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate    public int getAvailableRestoreSets(RestoreObserver observer) {
512d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        int err = -1;
522d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        RestoreObserverWrapper obsWrapper = new RestoreObserverWrapper(mContext, observer);
5380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        try {
542d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate            err = mBinder.getAvailableRestoreSets(obsWrapper);
5580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        } catch (RemoteException e) {
5680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            Log.d(TAG, "Can't contact server to get available sets");
5780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
582d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        return err;
5980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
6080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
6180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /**
6280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * Restore the given set onto the device, replacing the current data of any app
6380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * contained in the restore set with the data previously backed up.
6480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *
658472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
668472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *
6780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * @return Zero on success; nonzero on error.  The observer will only receive
6880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   progress callbacks if this method returned zero.
697951eaa92a962e39ebba0366fdcafc4a0a78cc98Kenny Root     * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
7080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   the restore set that should be used.
718472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * @param observer If non-null, this binder points to an object that will receive
728472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   progress callbacks during the restore operation.
738472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     */
748472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate    public int restoreAll(long token, RestoreObserver observer) {
758472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        int err = -1;
768472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        if (mObserver != null) {
778472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            Log.d(TAG, "restoreAll() called during active restore");
788472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            return -1;
798472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        }
808472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        mObserver = new RestoreObserverWrapper(mContext, observer);
818472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        try {
828472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            err = mBinder.restoreAll(token, mObserver);
838472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        } catch (RemoteException e) {
848472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            Log.d(TAG, "Can't contact server to restore");
858472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        }
868472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate        return err;
878472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate    }
888472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate
898472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate    /**
908472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * Restore a single application from backup.  The data will be restored from the
918472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * current backup dataset if the given package has stored data there, or from
928472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * the dataset used during the last full device setup operation if the current
938472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * backup dataset has no matching data.  If no backup data exists for this package
948472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * in either source, a nonzero value will be returned.
958472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *
968472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * @return Zero on success; nonzero on error.  The observer will only receive
978472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   progress callbacks if this method returned zero.
988472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * @param packageName The name of the package whose data to restore.  If this is
998472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   not the name of the caller's own package, then the android.permission.BACKUP
1008472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   permission must be held.
1018472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * @param observer If non-null, this binder points to an object that will receive
1028472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   progress callbacks during the restore operation.
10380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
1048472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate    public int restorePackage(String packageName, RestoreObserver observer) {
10580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        int err = -1;
10680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        if (mObserver != null) {
1078472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            Log.d(TAG, "restorePackage() called during active restore");
10880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            return -1;
10980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
11080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        mObserver = new RestoreObserverWrapper(mContext, observer);
11180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        try {
1128472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            err = mBinder.restorePackage(packageName, mObserver);
11380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        } catch (RemoteException e) {
1148472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate            Log.d(TAG, "Can't contact server to restore package");
11580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
11680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        return err;
11780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
11880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
11980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /**
12080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * End this restore session.  After this method is called, the RestoreSession
12180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * object is no longer valid.
12280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *
12380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * <p><b>Note:</b> The caller <i>must</i> invoke this method to end the restore session,
1247951eaa92a962e39ebba0366fdcafc4a0a78cc98Kenny Root     *   even if {@link #restorePackage(String, RestoreObserver)} failed.
12580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
12680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    public void endRestoreSession() {
12780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        try {
12880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            mBinder.endRestoreSession();
12980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        } catch (RemoteException e) {
13080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            Log.d(TAG, "Can't contact server to get available sets");
13180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        } finally {
13280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            mBinder = null;
13380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
13480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
13580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
13680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /*
13780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * Nonpublic implementation here
13880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
13980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
14080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    RestoreSession(Context context, IRestoreSession binder) {
14180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        mContext = context;
14280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        mBinder = binder;
14380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
14480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
14580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /*
14680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * We wrap incoming binder calls with a private class implementation that
14744a2790374bf27116cbd91060d4f096ca5999709Christopher Tate     * redirects them into main-thread actions.  This serializes the restore
14880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * progress callbacks nicely within the usual main-thread lifecycle pattern.
14980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
15080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    private class RestoreObserverWrapper extends IRestoreObserver.Stub {
15180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        final Handler mHandler;
15280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        final RestoreObserver mAppObserver;
15380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
154d3cd359122348ebc72fcf699de871ad084908622Christopher Tate        static final int MSG_RESTORE_STARTING = 1;
155d3cd359122348ebc72fcf699de871ad084908622Christopher Tate        static final int MSG_UPDATE = 2;
156d3cd359122348ebc72fcf699de871ad084908622Christopher Tate        static final int MSG_RESTORE_FINISHED = 3;
1572d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        static final int MSG_RESTORE_SETS_AVAILABLE = 4;
158d3cd359122348ebc72fcf699de871ad084908622Christopher Tate
15980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        RestoreObserverWrapper(Context context, RestoreObserver appObserver) {
160d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler = new Handler(context.getMainLooper()) {
161d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                @Override
162d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                public void handleMessage(Message msg) {
163d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    switch (msg.what) {
164d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_RESTORE_STARTING:
165d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        mAppObserver.restoreStarting(msg.arg1);
166d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
167d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_UPDATE:
1689c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                        mAppObserver.onUpdate(msg.arg1, (String)msg.obj);
169d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
170d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_RESTORE_FINISHED:
171d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        mAppObserver.restoreFinished(msg.arg1);
172d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
1732d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate                    case MSG_RESTORE_SETS_AVAILABLE:
1742d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate                        mAppObserver.restoreSetsAvailable((RestoreSet[])msg.obj);
1752d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate                        break;
176d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    }
177d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                }
178d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            };
17980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            mAppObserver = appObserver;
18080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
18180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
182d3cd359122348ebc72fcf699de871ad084908622Christopher Tate        // Binder calls into this object just enqueue on the main-thread handler
1832d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        public void restoreSetsAvailable(RestoreSet[] result) {
1842d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate            mHandler.sendMessage(
1852d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate                    mHandler.obtainMessage(MSG_RESTORE_SETS_AVAILABLE, result));
1862d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate        }
1872d449afe3d075020bdd1115bcc15c9383cbce122Christopher Tate
18880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        public void restoreStarting(int numPackages) {
189d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
190d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    mHandler.obtainMessage(MSG_RESTORE_STARTING, numPackages, 0));
19180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
19280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
1939c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        public void onUpdate(int nowBeingRestored, String currentPackage) {
194d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
1959c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                    mHandler.obtainMessage(MSG_UPDATE, nowBeingRestored, 0, currentPackage));
19680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
19780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
19880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        public void restoreFinished(int error) {
199d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
200d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    mHandler.obtainMessage(MSG_RESTORE_FINISHED, error, 0));
20180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
20280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
20380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate}
204