Loading core/java/com/android/internal/backup/IBackupTransport.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,20 @@ interface IBackupTransport { - cloud: tear down connection etc - 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 Loading core/java/com/android/internal/backup/LocalTransport.java +8 −0 Original line number Diff line number Diff line Loading @@ -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"); Loading @@ -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; Loading services/java/com/android/server/BackupManagerService.java +35 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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 Loading Loading @@ -372,7 +372,6 @@ class BackupManagerService extends IBackupManager.Stub { mBackupParticipants.put(uid, set); } set.add(pkg.applicationInfo); backUpPackageManagerData(); } } } Loading Loading @@ -416,7 +415,6 @@ class BackupManagerService extends IBackupManager.Stub { for (ApplicationInfo entry: set) { if (entry.packageName.equals(pkg.packageName)) { set.remove(entry); backUpPackageManagerData(); break; } } Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -571,24 +562,24 @@ 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"); // 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); Loading @@ -596,7 +587,6 @@ class BackupManagerService extends IBackupManager.Stub { processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport); } // Now run all the backups in our queue doQueuedBackups(mTransport); Loading Loading @@ -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; Loading @@ -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 Loading Loading
core/java/com/android/internal/backup/IBackupTransport.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,20 @@ interface IBackupTransport { - cloud: tear down connection etc - 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 Loading
core/java/com/android/internal/backup/LocalTransport.java +8 −0 Original line number Diff line number Diff line Loading @@ -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"); Loading @@ -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; Loading
services/java/com/android/server/BackupManagerService.java +35 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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 Loading Loading @@ -372,7 +372,6 @@ class BackupManagerService extends IBackupManager.Stub { mBackupParticipants.put(uid, set); } set.add(pkg.applicationInfo); backUpPackageManagerData(); } } } Loading Loading @@ -416,7 +415,6 @@ class BackupManagerService extends IBackupManager.Stub { for (ApplicationInfo entry: set) { if (entry.packageName.equals(pkg.packageName)) { set.remove(entry); backUpPackageManagerData(); break; } } Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -571,24 +562,24 @@ 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"); // 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); Loading @@ -596,7 +587,6 @@ class BackupManagerService extends IBackupManager.Stub { processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport); } // Now run all the backups in our queue doQueuedBackups(mTransport); Loading Loading @@ -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; Loading @@ -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 Loading