Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2009 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 | |
Christopher Tate | 4528186 | 2010-03-05 15:46:30 -0800 | [diff] [blame] | 17 | package android.app.backup; |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 18 | |
Christopher Tate | 4528186 | 2010-03-05 15:46:30 -0800 | [diff] [blame] | 19 | import android.app.backup.RestoreSession; |
| 20 | import android.app.backup.IBackupManager; |
| 21 | import android.app.backup.IRestoreSession; |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 22 | import android.content.Context; |
| 23 | import android.os.RemoteException; |
| 24 | import android.os.ServiceManager; |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 25 | import android.util.Log; |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 26 | |
| 27 | /** |
Scott Main | d17da43 | 2010-04-29 21:42:58 -0700 | [diff] [blame] | 28 | * The interface through which an application interacts with the Android backup service to |
| 29 | * request backup and restore operations. |
| 30 | * Applications instantiate it using the constructor and issue calls through that instance. |
Kenny Root | 5a20ea1 | 2010-02-23 18:49:11 -0800 | [diff] [blame] | 31 | * <p> |
| 32 | * When an application has made changes to data which should be backed up, a |
| 33 | * call to {@link #dataChanged()} will notify the backup service. The system |
| 34 | * will then schedule a backup operation to occur in the near future. Repeated |
| 35 | * calls to {@link #dataChanged()} have no further effect until the backup |
| 36 | * operation actually occurs. |
| 37 | * <p> |
Scott Main | d17da43 | 2010-04-29 21:42:58 -0700 | [diff] [blame] | 38 | * A backup or restore operation for your application begins when the system launches the |
| 39 | * {@link android.app.backup.BackupAgent} subclass you've declared in your manifest. See the |
Christopher Tate | 4528186 | 2010-03-05 15:46:30 -0800 | [diff] [blame] | 40 | * documentation for {@link android.app.backup.BackupAgent} for a detailed description |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 41 | * of how the operation then proceeds. |
Kenny Root | 5a20ea1 | 2010-02-23 18:49:11 -0800 | [diff] [blame] | 42 | * <p> |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 43 | * Several attributes affecting the operation of the backup and restore mechanism |
Joe Fernandez | 61fd1e8 | 2011-10-26 13:39:11 -0700 | [diff] [blame] | 44 | * can be set on the <code> |
| 45 | * <a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> |
Scott Main | d17da43 | 2010-04-29 21:42:58 -0700 | [diff] [blame] | 46 | * tag in your application's AndroidManifest.xml file. |
| 47 | * |
Joe Fernandez | 61fd1e8 | 2011-10-26 13:39:11 -0700 | [diff] [blame] | 48 | * <div class="special reference"> |
| 49 | * <h3>Developer Guides</h3> |
| 50 | * <p>For more information about using BackupManager, read the |
| 51 | * <a href="{@docRoot}guide/topics/data/backup.html">Data Backup</a> developer guide.</p></div> |
| 52 | * |
Kenny Root | 5a20ea1 | 2010-02-23 18:49:11 -0800 | [diff] [blame] | 53 | * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup |
| 54 | * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent |
Kenny Root | 5a20ea1 | 2010-02-23 18:49:11 -0800 | [diff] [blame] | 55 | * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 56 | * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 57 | */ |
| 58 | public class BackupManager { |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 59 | private static final String TAG = "BackupManager"; |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 60 | |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 61 | private Context mContext; |
| 62 | private static IBackupManager sService; |
| 63 | |
| 64 | private static void checkServiceBinder() { |
| 65 | if (sService == null) { |
| 66 | sService = IBackupManager.Stub.asInterface( |
| 67 | ServiceManager.getService(Context.BACKUP_SERVICE)); |
| 68 | } |
| 69 | } |
Christopher Tate | 043dadc | 2009-06-02 16:11:00 -0700 | [diff] [blame] | 70 | |
| 71 | /** |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 72 | * Constructs a BackupManager object through which the application can |
| 73 | * communicate with the Android backup system. |
Christopher Tate | c114eb5 | 2009-04-30 12:40:19 -0700 | [diff] [blame] | 74 | * |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 75 | * @param context The {@link android.content.Context} that was provided when |
| 76 | * one of your application's {@link android.app.Activity Activities} |
| 77 | * was created. |
| 78 | */ |
Christopher Tate | c114eb5 | 2009-04-30 12:40:19 -0700 | [diff] [blame] | 79 | public BackupManager(Context context) { |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 80 | mContext = context; |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Notifies the Android backup system that your application wishes to back up |
| 85 | * new changes to its data. A backup operation using your application's |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 86 | * {@link android.app.backup.BackupAgent} subclass will be scheduled when you |
| 87 | * call this method. |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 88 | */ |
| 89 | public void dataChanged() { |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 90 | checkServiceBinder(); |
| 91 | if (sService != null) { |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 92 | try { |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 93 | sService.dataChanged(mContext.getPackageName()); |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 94 | } catch (RemoteException e) { |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 95 | Log.d(TAG, "dataChanged() couldn't connect"); |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Convenience method for callers who need to indicate that some other package |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 102 | * needs a backup pass. This can be useful in the case of groups of packages |
| 103 | * that share a uid. |
| 104 | * <p> |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 105 | * This method requires that the application hold the "android.permission.BACKUP" |
Christopher Tate | 4e14a82 | 2010-04-08 12:54:23 -0700 | [diff] [blame] | 106 | * permission if the package named in the argument does not run under the same uid |
| 107 | * as the caller. |
Scott Main | d17da43 | 2010-04-29 21:42:58 -0700 | [diff] [blame] | 108 | * |
| 109 | * @param packageName The package name identifying the application to back up. |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 110 | */ |
| 111 | public static void dataChanged(String packageName) { |
| 112 | checkServiceBinder(); |
| 113 | if (sService != null) { |
| 114 | try { |
| 115 | sService.dataChanged(packageName); |
| 116 | } catch (RemoteException e) { |
| 117 | Log.d(TAG, "dataChanged(pkg) couldn't connect"); |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 118 | } |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 119 | } |
| 120 | } |
Christopher Tate | 9b3905c | 2009-06-08 15:24:01 -0700 | [diff] [blame] | 121 | |
| 122 | /** |
Christopher Tate | 9c3cee9 | 2010-03-25 16:06:43 -0700 | [diff] [blame] | 123 | * Restore the calling application from backup. The data will be restored from the |
| 124 | * current backup dataset if the application has stored data there, or from |
| 125 | * the dataset used during the last full device setup operation if the current |
| 126 | * backup dataset has no matching data. If no backup data exists for this application |
| 127 | * in either source, a nonzero value will be returned. |
| 128 | * |
| 129 | * <p>If this method returns zero (meaning success), the OS will attempt to retrieve |
| 130 | * a backed-up dataset from the remote transport, instantiate the application's |
| 131 | * backup agent, and pass the dataset to the agent's |
| 132 | * {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()} |
| 133 | * method. |
| 134 | * |
Scott Main | d17da43 | 2010-04-29 21:42:58 -0700 | [diff] [blame] | 135 | * @param observer The {@link RestoreObserver} to receive callbacks during the restore |
| 136 | * operation. This must not be null. |
| 137 | * |
Christopher Tate | 9c3cee9 | 2010-03-25 16:06:43 -0700 | [diff] [blame] | 138 | * @return Zero on success; nonzero on error. |
| 139 | */ |
| 140 | public int requestRestore(RestoreObserver observer) { |
| 141 | int result = -1; |
| 142 | checkServiceBinder(); |
| 143 | if (sService != null) { |
| 144 | RestoreSession session = null; |
| 145 | try { |
Chris Tate | 44ab845 | 2010-11-16 15:10:49 -0800 | [diff] [blame] | 146 | IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(), |
| 147 | null); |
Christopher Tate | f5491fc | 2012-05-25 14:14:49 -0700 | [diff] [blame] | 148 | if (binder != null) { |
| 149 | session = new RestoreSession(mContext, binder); |
| 150 | result = session.restorePackage(mContext.getPackageName(), observer); |
| 151 | } |
Christopher Tate | 9c3cee9 | 2010-03-25 16:06:43 -0700 | [diff] [blame] | 152 | } catch (RemoteException e) { |
| 153 | Log.w(TAG, "restoreSelf() unable to contact service"); |
| 154 | } finally { |
| 155 | if (session != null) { |
| 156 | session.endRestoreSession(); |
| 157 | } |
| 158 | } |
| 159 | } |
| 160 | return result; |
| 161 | } |
| 162 | |
| 163 | /** |
Christopher Tate | e28290e | 2010-02-16 15:22:26 -0800 | [diff] [blame] | 164 | * Begin the process of restoring data from backup. See the |
Christopher Tate | 4528186 | 2010-03-05 15:46:30 -0800 | [diff] [blame] | 165 | * {@link android.app.backup.RestoreSession} class for documentation on that process. |
Christopher Tate | 9c3cee9 | 2010-03-25 16:06:43 -0700 | [diff] [blame] | 166 | * @hide |
Christopher Tate | 9b3905c | 2009-06-08 15:24:01 -0700 | [diff] [blame] | 167 | */ |
Christopher Tate | 80202c8 | 2010-01-25 19:37:47 -0800 | [diff] [blame] | 168 | public RestoreSession beginRestoreSession() { |
Christopher Tate | 80202c8 | 2010-01-25 19:37:47 -0800 | [diff] [blame] | 169 | RestoreSession session = null; |
Christopher Tate | c8daa76 | 2009-07-06 19:04:57 -0700 | [diff] [blame] | 170 | checkServiceBinder(); |
| 171 | if (sService != null) { |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 172 | try { |
Chris Tate | 44ab845 | 2010-11-16 15:10:49 -0800 | [diff] [blame] | 173 | // All packages, current transport |
| 174 | IRestoreSession binder = sService.beginRestoreSession(null, null); |
Christopher Tate | f5491fc | 2012-05-25 14:14:49 -0700 | [diff] [blame] | 175 | if (binder != null) { |
| 176 | session = new RestoreSession(mContext, binder); |
| 177 | } |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 178 | } catch (RemoteException e) { |
Christopher Tate | e28290e | 2010-02-16 15:22:26 -0800 | [diff] [blame] | 179 | Log.w(TAG, "beginRestoreSession() couldn't connect"); |
Christopher Tate | 8a27f92 | 2009-06-26 11:49:18 -0700 | [diff] [blame] | 180 | } |
Christopher Tate | 9b3905c | 2009-06-08 15:24:01 -0700 | [diff] [blame] | 181 | } |
Christopher Tate | 80202c8 | 2010-01-25 19:37:47 -0800 | [diff] [blame] | 182 | return session; |
Christopher Tate | 9b3905c | 2009-06-08 15:24:01 -0700 | [diff] [blame] | 183 | } |
Christopher Tate | a8bf815 | 2009-04-30 11:36:21 -0700 | [diff] [blame] | 184 | } |