Loading core/java/com/android/internal/backup/BackupConstants.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.backup; /** * Constants used internally between the backup manager and its transports */ public class BackupConstants { public static final int TRANSPORT_OK = 0; public static final int TRANSPORT_ERROR = 1; public static final int TRANSPORT_NOT_INITIALIZED = 2; } core/java/com/android/internal/backup/IBackupTransport.aidl +7 −3 Original line number Diff line number Diff line Loading @@ -81,10 +81,14 @@ interface IBackupTransport { * will be erased prior to the storage of the data provided here. The purpose of this * is to provide a guarantee that no stale data exists in the restore set when the * device begins providing backups. * @return false if errors occurred (the backup should be aborted and rescheduled), * true if everything is OK so far (but {@link #finishBackup} must be called). * @return If everything is okay so far, returns zero (but {@link #finishBackup} must * still be called). If the backend dataset has unexpectedly become unavailable, * such as when it is deleted after a period of device inactivity, returns {@link * BackupManager#DATASET_UNAVAILABLE}; in this case, the transport should be * reinitalized and the entire backup pass restarted. Any other nonzero value is a * fatal error requiring that this package's backup be aborted and rescheduled. */ boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd, int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd, boolean wipeAllFirst); /** Loading core/java/com/android/internal/backup/LocalTransport.java +4 −4 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ public class LocalTransport extends IBackupTransport.Stub { return 0; } public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, boolean wipeAllFirst) throws RemoteException { if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName); Loading Loading @@ -99,7 +99,7 @@ public class LocalTransport extends IBackupTransport.Stub { entity.write(buf, 0, dataSize); } catch (IOException e) { Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); return false; return BackupConstants.TRANSPORT_ERROR; } finally { entity.close(); } Loading @@ -107,11 +107,11 @@ public class LocalTransport extends IBackupTransport.Stub { entityFile.delete(); } } return true; return BackupConstants.TRANSPORT_OK; } catch (IOException e) { // oops, something went wrong. abort the operation and return error. Log.v(TAG, "Exception reading backup input:", e); return false; return BackupConstants.TRANSPORT_ERROR; } } Loading services/java/com/android/server/BackupManagerService.java +70 −6 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.backup.IRestoreObserver; import android.backup.IRestoreSession; import android.backup.RestoreSet; import com.android.internal.backup.BackupConstants; import com.android.internal.backup.LocalTransport; import com.android.internal.backup.IBackupTransport; Loading Loading @@ -101,6 +102,7 @@ class BackupManagerService extends IBackupManager.Stub { private static final int BACKUP_AGENT_FAILURE_EVENT = 2823; private static final int BACKUP_PACKAGE_EVENT = 2824; private static final int BACKUP_SUCCESS_EVENT = 2825; private static final int BACKUP_RESET_EVENT = 2826; private static final int RESTORE_START_EVENT = 2830; private static final int RESTORE_TRANSPORT_FAILURE_EVENT = 2831; Loading Loading @@ -406,6 +408,47 @@ class BackupManagerService extends IBackupManager.Stub { } } // Reset all of our bookkeeping, in response to having been told that // the backend data has been wiped [due to idle expiry, for example], // so we must re-upload all saved settings. void resetBackupState(File stateFileDir) { synchronized (mQueueLock) { // Wipe the "what we've ever backed up" tracking try { // close the ever-stored journal... if (mEverStoredStream != null) { mEverStoredStream.close(); } // ... so we can delete it and start over mEverStored.delete(); mEverStoredStream = new RandomAccessFile(mEverStored, "rwd"); } catch (IOException e) { Log.e(TAG, "Unable to open known-stored file!"); mEverStoredStream = null; } mEverStoredApps.clear(); // Remove all the state files for (File sf : stateFileDir.listFiles()) { sf.delete(); } // Enqueue a new backup of every participant int N = mBackupParticipants.size(); for (int i=0; i<N; i++) { int uid = mBackupParticipants.keyAt(i); HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i); for (ApplicationInfo app: participants) { try { dataChanged(app.packageName); } catch (RemoteException e) { // can't happen; we're in the same process } } } } } // Add a transport to our set of available backends private void registerTransport(String name, IBackupTransport transport) { synchronized (mTransports) { Loading Loading @@ -891,8 +934,22 @@ class BackupManagerService extends IBackupManager.Stub { // If we haven't stored anything yet, we need to do an init // operation along with recording the metadata blob. boolean needInit = (mEverStoredApps.size() == 0); processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), int result = processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport, needInit); if (result == BackupConstants.TRANSPORT_NOT_INITIALIZED) { // The backend reports that our dataset has been wiped. We need to // reset all of our bookkeeping and instead run a new backup pass for // everything. EventLog.writeEvent(BACKUP_RESET_EVENT, mTransport.transportDirName()); resetBackupState(mStateDir); backupNow(); return; } else if (result != BackupConstants.TRANSPORT_OK) { // Give up if we couldn't even process the metadata Log.e(TAG, "Meta backup err " + result); return; } // Now run all the backups in our queue int count = mQueue.size(); Loading Loading @@ -953,7 +1010,7 @@ class BackupManagerService extends IBackupManager.Stub { } } void processOneBackup(BackupRequest request, IBackupAgent agent, int processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport, boolean doInit) { final String packageName = request.appInfo.packageName; if (DEBUG) Log.d(TAG, "processOneBackup doBackup(" + doInit + ") on " + packageName); Loading Loading @@ -1007,7 +1064,7 @@ class BackupManagerService extends IBackupManager.Stub { EventLog.writeEvent(BACKUP_AGENT_FAILURE_EVENT, packageName, e.toString()); backupDataName.delete(); newStateName.delete(); return; return BackupConstants.TRANSPORT_ERROR; } finally { try { if (savedState != null) savedState.close(); } catch (IOException e) {} try { if (backupData != null) backupData.close(); } catch (IOException e) {} Loading @@ -1027,7 +1084,13 @@ class BackupManagerService extends IBackupManager.Stub { // hold off on finishBackup() until the end, which implies holding off on // renaming *all* the output state files (see below) until that happens. if (!transport.performBackup(packInfo, backupData, doInit) || int performOkay = transport.performBackup(packInfo, backupData, doInit); if (performOkay == BackupConstants.TRANSPORT_NOT_INITIALIZED) { Log.i(TAG, "Backend not initialized"); return performOkay; } if ((performOkay != 0) || !transport.finishBackup()) { throw new Exception("Backup transport failed"); } Loading @@ -1044,10 +1107,12 @@ class BackupManagerService extends IBackupManager.Stub { } catch (Exception e) { Log.e(TAG, "Transport error backing up " + packageName, e); EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName); return; return BackupConstants.TRANSPORT_ERROR; } finally { try { if (backupData != null) backupData.close(); } catch (IOException e) {} } return BackupConstants.TRANSPORT_OK; } } Loading Loading @@ -1590,7 +1655,6 @@ class BackupManagerService extends IBackupManager.Stub { if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass"); synchronized (mQueueLock) { try { if (DEBUG) Log.v(TAG, "sending immediate backup broadcast"); mRunBackupIntent.send(); } catch (PendingIntent.CanceledException e) { // should never happen Loading Loading
core/java/com/android/internal/backup/BackupConstants.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.backup; /** * Constants used internally between the backup manager and its transports */ public class BackupConstants { public static final int TRANSPORT_OK = 0; public static final int TRANSPORT_ERROR = 1; public static final int TRANSPORT_NOT_INITIALIZED = 2; }
core/java/com/android/internal/backup/IBackupTransport.aidl +7 −3 Original line number Diff line number Diff line Loading @@ -81,10 +81,14 @@ interface IBackupTransport { * will be erased prior to the storage of the data provided here. The purpose of this * is to provide a guarantee that no stale data exists in the restore set when the * device begins providing backups. * @return false if errors occurred (the backup should be aborted and rescheduled), * true if everything is OK so far (but {@link #finishBackup} must be called). * @return If everything is okay so far, returns zero (but {@link #finishBackup} must * still be called). If the backend dataset has unexpectedly become unavailable, * such as when it is deleted after a period of device inactivity, returns {@link * BackupManager#DATASET_UNAVAILABLE}; in this case, the transport should be * reinitalized and the entire backup pass restarted. Any other nonzero value is a * fatal error requiring that this package's backup be aborted and rescheduled. */ boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd, int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd, boolean wipeAllFirst); /** Loading
core/java/com/android/internal/backup/LocalTransport.java +4 −4 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ public class LocalTransport extends IBackupTransport.Stub { return 0; } public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, boolean wipeAllFirst) throws RemoteException { if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName); Loading Loading @@ -99,7 +99,7 @@ public class LocalTransport extends IBackupTransport.Stub { entity.write(buf, 0, dataSize); } catch (IOException e) { Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); return false; return BackupConstants.TRANSPORT_ERROR; } finally { entity.close(); } Loading @@ -107,11 +107,11 @@ public class LocalTransport extends IBackupTransport.Stub { entityFile.delete(); } } return true; return BackupConstants.TRANSPORT_OK; } catch (IOException e) { // oops, something went wrong. abort the operation and return error. Log.v(TAG, "Exception reading backup input:", e); return false; return BackupConstants.TRANSPORT_ERROR; } } Loading
services/java/com/android/server/BackupManagerService.java +70 −6 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.backup.IRestoreObserver; import android.backup.IRestoreSession; import android.backup.RestoreSet; import com.android.internal.backup.BackupConstants; import com.android.internal.backup.LocalTransport; import com.android.internal.backup.IBackupTransport; Loading Loading @@ -101,6 +102,7 @@ class BackupManagerService extends IBackupManager.Stub { private static final int BACKUP_AGENT_FAILURE_EVENT = 2823; private static final int BACKUP_PACKAGE_EVENT = 2824; private static final int BACKUP_SUCCESS_EVENT = 2825; private static final int BACKUP_RESET_EVENT = 2826; private static final int RESTORE_START_EVENT = 2830; private static final int RESTORE_TRANSPORT_FAILURE_EVENT = 2831; Loading Loading @@ -406,6 +408,47 @@ class BackupManagerService extends IBackupManager.Stub { } } // Reset all of our bookkeeping, in response to having been told that // the backend data has been wiped [due to idle expiry, for example], // so we must re-upload all saved settings. void resetBackupState(File stateFileDir) { synchronized (mQueueLock) { // Wipe the "what we've ever backed up" tracking try { // close the ever-stored journal... if (mEverStoredStream != null) { mEverStoredStream.close(); } // ... so we can delete it and start over mEverStored.delete(); mEverStoredStream = new RandomAccessFile(mEverStored, "rwd"); } catch (IOException e) { Log.e(TAG, "Unable to open known-stored file!"); mEverStoredStream = null; } mEverStoredApps.clear(); // Remove all the state files for (File sf : stateFileDir.listFiles()) { sf.delete(); } // Enqueue a new backup of every participant int N = mBackupParticipants.size(); for (int i=0; i<N; i++) { int uid = mBackupParticipants.keyAt(i); HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i); for (ApplicationInfo app: participants) { try { dataChanged(app.packageName); } catch (RemoteException e) { // can't happen; we're in the same process } } } } } // Add a transport to our set of available backends private void registerTransport(String name, IBackupTransport transport) { synchronized (mTransports) { Loading Loading @@ -891,8 +934,22 @@ class BackupManagerService extends IBackupManager.Stub { // If we haven't stored anything yet, we need to do an init // operation along with recording the metadata blob. boolean needInit = (mEverStoredApps.size() == 0); processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), int result = processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport, needInit); if (result == BackupConstants.TRANSPORT_NOT_INITIALIZED) { // The backend reports that our dataset has been wiped. We need to // reset all of our bookkeeping and instead run a new backup pass for // everything. EventLog.writeEvent(BACKUP_RESET_EVENT, mTransport.transportDirName()); resetBackupState(mStateDir); backupNow(); return; } else if (result != BackupConstants.TRANSPORT_OK) { // Give up if we couldn't even process the metadata Log.e(TAG, "Meta backup err " + result); return; } // Now run all the backups in our queue int count = mQueue.size(); Loading Loading @@ -953,7 +1010,7 @@ class BackupManagerService extends IBackupManager.Stub { } } void processOneBackup(BackupRequest request, IBackupAgent agent, int processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport, boolean doInit) { final String packageName = request.appInfo.packageName; if (DEBUG) Log.d(TAG, "processOneBackup doBackup(" + doInit + ") on " + packageName); Loading Loading @@ -1007,7 +1064,7 @@ class BackupManagerService extends IBackupManager.Stub { EventLog.writeEvent(BACKUP_AGENT_FAILURE_EVENT, packageName, e.toString()); backupDataName.delete(); newStateName.delete(); return; return BackupConstants.TRANSPORT_ERROR; } finally { try { if (savedState != null) savedState.close(); } catch (IOException e) {} try { if (backupData != null) backupData.close(); } catch (IOException e) {} Loading @@ -1027,7 +1084,13 @@ class BackupManagerService extends IBackupManager.Stub { // hold off on finishBackup() until the end, which implies holding off on // renaming *all* the output state files (see below) until that happens. if (!transport.performBackup(packInfo, backupData, doInit) || int performOkay = transport.performBackup(packInfo, backupData, doInit); if (performOkay == BackupConstants.TRANSPORT_NOT_INITIALIZED) { Log.i(TAG, "Backend not initialized"); return performOkay; } if ((performOkay != 0) || !transport.finishBackup()) { throw new Exception("Backup transport failed"); } Loading @@ -1044,10 +1107,12 @@ class BackupManagerService extends IBackupManager.Stub { } catch (Exception e) { Log.e(TAG, "Transport error backing up " + packageName, e); EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName); return; return BackupConstants.TRANSPORT_ERROR; } finally { try { if (backupData != null) backupData.close(); } catch (IOException e) {} } return BackupConstants.TRANSPORT_OK; } } Loading Loading @@ -1590,7 +1655,6 @@ class BackupManagerService extends IBackupManager.Stub { if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass"); synchronized (mQueueLock) { try { if (DEBUG) Log.v(TAG, "sending immediate backup broadcast"); mRunBackupIntent.send(); } catch (PendingIntent.CanceledException e) { // should never happen Loading