RestoreSession.java revision 4528186e0d65fc68ef0dd1941aa2ac8aefcd55a3
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/**
3080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate * Interface for applications to use when managing a restore session.
3180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate */
3280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tatepublic class RestoreSession {
3380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    static final String TAG = "RestoreSession";
3480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
3580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    final Context mContext;
3680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    IRestoreSession mBinder;
3780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    RestoreObserverWrapper mObserver = null;
3880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
3980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /**
4080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * Ask the current transport what the available restore sets are.
4180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *
4280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * @return A bundle containing two elements:  an int array under the key
4380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   "tokens" whose entries are a transport-private identifier for each backup set;
4480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   and a String array under the key "names" whose entries are the user-meaningful
4580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   text corresponding to the backup sets at each index in the tokens array.
4680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   On error, returns null.
47e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
48e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * {@hide}
4980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     */
5080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    public RestoreSet[] getAvailableRestoreSets() {
5180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        try {
5280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            return mBinder.getAvailableRestoreSets();
5380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        } catch (RemoteException e) {
5480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            Log.d(TAG, "Can't contact server to get available sets");
5580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            return null;
5680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
5780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
5880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
5980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    /**
6080202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * Restore the given set onto the device, replacing the current data of any app
6180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * contained in the restore set with the data previously backed up.
6280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *
638472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
648472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *
6580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     * @return Zero on success; nonzero on error.  The observer will only receive
6680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   progress callbacks if this method returned zero.
677951eaa92a962e39ebba0366fdcafc4a0a78cc98Kenny Root     * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
6880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate     *   the restore set that should be used.
698472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     * @param observer If non-null, this binder points to an object that will receive
708472581aa32eee1368de379c2c079ea0a66baa3cChristopher Tate     *   progress callbacks during the restore operation.
71e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
72e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * {@hide}
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;
157d3cd359122348ebc72fcf699de871ad084908622Christopher Tate
15880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        RestoreObserverWrapper(Context context, RestoreObserver appObserver) {
159d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler = new Handler(context.getMainLooper()) {
160d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                @Override
161d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                public void handleMessage(Message msg) {
162d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    switch (msg.what) {
163d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_RESTORE_STARTING:
164d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        mAppObserver.restoreStarting(msg.arg1);
165d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
166d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_UPDATE:
167d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        mAppObserver.onUpdate(msg.arg1);
168d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
169d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    case MSG_RESTORE_FINISHED:
170d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        mAppObserver.restoreFinished(msg.arg1);
171d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                        break;
172d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    }
173d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                }
174d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            };
17580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate            mAppObserver = appObserver;
17680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
17780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
178d3cd359122348ebc72fcf699de871ad084908622Christopher Tate        // Binder calls into this object just enqueue on the main-thread handler
17980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        public void restoreStarting(int numPackages) {
180d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
181d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    mHandler.obtainMessage(MSG_RESTORE_STARTING, numPackages, 0));
18280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
18380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
18480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        public void onUpdate(int nowBeingRestored) {
185d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
186d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    mHandler.obtainMessage(MSG_UPDATE, nowBeingRestored, 0));
18780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
18880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate
18980202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        public void restoreFinished(int error) {
190d3cd359122348ebc72fcf699de871ad084908622Christopher Tate            mHandler.sendMessage(
191d3cd359122348ebc72fcf699de871ad084908622Christopher Tate                    mHandler.obtainMessage(MSG_RESTORE_FINISHED, error, 0));
19280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        }
19380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    }
19480202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate}
195