BackupManager.java revision fe06bf64d204c459699b0bf6465f9fb69208345e
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 19d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tateimport android.annotation.SystemApi; 20a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.content.Context; 21fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.os.Handler; 22fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.os.Message; 23a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.RemoteException; 24a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.ServiceManager; 25c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tateimport android.util.Log; 26fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.util.Pair; 27a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 28a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/** 29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * The interface through which an application interacts with the Android backup service to 30d17da43c82c4edb97514d6138bc208eeba321636Scott Main * request backup and restore operations. 31d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Applications instantiate it using the constructor and issue calls through that instance. 325a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 335a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * When an application has made changes to data which should be backed up, a 345a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * call to {@link #dataChanged()} will notify the backup service. The system 355a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * will then schedule a backup operation to occur in the near future. Repeated 365a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * calls to {@link #dataChanged()} have no further effect until the backup 375a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation actually occurs. 385a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A backup or restore operation for your application begins when the system launches the 40d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link android.app.backup.BackupAgent} subclass you've declared in your manifest. See the 414528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * documentation for {@link android.app.backup.BackupAgent} for a detailed description 424e14a829129feee14ebe453f61a124784c870610Christopher Tate * of how the operation then proceeds. 435a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 444e14a829129feee14ebe453f61a124784c870610Christopher Tate * Several attributes affecting the operation of the backup and restore mechanism 4561fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * can be set on the <code> 4661fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> 47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * tag in your application's AndroidManifest.xml file. 48d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 4961fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <div class="special reference"> 5061fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <h3>Developer Guides</h3> 5161fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <p>For more information about using BackupManager, read the 5261fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/data/backup.html">Data Backup</a> developer guide.</p></div> 5361fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * 545a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup 555a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent 565a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore 574e14a829129feee14ebe453f61a124784c870610Christopher Tate * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion 58a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 59a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tatepublic class BackupManager { 60c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static final String TAG = "BackupManager"; 61c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate 62fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov // BackupObserver status codes 63fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 64fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * Indicates that backup succeeded. 65fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 66fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 67fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 68fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 69fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int SUCCESS = 0; 70fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 71fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 72fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * Indicates that backup is either not enabled at all or 73fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * backup for the package was rejected by backup service 74fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * or backup transport, 75fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 76fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 77fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 78fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 79fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int ERROR_BACKUP_NOT_ALLOWED = -2001; 80fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 81fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 82fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * The requested app is not installed on the device. 83fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 84fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 85fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 86fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 87fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int ERROR_PACKAGE_NOT_FOUND = -2002; 88fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 89fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 90fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * The transport for some reason was not in a good state and 91fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * aborted the entire backup request. This is a transient 92fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * failure and should not be retried immediately. 93fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 94fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 95fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 96fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 97fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int ERROR_TRANSPORT_ABORTED = BackupTransport.TRANSPORT_ERROR; 98fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 99fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 100fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * Returned when the transport was unable to process the 101fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * backup request for a given package, for example if the 102fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * transport hit a transient network failure. The remaining 103fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * packages provided to {@link #requestBackup(String[], BackupObserver)} 104fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * will still be attempted. 105fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 106fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 107fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 108fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 109fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int ERROR_TRANSPORT_PACKAGE_REJECTED = 110fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov BackupTransport.TRANSPORT_PACKAGE_REJECTED; 111fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 112fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 113fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * The {@link BackupAgent} for the requested package failed for some reason 114fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * and didn't provide appropriate backup data. 115fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 116fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 117fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 118fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 119fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public static final int ERROR_AGENT_FAILURE = BackupTransport.AGENT_ERROR; 120fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 121a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate private Context mContext; 122c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static IBackupManager sService; 123a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 124c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate private static void checkServiceBinder() { 125c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService == null) { 126c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService = IBackupManager.Stub.asInterface( 127c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate ServiceManager.getService(Context.BACKUP_SERVICE)); 128c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 129c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 130043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate 131043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate /** 132a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Constructs a BackupManager object through which the application can 133a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * communicate with the Android backup system. 134c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate * 135a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * @param context The {@link android.content.Context} that was provided when 136a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * one of your application's {@link android.app.Activity Activities} 137a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * was created. 138a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 139c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate public BackupManager(Context context) { 140a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate mContext = context; 141a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 142a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate 143a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate /** 144a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Notifies the Android backup system that your application wishes to back up 145a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * new changes to its data. A backup operation using your application's 1464e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link android.app.backup.BackupAgent} subclass will be scheduled when you 1474e14a829129feee14ebe453f61a124784c870610Christopher Tate * call this method. 148a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */ 149a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate public void dataChanged() { 150c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 151c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 152c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate try { 153c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService.dataChanged(mContext.getPackageName()); 154c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } catch (RemoteException e) { 155c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate Log.d(TAG, "dataChanged() couldn't connect"); 156c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 157c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 158c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate } 159c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate 160c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate /** 161c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate * Convenience method for callers who need to indicate that some other package 1624e14a829129feee14ebe453f61a124784c870610Christopher Tate * needs a backup pass. This can be useful in the case of groups of packages 1634e14a829129feee14ebe453f61a124784c870610Christopher Tate * that share a uid. 1644e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 165c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate * This method requires that the application hold the "android.permission.BACKUP" 1664e14a829129feee14ebe453f61a124784c870610Christopher Tate * permission if the package named in the argument does not run under the same uid 1674e14a829129feee14ebe453f61a124784c870610Christopher Tate * as the caller. 168d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 169d17da43c82c4edb97514d6138bc208eeba321636Scott Main * @param packageName The package name identifying the application to back up. 170c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate */ 171c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate public static void dataChanged(String packageName) { 172c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 173c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 1748a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate try { 175c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate sService.dataChanged(packageName); 1768a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } catch (RemoteException e) { 177d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "dataChanged(pkg) couldn't connect"); 1788a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } 179a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 180a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate } 1819b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate 1829b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate /** 1839c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * Restore the calling application from backup. The data will be restored from the 1849c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * current backup dataset if the application has stored data there, or from 1859c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * the dataset used during the last full device setup operation if the current 1869c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * backup dataset has no matching data. If no backup data exists for this application 1879c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * in either source, a nonzero value will be returned. 1889c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * 1899c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * <p>If this method returns zero (meaning success), the OS will attempt to retrieve 1909c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * a backed-up dataset from the remote transport, instantiate the application's 1919c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * backup agent, and pass the dataset to the agent's 1929c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()} 1939c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * method. 1949c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * 195d17da43c82c4edb97514d6138bc208eeba321636Scott Main * @param observer The {@link RestoreObserver} to receive callbacks during the restore 196d17da43c82c4edb97514d6138bc208eeba321636Scott Main * operation. This must not be null. 197d17da43c82c4edb97514d6138bc208eeba321636Scott Main * 1989c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * @return Zero on success; nonzero on error. 1999c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate */ 2009c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate public int requestRestore(RestoreObserver observer) { 2019c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate int result = -1; 2029c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate checkServiceBinder(); 2039c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate if (sService != null) { 2049c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate RestoreSession session = null; 2059c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate try { 20644ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(), 20744ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate null); 208f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate if (binder != null) { 209f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate session = new RestoreSession(mContext, binder); 210f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate result = session.restorePackage(mContext.getPackageName(), observer); 211f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate } 2129c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } catch (RemoteException e) { 213d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "restoreSelf() unable to contact service"); 2149c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } finally { 2159c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate if (session != null) { 2169c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate session.endRestoreSession(); 2179c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 2189c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 2199c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 2209c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate return result; 2219c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate } 2229c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate 2232e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate // system APIs start here 2242e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate 2259c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate /** 226e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * Begin the process of restoring data from backup. See the 2274528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * {@link android.app.backup.RestoreSession} class for documentation on that process. 2289c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate * @hide 2299b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate */ 2302e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate @SystemApi 23180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate public RestoreSession beginRestoreSession() { 23280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate RestoreSession session = null; 233c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate checkServiceBinder(); 234c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate if (sService != null) { 2358a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate try { 23644ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate // All packages, current transport 23744ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate IRestoreSession binder = sService.beginRestoreSession(null, null); 238f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate if (binder != null) { 239f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate session = new RestoreSession(mContext, binder); 240f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate } 2418a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } catch (RemoteException e) { 242d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "beginRestoreSession() couldn't connect"); 2438a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate } 2449b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate } 24580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate return session; 2469b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate } 247d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 248d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 249d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Enable/disable the backup service entirely. When disabled, no backup 250d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * or restore operations will take place. Data-changed notifications will 251d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * still be observed and collected, however, so that changes made while the 252d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * mechanism was disabled will still be backed up properly if it is enabled 253d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * at some point in the future. 254d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 255d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * <p>Callers must hold the android.permission.BACKUP permission to use this method. 256d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 257d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 258d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 259d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 260d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public void setBackupEnabled(boolean isEnabled) { 261d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate checkServiceBinder(); 262d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 263d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 264d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate sService.setBackupEnabled(isEnabled); 265d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 266d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "setBackupEnabled() couldn't connect"); 267d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 268d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 269d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 270d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 271d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 272d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Report whether the backup mechanism is currently enabled. 273d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 274d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * <p>Callers must hold the android.permission.BACKUP permission to use this method. 275d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 276d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 277d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 278d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 279d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public boolean isBackupEnabled() { 2809e079298edd022c43a960729442a53557fd16e45Christopher Tate checkServiceBinder(); 281d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 282d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 283d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return sService.isBackupEnabled(); 284d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 285d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "isBackupEnabled() couldn't connect"); 286d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 287d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 288d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return false; 289d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 290d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 291d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 292a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * Enable/disable data restore at application install time. When enabled, app 293a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * installation will include an attempt to fetch the app's historical data from 294a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * the archival restore dataset (if any). When disabled, no such attempt will 295a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * be made. 296a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * 297a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * <p>Callers must hold the android.permission.BACKUP permission to use this method. 298a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * 299a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate * @hide 300a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate */ 301a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate @SystemApi 302a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate public void setAutoRestore(boolean isEnabled) { 303a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate checkServiceBinder(); 304a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate if (sService != null) { 305a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate try { 306a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate sService.setAutoRestore(isEnabled); 307a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate } catch (RemoteException e) { 308a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate Log.e(TAG, "setAutoRestore() couldn't connect"); 309a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate } 310a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate } 311a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate } 312a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate 313a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate /** 314d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Identify the currently selected transport. Callers must hold the 315d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * android.permission.BACKUP permission to use this method. 316d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @return The name of the currently active backup transport. In case of 317d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * failure or if no transport is currently active, this method returns {@code null}. 318d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 319d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 320d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 321d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 322d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public String getCurrentTransport() { 323d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate checkServiceBinder(); 324d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 325d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 326d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return sService.getCurrentTransport(); 327d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 328d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "getCurrentTransport() couldn't connect"); 329d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 330d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 331d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return null; 332d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 333d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 334d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 335d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Request a list of all available backup transports' names. Callers must 336d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * hold the android.permission.BACKUP permission to use this method. 337d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 338d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 339d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 340d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 341d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public String[] listAllTransports() { 342d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate checkServiceBinder(); 343d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 344d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 345d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return sService.listAllTransports(); 346d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 347d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "listAllTransports() couldn't connect"); 348d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 349d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 350d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return null; 351d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 352d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 353d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 354d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Specify the current backup transport. Callers must hold the 355d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * android.permission.BACKUP permission to use this method. 356d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 357d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @param transport The name of the transport to select. This should be one 358d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * of the names returned by {@link #listAllTransports()}. 359d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @return The name of the previously selected transport. If the given transport 360d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * name is not one of the currently available transports, no change is made to 361d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * the current transport setting and the method returns null. 362d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 363d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 364d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 365d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 366d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public String selectBackupTransport(String transport) { 367d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate checkServiceBinder(); 368d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 369d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 370d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return sService.selectBackupTransport(transport); 371d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 372d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "selectBackupTransport() couldn't connect"); 373d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 374d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 375d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate return null; 376d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 377d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate 378d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate /** 379d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * Schedule an immediate backup attempt for all pending key/value updates. This 380d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * is primarily intended for transports to use when they detect a suitable 381d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * opportunity for doing a backup pass. If there are no pending updates to 382d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * be sent, no action will be taken. Even if some updates are pending, the 383d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * transport will still be asked to confirm via the usual requestBackupTime() 384d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * method. 385d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 386d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * <p>Callers must hold the android.permission.BACKUP permission to use this method. 387d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * 388d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate * @hide 389d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate */ 390d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate @SystemApi 391d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate public void backupNow() { 392d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate checkServiceBinder(); 393d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate if (sService != null) { 394d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate try { 395d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate sService.backupNow(); 396d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } catch (RemoteException e) { 397d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate Log.e(TAG, "backupNow() couldn't connect"); 398d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 399d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 400d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate } 401511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate 402511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate /** 403511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * Ask the framework which dataset, if any, the given package's data would be 404511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * restored from if we were to install it right now. 405511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * 406511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * <p>Callers must hold the android.permission.BACKUP permission to use this method. 407511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * 408511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * @param packageName The name of the package whose most-suitable dataset we 409511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * wish to look up 410511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * @return The dataset token from which a restore should be attempted, or zero if 411511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * no suitable data is available. 412511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * 413511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate * @hide 414511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate */ 415511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate @SystemApi 416511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate public long getAvailableRestoreToken(String packageName) { 417511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate checkServiceBinder(); 418511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate if (sService != null) { 419511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate try { 420511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate return sService.getAvailableRestoreToken(packageName); 421511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate } catch (RemoteException e) { 422511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate Log.e(TAG, "getAvailableRestoreToken() couldn't connect"); 423511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate } 424511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate } 425511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate return 0; 426511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate } 427fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 428fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /** 429fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * Request an immediate backup, providing an observer to which results of the backup operation 430fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * will be published. The Android backup system will decide for each package whether it will 431fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * be full app data backup or key/value-pair-based backup. 432fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 433fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * <p>If this method returns {@link BackupManager#SUCCESS}, the OS will attempt to backup all 434fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * provided packages using the remote transport. 435fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 436fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @param packages List of package names to backup. 437fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @param observer The {@link BackupObserver} to receive callbacks during the backup 438fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * operation. 439fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @return {@link BackupManager#SUCCESS} on success; nonzero on error. 440fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @exception IllegalArgumentException on null or empty {@code packages} param. 441fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * 442fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * @hide 443fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 444fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 445fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public int requestBackup(String[] packages, BackupObserver observer) { 446fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov checkServiceBinder(); 447fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov if (sService != null) { 448fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov try { 449fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov BackupObserverWrapper observerWrapper = 450fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov new BackupObserverWrapper(mContext, observer); 451fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov return sService.requestBackup(packages, observerWrapper); 452fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } catch (RemoteException e) { 453fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov Log.e(TAG, "requestBackup() couldn't connect"); 454fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 455fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 456fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov return -1; 457fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 458fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 459fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov /* 460fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * We wrap incoming binder calls with a private class implementation that 461fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * redirects them into main-thread actions. This serializes the backup 462fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov * progress callbacks nicely within the usual main-thread lifecycle pattern. 463fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov */ 464fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @SystemApi 465fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov private class BackupObserverWrapper extends IBackupObserver.Stub { 466fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov final Handler mHandler; 467fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov final BackupObserver mObserver; 468fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 469fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov static final int MSG_UPDATE = 1; 470fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov static final int MSG_RESULT = 2; 471fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov static final int MSG_FINISHED = 3; 472fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 473fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov BackupObserverWrapper(Context context, BackupObserver observer) { 474fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler = new Handler(context.getMainLooper()) { 475fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @Override 476fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public void handleMessage(Message msg) { 477fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov switch (msg.what) { 478fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov case MSG_UPDATE: 479fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov Pair<String, BackupProgress> obj = 480fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov (Pair<String, BackupProgress>) msg.obj; 481fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mObserver.onUpdate(obj.first, obj.second); 482fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov break; 483fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov case MSG_RESULT: 484fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mObserver.onResult((String)msg.obj, msg.arg1); 485fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov break; 486fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov case MSG_FINISHED: 487fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mObserver.backupFinished(msg.arg1); 488fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov break; 489fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov default: 490fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov Log.w(TAG, "Unknown message: " + msg); 491fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov break; 492fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 493fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 494fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov }; 495fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mObserver = observer; 496fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 497fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 498fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov // Binder calls into this object just enqueue on the main-thread handler 499fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @Override 500fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public void onUpdate(String currentPackage, BackupProgress backupProgress) { 501fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.sendMessage( 502fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.obtainMessage(MSG_UPDATE, Pair.create(currentPackage, backupProgress))); 503fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 504fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 505fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @Override 506fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public void onResult(String currentPackage, int status) { 507fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.sendMessage( 508fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.obtainMessage(MSG_FINISHED, status, 0, currentPackage)); 509fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 510fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov 511fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov @Override 512fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov public void backupFinished(int status) { 513fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.sendMessage( 514fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov mHandler.obtainMessage(MSG_FINISHED, status, 0)); 515fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 516fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov } 517a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate} 518