diff options
3 files changed, 57 insertions, 37 deletions
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl index ec63528..4bef265 100644 --- a/core/java/com/android/internal/backup/IBackupTransport.aidl +++ b/core/java/com/android/internal/backup/IBackupTransport.aidl @@ -41,6 +41,20 @@ interface IBackupTransport { - adb: close the file */ /** + * Ask the transport where, on local device storage, to keep backup state blobs. + * This is per-transport so that mock transports used for testing can coexist with + * "live" backup services without interfering with the live bookkeeping. The + * returned string should be a name that is expected to be unambiguous among all + * available backup transports; the name of the class implementing the transport + * is a good choice. + * + * @return A unique name, suitable for use as a file or directory name, that the + * Backup Manager could use to disambiguate state files associated with + * different backup transports. + */ + String transportDirName(); + + /** * Verify that this is a suitable time for a backup pass. This should return zero * if a backup is reasonable right now, some positive value otherwise. This method * will be called outside of the {@link #startSession}/{@link #endSession} pair. diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java index 0fbbb3f..c5d9d40 100644 --- a/core/java/com/android/internal/backup/LocalTransport.java +++ b/core/java/com/android/internal/backup/LocalTransport.java @@ -30,6 +30,9 @@ public class LocalTransport extends IBackupTransport.Stub { private static final String TAG = "LocalTransport"; private static final boolean DEBUG = true; + private static final String TRANSPORT_DIR_NAME + = "com.android.internal.backup.LocalTransport"; + private Context mContext; private PackageManager mPackageManager; private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup"); @@ -43,6 +46,11 @@ public class LocalTransport extends IBackupTransport.Stub { mPackageManager = context.getPackageManager(); } + + public String transportDirName() throws RemoteException { + return TRANSPORT_DIR_NAME; + } + public long requestBackupTime() throws RemoteException { // any time is a good time for local backup return 0; diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index a6639de..e131c6e 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -109,8 +109,8 @@ class BackupManagerService extends IBackupManager.Stub { // Backups that we haven't started yet. private HashMap<ApplicationInfo,BackupRequest> mPendingBackups = new HashMap<ApplicationInfo,BackupRequest>(); - // Do we need to back up the package manager metadata on the next pass? - private boolean mDoPackageManager; + + // Pseudoname that we use for the Package Manager metadata "package" private static final String PACKAGE_MANAGER_SENTINEL = "@pm@"; // locking around the pending-backup management @@ -133,7 +133,8 @@ class BackupManagerService extends IBackupManager.Stub { private IBackupTransport mLocalTransport, mGoogleTransport; private RestoreSession mActiveRestoreSession; - private File mStateDir; + // Where we keep our journal files and other bookkeeping + private File mBaseStateDir; private File mDataDir; private File mJournalDir; private File mJournal; @@ -145,13 +146,12 @@ class BackupManagerService extends IBackupManager.Stub { mActivityManager = ActivityManagerNative.getDefault(); // Set up our bookkeeping - mStateDir = new File(Environment.getDataDirectory(), "backup"); - mStateDir.mkdirs(); + mBaseStateDir = new File(Environment.getDataDirectory(), "backup"); mDataDir = Environment.getDownloadCacheDirectory(); // Set up the backup-request journaling - mJournalDir = new File(mStateDir, "pending"); - mJournalDir.mkdirs(); + mJournalDir = new File(mBaseStateDir, "pending"); + mJournalDir.mkdirs(); // creates mBaseStateDir along the way makeJournalLocked(); // okay because no other threads are running yet // Build our mapping of uid to backup client services. This implicitly @@ -372,7 +372,6 @@ class BackupManagerService extends IBackupManager.Stub { mBackupParticipants.put(uid, set); } set.add(pkg.applicationInfo); - backUpPackageManagerData(); } } } @@ -416,7 +415,6 @@ class BackupManagerService extends IBackupManager.Stub { for (ApplicationInfo entry: set) { if (entry.packageName.equals(pkg.packageName)) { set.remove(entry); - backUpPackageManagerData(); break; } } @@ -459,14 +457,6 @@ class BackupManagerService extends IBackupManager.Stub { addPackageParticipantsLockedInner(packageName, allApps); } - private void backUpPackageManagerData() { - // No need to schedule a backup just for the metadata; just piggyback on - // the next actual data backup. - synchronized(this) { - mDoPackageManager = true; - } - } - // The queue lock should be held when scheduling a backup pass private void scheduleBackupPassLocked(long timeFromNowMillis) { mBackupHandler.removeMessages(MSG_RUN_BACKUP); @@ -564,6 +554,7 @@ class BackupManagerService extends IBackupManager.Stub { private static final String TAG = "PerformBackupThread"; IBackupTransport mTransport; ArrayList<BackupRequest> mQueue; + File mStateDir; File mJournal; public PerformBackupThread(IBackupTransport transport, ArrayList<BackupRequest> queue, @@ -571,32 +562,31 @@ class BackupManagerService extends IBackupManager.Stub { mTransport = transport; mQueue = queue; mJournal = journal; + + try { + mStateDir = new File(mBaseStateDir, transport.transportDirName()); + } catch (RemoteException e) { + // can't happen; the transport is local + } + mStateDir.mkdirs(); } @Override public void run() { if (DEBUG) Log.v(TAG, "Beginning backup of " + mQueue.size() + " targets"); - // First, back up the package manager metadata if necessary - boolean doPackageManager; - synchronized (BackupManagerService.this) { - doPackageManager = mDoPackageManager; - mDoPackageManager = false; - } - if (doPackageManager) { - // The package manager doesn't have a proper <application> etc, but since - // it's running here in the system process we can just set up its agent - // directly and use a synthetic BackupRequest. - if (DEBUG) Log.i(TAG, "Running PM backup pass as well"); - - PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent( - mPackageManager, allAgentPackages()); - BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false); - pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL; - processOneBackup(pmRequest, - IBackupAgent.Stub.asInterface(pmAgent.onBind()), - mTransport); - } + // The package manager doesn't have a proper <application> etc, but since + // it's running here in the system process we can just set up its agent + // directly and use a synthetic BackupRequest. We always run this pass + // because it's cheap and this way we guarantee that we don't get out of + // step even if we're selecting among various transports at run time. + PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent( + mPackageManager, allAgentPackages()); + BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false); + pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL; + processOneBackup(pmRequest, + IBackupAgent.Stub.asInterface(pmAgent.onBind()), + mTransport); // Now run all the backups in our queue doQueuedBackups(mTransport); @@ -760,6 +750,7 @@ class BackupManagerService extends IBackupManager.Stub { private IBackupTransport mTransport; private int mToken; private RestoreSet mImage; + private File mStateDir; class RestoreRequest { public PackageInfo app; @@ -774,6 +765,13 @@ class BackupManagerService extends IBackupManager.Stub { PerformRestoreThread(IBackupTransport transport, int restoreSetToken) { mTransport = transport; mToken = restoreSetToken; + + try { + mStateDir = new File(mBaseStateDir, transport.transportDirName()); + } catch (RemoteException e) { + // can't happen; the transport is local + } + mStateDir.mkdirs(); } @Override |