• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.backup;
18 
19 import android.annotation.SystemApi;
20 import android.app.backup.RestoreObserver;
21 import android.app.backup.RestoreSet;
22 import android.app.backup.IRestoreObserver;
23 import android.app.backup.IRestoreSession;
24 import android.content.Context;
25 import android.os.Bundle;
26 import android.os.Handler;
27 import android.os.Message;
28 import android.os.RemoteException;
29 import android.util.Log;
30 
31 /**
32  * Interface for managing a restore session.
33  * @hide
34  */
35 @SystemApi
36 public class RestoreSession {
37     static final String TAG = "RestoreSession";
38 
39     final Context mContext;
40     IRestoreSession mBinder;
41     RestoreObserverWrapper mObserver = null;
42 
43     /**
44      * Ask the current transport what the available restore sets are.
45      *
46      * @param observer a RestoreObserver object whose restoreSetsAvailable() method will
47      *   be called on the application's main thread in order to supply the results of
48      *   the restore set lookup by the backup transport.  This parameter must not be
49      *   null.
50      * @param monitor a BackupManagerMonitor object will supply data about important events.
51      * @return Zero on success, nonzero on error.  The observer's restoreSetsAvailable()
52      *   method will only be called if this method returned zero.
53      */
getAvailableRestoreSets(RestoreObserver observer, BackupManagerMonitor monitor)54     public int getAvailableRestoreSets(RestoreObserver observer, BackupManagerMonitor monitor) {
55         int err = -1;
56         RestoreObserverWrapper obsWrapper = new RestoreObserverWrapper(mContext, observer);
57         BackupManagerMonitorWrapper monitorWrapper = monitor == null
58                 ? null
59                 : new BackupManagerMonitorWrapper(monitor);
60         try {
61             err = mBinder.getAvailableRestoreSets(obsWrapper, monitorWrapper);
62         } catch (RemoteException e) {
63             Log.d(TAG, "Can't contact server to get available sets");
64         }
65         return err;
66     }
67 
68     /**
69      * Ask the current transport what the available restore sets are.
70      *
71      * @param observer a RestoreObserver object whose restoreSetsAvailable() method will
72      *   be called on the application's main thread in order to supply the results of
73      *   the restore set lookup by the backup transport.  This parameter must not be
74      *   null.
75      * @return Zero on success, nonzero on error.  The observer's restoreSetsAvailable()
76      *   method will only be called if this method returned zero.
77      */
getAvailableRestoreSets(RestoreObserver observer)78     public int getAvailableRestoreSets(RestoreObserver observer) {
79         return getAvailableRestoreSets(observer, null);
80     }
81 
82     /**
83      * Restore the given set onto the device, replacing the current data of any app
84      * contained in the restore set with the data previously backed up.
85      *
86      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
87      *
88      * @return Zero on success; nonzero on error.  The observer will only receive
89      *   progress callbacks if this method returned zero.
90      * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
91      *   the restore set that should be used.
92      * @param observer If non-null, this binder points to an object that will receive
93      *   progress callbacks during the restore operation.
94      * @param monitor If non-null, this binder points to an object that will receive
95      *   progress callbacks during the restore operation.
96      */
restoreAll(long token, RestoreObserver observer, BackupManagerMonitor monitor)97     public int restoreAll(long token, RestoreObserver observer, BackupManagerMonitor monitor) {
98         int err = -1;
99         if (mObserver != null) {
100             Log.d(TAG, "restoreAll() called during active restore");
101             return -1;
102         }
103         mObserver = new RestoreObserverWrapper(mContext, observer);
104         BackupManagerMonitorWrapper monitorWrapper = monitor == null
105                 ? null
106                 : new BackupManagerMonitorWrapper(monitor);
107         try {
108             err = mBinder.restoreAll(token, mObserver, monitorWrapper);
109         } catch (RemoteException e) {
110             Log.d(TAG, "Can't contact server to restore");
111         }
112         return err;
113     }
114 
115     /**
116      * Restore the given set onto the device, replacing the current data of any app
117      * contained in the restore set with the data previously backed up.
118      *
119      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
120      *
121      * @return Zero on success; nonzero on error.  The observer will only receive
122      *   progress callbacks if this method returned zero.
123      * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
124      *   the restore set that should be used.
125      * @param observer If non-null, this binder points to an object that will receive
126      *   progress callbacks during the restore operation.
127      */
restoreAll(long token, RestoreObserver observer)128     public int restoreAll(long token, RestoreObserver observer) {
129         return restoreAll(token, observer, null);
130     }
131 
132     /**
133      * Restore select packages from the given set onto the device, replacing the
134      * current data of any app contained in the set with the data previously
135      * backed up.
136      *
137      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
138      *
139      * @return Zero on success, nonzero on error. The observer will only receive
140      *   progress callbacks if this method returned zero.
141      * @param token The token from {@link getAvailableRestoreSets()} corresponding to
142      *   the restore set that should be used.
143      * @param observer If non-null, this binder points to an object that will receive
144      *   progress callbacks during the restore operation.
145      * @param monitor If non-null, this binder points to an object that will receive
146      *   progress callbacks during the restore operation.
147      * @param packages The set of packages for which to attempt a restore.  Regardless of
148      *   the contents of the actual back-end dataset named by {@code token}, only
149      *   applications mentioned in this list will have their data restored.
150      *
151      * @hide
152      */
restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor, String[] packages)153     public int restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor,
154             String[] packages) {
155         int err = -1;
156         if (mObserver != null) {
157             Log.d(TAG, "restoreAll() called during active restore");
158             return -1;
159         }
160         mObserver = new RestoreObserverWrapper(mContext, observer);
161         BackupManagerMonitorWrapper monitorWrapper = monitor == null
162                 ? null
163                 : new BackupManagerMonitorWrapper(monitor);
164         try {
165             err = mBinder.restoreSome(token, mObserver, monitorWrapper, packages);
166         } catch (RemoteException e) {
167             Log.d(TAG, "Can't contact server to restore packages");
168         }
169         return err;
170     }
171 
172     /**
173      * Restore select packages from the given set onto the device, replacing the
174      * current data of any app contained in the set with the data previously
175      * backed up.
176      *
177      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
178      *
179      * @return Zero on success, nonzero on error. The observer will only receive
180      *   progress callbacks if this method returned zero.
181      * @param token The token from {@link getAvailableRestoreSets()} corresponding to
182      *   the restore set that should be used.
183      * @param observer If non-null, this binder points to an object that will receive
184      *   progress callbacks during the restore operation.
185      * @param packages The set of packages for which to attempt a restore.  Regardless of
186      *   the contents of the actual back-end dataset named by {@code token}, only
187      *   applications mentioned in this list will have their data restored.
188      *
189      * @hide
190      */
restoreSome(long token, RestoreObserver observer, String[] packages)191     public int restoreSome(long token, RestoreObserver observer, String[] packages) {
192         return restoreSome(token, observer, null, packages);
193     }
194 
195     /**
196      * Restore a single application from backup.  The data will be restored from the
197      * current backup dataset if the given package has stored data there, or from
198      * the dataset used during the last full device setup operation if the current
199      * backup dataset has no matching data.  If no backup data exists for this package
200      * in either source, a nonzero value will be returned.
201      *
202      * @return Zero on success; nonzero on error.  The observer will only receive
203      *   progress callbacks if this method returned zero.
204      * @param packageName The name of the package whose data to restore.  If this is
205      *   not the name of the caller's own package, then the android.permission.BACKUP
206      *   permission must be held.
207      * @param observer If non-null, this binder points to an object that will receive
208      *   progress callbacks during the restore operation.
209      *
210      * @param monitor If non-null, this binder points to an object that will receive
211      *   event callbacks during the restore operation.
212      */
restorePackage(String packageName, RestoreObserver observer, BackupManagerMonitor monitor)213     public int restorePackage(String packageName, RestoreObserver observer,
214             BackupManagerMonitor monitor) {
215         int err = -1;
216         if (mObserver != null) {
217             Log.d(TAG, "restorePackage() called during active restore");
218             return -1;
219         }
220         mObserver = new RestoreObserverWrapper(mContext, observer);
221         BackupManagerMonitorWrapper monitorWrapper = monitor == null
222                 ? null
223                 : new BackupManagerMonitorWrapper(monitor);
224         try {
225             err = mBinder.restorePackage(packageName, mObserver, monitorWrapper);
226         } catch (RemoteException e) {
227             Log.d(TAG, "Can't contact server to restore package");
228         }
229         return err;
230     }
231 
232 
233     /**
234      * Restore a single application from backup.  The data will be restored from the
235      * current backup dataset if the given package has stored data there, or from
236      * the dataset used during the last full device setup operation if the current
237      * backup dataset has no matching data.  If no backup data exists for this package
238      * in either source, a nonzero value will be returned.
239      *
240      * @return Zero on success; nonzero on error.  The observer will only receive
241      *   progress callbacks if this method returned zero.
242      * @param packageName The name of the package whose data to restore.  If this is
243      *   not the name of the caller's own package, then the android.permission.BACKUP
244      *   permission must be held.
245      * @param observer If non-null, this binder points to an object that will receive
246      *   progress callbacks during the restore operation.
247      */
restorePackage(String packageName, RestoreObserver observer)248     public int restorePackage(String packageName, RestoreObserver observer) {
249         return restorePackage(packageName, observer, null);
250     }
251 
252     /**
253      * End this restore session.  After this method is called, the RestoreSession
254      * object is no longer valid.
255      *
256      * <p><b>Note:</b> The caller <i>must</i> invoke this method to end the restore session,
257      *   even if {@link #restorePackage(String, RestoreObserver)} failed.
258      */
endRestoreSession()259     public void endRestoreSession() {
260         try {
261             mBinder.endRestoreSession();
262         } catch (RemoteException e) {
263             Log.d(TAG, "Can't contact server to get available sets");
264         } finally {
265             mBinder = null;
266         }
267     }
268 
269     /*
270      * Nonpublic implementation here
271      */
272 
RestoreSession(Context context, IRestoreSession binder)273     RestoreSession(Context context, IRestoreSession binder) {
274         mContext = context;
275         mBinder = binder;
276     }
277 
278     /*
279      * We wrap incoming binder calls with a private class implementation that
280      * redirects them into main-thread actions.  This serializes the restore
281      * progress callbacks nicely within the usual main-thread lifecycle pattern.
282      */
283     private class RestoreObserverWrapper extends IRestoreObserver.Stub {
284         final Handler mHandler;
285         final RestoreObserver mAppObserver;
286 
287         static final int MSG_RESTORE_STARTING = 1;
288         static final int MSG_UPDATE = 2;
289         static final int MSG_RESTORE_FINISHED = 3;
290         static final int MSG_RESTORE_SETS_AVAILABLE = 4;
291 
RestoreObserverWrapper(Context context, RestoreObserver appObserver)292         RestoreObserverWrapper(Context context, RestoreObserver appObserver) {
293             mHandler = new Handler(context.getMainLooper()) {
294                 @Override
295                 public void handleMessage(Message msg) {
296                     switch (msg.what) {
297                     case MSG_RESTORE_STARTING:
298                         mAppObserver.restoreStarting(msg.arg1);
299                         break;
300                     case MSG_UPDATE:
301                         mAppObserver.onUpdate(msg.arg1, (String)msg.obj);
302                         break;
303                     case MSG_RESTORE_FINISHED:
304                         mAppObserver.restoreFinished(msg.arg1);
305                         break;
306                     case MSG_RESTORE_SETS_AVAILABLE:
307                         mAppObserver.restoreSetsAvailable((RestoreSet[])msg.obj);
308                         break;
309                     }
310                 }
311             };
312             mAppObserver = appObserver;
313         }
314 
315         // Binder calls into this object just enqueue on the main-thread handler
restoreSetsAvailable(RestoreSet[] result)316         public void restoreSetsAvailable(RestoreSet[] result) {
317             mHandler.sendMessage(
318                     mHandler.obtainMessage(MSG_RESTORE_SETS_AVAILABLE, result));
319         }
320 
restoreStarting(int numPackages)321         public void restoreStarting(int numPackages) {
322             mHandler.sendMessage(
323                     mHandler.obtainMessage(MSG_RESTORE_STARTING, numPackages, 0));
324         }
325 
onUpdate(int nowBeingRestored, String currentPackage)326         public void onUpdate(int nowBeingRestored, String currentPackage) {
327             mHandler.sendMessage(
328                     mHandler.obtainMessage(MSG_UPDATE, nowBeingRestored, 0, currentPackage));
329         }
330 
restoreFinished(int error)331         public void restoreFinished(int error) {
332             mHandler.sendMessage(
333                     mHandler.obtainMessage(MSG_RESTORE_FINISHED, error, 0));
334         }
335     }
336 
337     private class BackupManagerMonitorWrapper extends IBackupManagerMonitor.Stub {
338         final BackupManagerMonitor mMonitor;
339 
BackupManagerMonitorWrapper(BackupManagerMonitor monitor)340         BackupManagerMonitorWrapper(BackupManagerMonitor monitor) {
341             mMonitor = monitor;
342         }
343 
344         @Override
onEvent(final Bundle event)345         public void onEvent(final Bundle event) throws RemoteException {
346             mMonitor.onEvent(event);
347         }
348     }
349 }
350