1a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/* 2a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Copyright (C) 2009 The Android Open Source Project 3a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * 4a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License"); 5a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * you may not use this file except in compliance with the License. 6a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * You may obtain a copy of the License at 7a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * 8a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * http://www.apache.org/licenses/LICENSE-2.0 9a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * 10a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Unless required by applicable law or agreed to in writing, software 11a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS, 12a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * See the License for the specific language governing permissions and 14a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * limitations under the License. 15a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 16a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup; 18a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 194528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.RestoreSession; 204528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IBackupManager; 214528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IRestoreSession; 22a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.content.Context; 23a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.RemoteException; 24a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.ServiceManager; 25c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tateimport android.util.Log; 26a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 27a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/** 28d17da43c82c4edb97514d6138bc208eeba321636Scott Main * The interface through which an application interacts with the Android backup service to 29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * request backup and restore operations. 30d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Applications instantiate it using the constructor and issue calls through that instance. 315a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 325a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * When an application has made changes to data which should be backed up, a 335a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * call to {@link #dataChanged()} will notify the backup service. The system 345a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * will then schedule a backup operation to occur in the near future. Repeated 355a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * calls to {@link #dataChanged()} have no further effect until the backup 365a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation actually occurs. 375a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 38d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A backup or restore operation for your application begins when the system launches the 39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link android.app.backup.BackupAgent} subclass you've declared in your manifest. See the 404528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * documentation for {@link android.app.backup.BackupAgent} for a detailed description 414e14a829129feee14ebe453f61a124784c870610Christopher Tate * of how the operation then proceeds. 425a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 434e14a829129feee14ebe453f61a124784c870610Christopher Tate * Several attributes affecting the operation of the backup and restore mechanism 44d17da43c82c4edb97514d6138bc208eeba321636Scott Main * can be set on the <code><a 45d17da43c82c4edb97514d6138bc208eeba321636Scott Main * href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> 46d17da43c82c4edb97514d6138bc208eeba321636Scott Main * tag in your application's AndroidManifest.xml file. 47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 485a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup 495a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent 505a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore 514e14a829129feee14ebe453f61a124784c870610Christopher Tate * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion 52a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 53a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tatepublic class BackupManager { 54c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static final String TAG = "BackupManager"; 55c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate 56a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate private Context mContext; 57c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static IBackupManager sService; 58a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 59c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static void checkServiceBinder() { 60c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService == null) { 61c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService = IBackupManager.Stub.asInterface( 62c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate ServiceManager.getService(Context.BACKUP_SERVICE)); 63c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 64c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 65043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate 66043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate /** 67a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Constructs a BackupManager object through which the application can 68a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * communicate with the Android backup system. 69c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate * 70a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * @param context The {@link android.content.Context} that was provided when 71a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * one of your application's {@link android.app.Activity Activities} 72a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * was created. 73a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 74c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate public BackupManager(Context context) { 75a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate mContext = context; 76a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 77a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 78a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate /** 79a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Notifies the Android backup system that your application wishes to back up 80a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * new changes to its data. A backup operation using your application's 814e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link android.app.backup.BackupAgent} subclass will be scheduled when you 824e14a829129feee14ebe453f61a124784c870610Christopher Tate * call this method. 83a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 84a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate public void dataChanged() { 85c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 86c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 87c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate try { 88c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService.dataChanged(mContext.getPackageName()); 89c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } catch (RemoteException e) { 90c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate Log.d(TAG, "dataChanged() couldn't connect"); 91c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 92c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 93c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 94c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate 95c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate /** 96c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate * Convenience method for callers who need to indicate that some other package 974e14a829129feee14ebe453f61a124784c870610Christopher Tate * needs a backup pass. This can be useful in the case of groups of packages 984e14a829129feee14ebe453f61a124784c870610Christopher Tate * that share a uid. 994e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 100c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate * This method requires that the application hold the "android.permission.BACKUP" 1014e14a829129feee14ebe453f61a124784c870610Christopher Tate * permission if the package named in the argument does not run under the same uid 1024e14a829129feee14ebe453f61a124784c870610Christopher Tate * as the caller. 103d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 104d17da43c82c4edb97514d6138bc208eeba321636Scott Main * @param packageName The package name identifying the application to back up. 105c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate */ 106c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate public static void dataChanged(String packageName) { 107c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 108c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 1098a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate try { 110c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService.dataChanged(packageName); 1118a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } catch (RemoteException e) { 112c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate Log.d(TAG, "dataChanged(pkg) couldn't connect"); 1138a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } 114a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 115a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 1169b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate 1179b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate /** 1189c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * Restore the calling application from backup. The data will be restored from the 1199c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * current backup dataset if the application has stored data there, or from 1209c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * the dataset used during the last full device setup operation if the current 1219c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * backup dataset has no matching data. If no backup data exists for this application 1229c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * in either source, a nonzero value will be returned. 1239c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * 1249c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * <p>If this method returns zero (meaning success), the OS will attempt to retrieve 1259c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * a backed-up dataset from the remote transport, instantiate the application's 1269c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * backup agent, and pass the dataset to the agent's 1279c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()} 1289c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * method. 1299c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * 130d17da43c82c4edb97514d6138bc208eeba321636Scott Main * @param observer The {@link RestoreObserver} to receive callbacks during the restore 131d17da43c82c4edb97514d6138bc208eeba321636Scott Main * operation. This must not be null. 132d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 1339c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * @return Zero on success; nonzero on error. 1349c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate */ 1359c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate public int requestRestore(RestoreObserver observer) { 1369c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate int result = -1; 1379c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate checkServiceBinder(); 1389c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate if (sService != null) { 1399c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate RestoreSession session = null; 1409c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate try { 1419c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate String transport = sService.getCurrentTransport(); 1429c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate IRestoreSession binder = sService.beginRestoreSession(transport); 1439c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate session = new RestoreSession(mContext, binder); 1449c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate result = session.restorePackage(mContext.getPackageName(), observer); 1459c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } catch (RemoteException e) { 1469c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate Log.w(TAG, "restoreSelf() unable to contact service"); 1479c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } finally { 1489c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate if (session != null) { 1499c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate session.endRestoreSession(); 1509c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 1519c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 1529c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 1539c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate return result; 1549c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 1559c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate 1569c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate /** 157e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * Begin the process of restoring data from backup. See the 1584528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * {@link android.app.backup.RestoreSession} class for documentation on that process. 1599c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * @hide 1609b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate */ 16180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate public RestoreSession beginRestoreSession() { 16280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate RestoreSession session = null; 163c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 164c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 1658a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate try { 16680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate String transport = sService.getCurrentTransport(); 16780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate IRestoreSession binder = sService.beginRestoreSession(transport); 16880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate session = new RestoreSession(mContext, binder); 1698a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } catch (RemoteException e) { 170e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate Log.w(TAG, "beginRestoreSession() couldn't connect"); 1718a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } 1729b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate } 17380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate return session; 1749b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate } 175a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate} 176