1487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate/* 2487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * Copyright (C) 2009 The Android Open Source Project 3487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * 4487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License"); 5487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * you may not use this file except in compliance with the License. 6487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * You may obtain a copy of the License at 7487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * 8487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * http://www.apache.org/licenses/LICENSE-2.0 9487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * 10487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * Unless required by applicable law or agreed to in writing, software 11487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS, 12487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * See the License for the specific language governing permissions and 14487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate * limitations under the License. 15487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate */ 16487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup; 18487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 19181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tateimport android.app.IBackupAgent; 204528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IBackupManager; 21181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tateimport android.content.Context; 22181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tateimport android.content.ContextWrapper; 231902492420825874b12962a10712e653901d120dChristopher Tateimport android.os.Binder; 24487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tateimport android.os.IBinder; 2522b8787ed4be8d4b7ed5d54802f9913fedb41425Christopher Tateimport android.os.ParcelFileDescriptor; 26487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tateimport android.os.RemoteException; 27487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tateimport android.util.Log; 28487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 2983248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onoratoimport java.io.IOException; 3083248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato 31487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate/** 32d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Provides the central interface between an 334e14a829129feee14ebe453f61a124784c870610Christopher Tate * application and Android's data backup infrastructure. An application that wishes 344e14a829129feee14ebe453f61a124784c870610Christopher Tate * to participate in the backup and restore mechanism will declare a subclass of 354e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link android.app.backup.BackupAgent}, implement the 36d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup()} 37d17da43c82c4edb97514d6138bc208eeba321636Scott Main * and {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor) onRestore()} methods, 38d17da43c82c4edb97514d6138bc208eeba321636Scott Main * and provide the name of its backup agent class in its {@code AndroidManifest.xml} file via 39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * the <code><a 40d17da43c82c4edb97514d6138bc208eeba321636Scott Main * href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> 41d17da43c82c4edb97514d6138bc208eeba321636Scott Main * tag's {@code android:backupAgent} attribute. 42d17da43c82c4edb97514d6138bc208eeba321636Scott Main * <h3>Basic Operation</h3> 435a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 444e14a829129feee14ebe453f61a124784c870610Christopher Tate * When the application makes changes to data that it wishes to keep backed up, 454e14a829129feee14ebe453f61a124784c870610Christopher Tate * it should call the 464e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link android.app.backup.BackupManager#dataChanged() BackupManager.dataChanged()} method. 47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * This notifies the Android Backup Manager that the application needs an opportunity 48d17da43c82c4edb97514d6138bc208eeba321636Scott Main * to update its backup image. The Backup Manager, in turn, schedules a 494e14a829129feee14ebe453f61a124784c870610Christopher Tate * backup pass to be performed at an opportune time. 504e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 51d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Restore operations are typically performed only when applications are first 524e14a829129feee14ebe453f61a124784c870610Christopher Tate * installed on a device. At that time, the operating system checks to see whether 53d17da43c82c4edb97514d6138bc208eeba321636Scott Main * there is a previously-saved data set available for the application being installed, and if so, 54d17da43c82c4edb97514d6138bc208eeba321636Scott Main * begins an immediate restore pass to deliver the backup data as part of the installation 554e14a829129feee14ebe453f61a124784c870610Christopher Tate * process. 564e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 57d17da43c82c4edb97514d6138bc208eeba321636Scott Main * When a backup or restore pass is run, the application's process is launched 58d17da43c82c4edb97514d6138bc208eeba321636Scott Main * (if not already running), the manifest-declared backup agent class (in the {@code 59d17da43c82c4edb97514d6138bc208eeba321636Scott Main * android:backupAgent} attribute) is instantiated within 60d17da43c82c4edb97514d6138bc208eeba321636Scott Main * that process, and the agent's {@link #onCreate()} method is invoked. This prepares the 614e14a829129feee14ebe453f61a124784c870610Christopher Tate * agent instance to run the actual backup or restore logic. At this point the 624e14a829129feee14ebe453f61a124784c870610Christopher Tate * agent's 634e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup()} or 644e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor) onRestore()} method will be 654e14a829129feee14ebe453f61a124784c870610Christopher Tate * invoked as appropriate for the operation being performed. 664e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 67d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A backup data set consists of one or more "entities," flattened binary data 68d17da43c82c4edb97514d6138bc208eeba321636Scott Main * records that are each identified with a key string unique within the data set. Adding a 69d17da43c82c4edb97514d6138bc208eeba321636Scott Main * record to the active data set or updating an existing record is done by simply 704e14a829129feee14ebe453f61a124784c870610Christopher Tate * writing new entity data under the desired key. Deleting an entity from the data set 714e14a829129feee14ebe453f61a124784c870610Christopher Tate * is done by writing an entity under that key with header specifying a negative data 724e14a829129feee14ebe453f61a124784c870610Christopher Tate * size, and no actual entity data. 734e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 744e14a829129feee14ebe453f61a124784c870610Christopher Tate * <b>Helper Classes</b> 754e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 764e14a829129feee14ebe453f61a124784c870610Christopher Tate * An extensible agent based on convenient helper classes is available in 774e14a829129feee14ebe453f61a124784c870610Christopher Tate * {@link android.app.backup.BackupAgentHelper}. That class is particularly 784e14a829129feee14ebe453f61a124784c870610Christopher Tate * suited to handling of simple file or {@link android.content.SharedPreferences} 794e14a829129feee14ebe453f61a124784c870610Christopher Tate * backup and restore. 804e14a829129feee14ebe453f61a124784c870610Christopher Tate * 814e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see android.app.backup.BackupManager 824e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see android.app.backup.BackupAgentHelper 834e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see android.app.backup.BackupDataInput 844e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see android.app.backup.BackupDataOutput 85487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate */ 86181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tatepublic abstract class BackupAgent extends ContextWrapper { 8783248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato private static final String TAG = "BackupAgent"; 88436344ae12c819f58306ceb94241a266141e1218Christopher Tate private static final boolean DEBUG = false; 8983248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato 90181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate public BackupAgent() { 91181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate super(null); 92181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate } 93487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 944e14a829129feee14ebe453f61a124784c870610Christopher Tate /** 954e14a829129feee14ebe453f61a124784c870610Christopher Tate * Provided as a convenience for agent implementations that need an opportunity 964e14a829129feee14ebe453f61a124784c870610Christopher Tate * to do one-time initialization before the actual backup or restore operation 974e14a829129feee14ebe453f61a124784c870610Christopher Tate * is begun. 984e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 994e14a829129feee14ebe453f61a124784c870610Christopher Tate * Agents do not need to override this method. 1004e14a829129feee14ebe453f61a124784c870610Christopher Tate */ 101181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate public void onCreate() { 102181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate } 103181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate 1044e14a829129feee14ebe453f61a124784c870610Christopher Tate /** 1054e14a829129feee14ebe453f61a124784c870610Christopher Tate * Provided as a convenience for agent implementations that need to do some 1064e14a829129feee14ebe453f61a124784c870610Christopher Tate * sort of shutdown process after backup or restore is completed. 1074e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 1084e14a829129feee14ebe453f61a124784c870610Christopher Tate * Agents do not need to override this method. 1094e14a829129feee14ebe453f61a124784c870610Christopher Tate */ 110181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate public void onDestroy() { 111181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate } 112487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 113487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate /** 1145a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * The application is being asked to write any data changed since the last 1155a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * time it performed a backup operation. The state data recorded during the 1165a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * last backup pass is provided in the <code>oldState</code> file 1175a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * descriptor. If <code>oldState</code> is <code>null</code>, no old state 1185a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * is available and the application should perform a full backup. In both 1195a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * cases, a representation of the final backup state after this pass should 1205a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * be written to the file pointed to by the file descriptor wrapped in 1215a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <code>newState</code>. 1224e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 1234e14a829129feee14ebe453f61a124784c870610Christopher Tate * Each entity written to the {@link android.app.backup.BackupDataOutput} 1244e14a829129feee14ebe453f61a124784c870610Christopher Tate * <code>data</code> stream will be transmitted 1254e14a829129feee14ebe453f61a124784c870610Christopher Tate * over the current backup transport and stored in the remote data set under 1264e14a829129feee14ebe453f61a124784c870610Christopher Tate * the key supplied as part of the entity. Writing an entity with a negative 1274e14a829129feee14ebe453f61a124784c870610Christopher Tate * data size instructs the transport to delete whatever entity currently exists 1284e14a829129feee14ebe453f61a124784c870610Christopher Tate * under that key from the remote data set. 1295a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * 1305a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @param oldState An open, read-only ParcelFileDescriptor pointing to the 1315a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * last backup state provided by the application. May be 1325a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <code>null</code>, in which case no prior state is being 1335a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * provided and the application should perform a full backup. 1345a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @param data A structured wrapper around an open, read/write 1354e14a829129feee14ebe453f61a124784c870610Christopher Tate * file descriptor pointing to the backup data destination. 1365a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * Typically the application will use backup helper classes to 1375a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * write to this file. 1385a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @param newState An open, read/write ParcelFileDescriptor pointing to an 1395a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * empty file. The application should record the final backup 1404e14a829129feee14ebe453f61a124784c870610Christopher Tate * state here after writing the requested data to the <code>data</code> 1414e14a829129feee14ebe453f61a124784c870610Christopher Tate * output stream. 142487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate */ 143290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, 1444ababd922eac5931e0222862ff082dc29e012816Joe Onorato ParcelFileDescriptor newState) throws IOException; 1455a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root 146487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate /** 1475a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * The application is being restored from backup and should replace any 1485a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * existing data with the contents of the backup. The backup data is 1494e14a829129feee14ebe453f61a124784c870610Christopher Tate * provided through the <code>data</code> parameter. Once 1505a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * the restore is finished, the application should write a representation of 1515a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * the final state to the <code>newState</code> file descriptor. 1525a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p> 1535a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * The application is responsible for properly erasing its old data and 1545a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * replacing it with the data supplied to this method. No "clear user data" 1555a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation will be performed automatically by the operating system. The 1565a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * exception to this is in the case of a failed restore attempt: if 1575a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * onRestore() throws an exception, the OS will assume that the 1585a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * application's data may now be in an incoherent state, and will clear it 1595a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * before proceeding. 1605a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * 1615a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @param data A structured wrapper around an open, read-only 1624e14a829129feee14ebe453f61a124784c870610Christopher Tate * file descriptor pointing to a full snapshot of the 1634e14a829129feee14ebe453f61a124784c870610Christopher Tate * application's data. The application should consume every 1644e14a829129feee14ebe453f61a124784c870610Christopher Tate * entity represented in this data stream. 165b83a283ac178ab0a72f1d811189d79b26097835eScott Main * @param appVersionCode The value of the <a 166b83a283ac178ab0a72f1d811189d79b26097835eScott Main * href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code 167b83a283ac178ab0a72f1d811189d79b26097835eScott Main * android:versionCode}</a> manifest attribute, 168b83a283ac178ab0a72f1d811189d79b26097835eScott Main * from the application that backed up this particular data set. This 1694e14a829129feee14ebe453f61a124784c870610Christopher Tate * makes it possible for an application's agent to distinguish among any 1705a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * possible older data versions when asked to perform the restore 1715a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation. 1725a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @param newState An open, read/write ParcelFileDescriptor pointing to an 1735a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * empty file. The application should record the final backup 1744e14a829129feee14ebe453f61a124784c870610Christopher Tate * state here after restoring its data from the <code>data</code> stream. 175487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate */ 1765cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate public abstract void onRestore(BackupDataInput data, int appVersionCode, 1775cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate ParcelFileDescriptor newState) 17883248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato throws IOException; 179487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 180487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 181487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate // ----- Core implementation ----- 18244a2790374bf27116cbd91060d4f096ca5999709Christopher Tate 18344a2790374bf27116cbd91060d4f096ca5999709Christopher Tate /** @hide */ 18444a2790374bf27116cbd91060d4f096ca5999709Christopher Tate public final IBinder onBind() { 185181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate return mBinder; 186487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate } 187487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 188487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate private final IBinder mBinder = new BackupServiceBinder().asBinder(); 189487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 190181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate /** @hide */ 191181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate public void attach(Context context) { 192181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate attachBaseContext(context); 193181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate } 194181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate 195487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate // ----- IBackupService binder interface ----- 196181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate private class BackupServiceBinder extends IBackupAgent.Stub { 197181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate private static final String TAG = "BackupServiceBinder"; 198181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate 19922b8787ed4be8d4b7ed5d54802f9913fedb41425Christopher Tate public void doBackup(ParcelFileDescriptor oldState, 20022b8787ed4be8d4b7ed5d54802f9913fedb41425Christopher Tate ParcelFileDescriptor data, 20144a2790374bf27116cbd91060d4f096ca5999709Christopher Tate ParcelFileDescriptor newState, 20244a2790374bf27116cbd91060d4f096ca5999709Christopher Tate int token, IBackupManager callbackBinder) throws RemoteException { 2031902492420825874b12962a10712e653901d120dChristopher Tate // Ensure that we're running with the app's normal permission level 20444a2790374bf27116cbd91060d4f096ca5999709Christopher Tate long ident = Binder.clearCallingIdentity(); 2051902492420825874b12962a10712e653901d120dChristopher Tate 206436344ae12c819f58306ceb94241a266141e1218Christopher Tate if (DEBUG) Log.v(TAG, "doBackup() invoked"); 20783248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor()); 208290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato try { 209181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate BackupAgent.this.onBackup(oldState, output, newState); 2104ababd922eac5931e0222862ff082dc29e012816Joe Onorato } catch (IOException ex) { 2114ababd922eac5931e0222862ff082dc29e012816Joe Onorato Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex); 2124ababd922eac5931e0222862ff082dc29e012816Joe Onorato throw new RuntimeException(ex); 213290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato } catch (RuntimeException ex) { 21483248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex); 215290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato throw ex; 2161902492420825874b12962a10712e653901d120dChristopher Tate } finally { 21744a2790374bf27116cbd91060d4f096ca5999709Christopher Tate Binder.restoreCallingIdentity(ident); 21844a2790374bf27116cbd91060d4f096ca5999709Christopher Tate try { 21944a2790374bf27116cbd91060d4f096ca5999709Christopher Tate callbackBinder.opComplete(token); 22044a2790374bf27116cbd91060d4f096ca5999709Christopher Tate } catch (RemoteException e) { 22144a2790374bf27116cbd91060d4f096ca5999709Christopher Tate // we'll time out anyway, so we're safe 22244a2790374bf27116cbd91060d4f096ca5999709Christopher Tate } 223290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato } 224487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate } 225487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate 2265cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate public void doRestore(ParcelFileDescriptor data, int appVersionCode, 22744a2790374bf27116cbd91060d4f096ca5999709Christopher Tate ParcelFileDescriptor newState, 22844a2790374bf27116cbd91060d4f096ca5999709Christopher Tate int token, IBackupManager callbackBinder) throws RemoteException { 2291902492420825874b12962a10712e653901d120dChristopher Tate // Ensure that we're running with the app's normal permission level 23044a2790374bf27116cbd91060d4f096ca5999709Christopher Tate long ident = Binder.clearCallingIdentity(); 2311902492420825874b12962a10712e653901d120dChristopher Tate 232436344ae12c819f58306ceb94241a266141e1218Christopher Tate if (DEBUG) Log.v(TAG, "doRestore() invoked"); 23383248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato BackupDataInput input = new BackupDataInput(data.getFileDescriptor()); 23483248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato try { 2355cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate BackupAgent.this.onRestore(input, appVersionCode, newState); 23683248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato } catch (IOException ex) { 23783248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex); 23883248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato throw new RuntimeException(ex); 23983248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato } catch (RuntimeException ex) { 24083248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex); 24183248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato throw ex; 2421902492420825874b12962a10712e653901d120dChristopher Tate } finally { 24344a2790374bf27116cbd91060d4f096ca5999709Christopher Tate Binder.restoreCallingIdentity(ident); 24444a2790374bf27116cbd91060d4f096ca5999709Christopher Tate try { 24544a2790374bf27116cbd91060d4f096ca5999709Christopher Tate callbackBinder.opComplete(token); 24644a2790374bf27116cbd91060d4f096ca5999709Christopher Tate } catch (RemoteException e) { 24744a2790374bf27116cbd91060d4f096ca5999709Christopher Tate // we'll time out anyway, so we're safe 24844a2790374bf27116cbd91060d4f096ca5999709Christopher Tate } 24983248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato } 250487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate } 251487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate } 252487529a70cd1479ae8d6bbfb356be7e72542c185Christopher Tate} 253