Loading services/backup/java/com/android/server/backup/BackupManagerService.java +70 −91 Original line number Diff line number Diff line Loading @@ -6558,52 +6558,35 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF private void startRestore() { sendStartRestore(mAcceptSet.size()); UnifiedRestoreState nextState = UnifiedRestoreState.RESTORE_FINISHED; try { // If we don't yet have PM metadata for this token, synthesize an // entry for the PM pseudopackage and make it the first to be // restored. String transportDir = mTransport.transportDirName(); mStateDir = new File(mBaseStateDir, transportDir); File metadataDir = new File(mStateDir, "_metadata"); metadataDir.mkdirs(); File metadataFile = new File(metadataDir, Long.toHexString(mToken)); try { // PM info is cached in $BASE/transport/_metadata/$TOKEN mPmAgent = new PackageManagerBackupAgent(metadataFile); } catch (IOException e) { // Nope, we need to get it via restore if (MORE_DEBUG) Slog.v(TAG, "Need to restore @pm@"); // Fetch the current metadata from the dataset first PackageInfo pmPackage = new PackageInfo(); pmPackage.packageName = PACKAGE_MANAGER_SENTINEL; mAcceptSet.add(0, pmPackage); } PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]); mStatus = mTransport.startRestore(mToken, packages); if (mStatus != BackupTransport.TRANSPORT_OK) { Slog.e(TAG, "Transport error " + mStatus + "; no restore possible"); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } if (mPmAgent == null) { if (DEBUG) { Slog.v(TAG, "Need to fetch metadata for token " + Long.toHexString(mToken)); } RestoreDescription desc = mTransport.nextRestorePackage(); if (desc == null) { Slog.e(TAG, "No restore metadata available; halting"); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } if (!PACKAGE_MANAGER_SENTINEL.equals(desc.getPackageName())) { Slog.e(TAG, "Required metadata but got " + desc.getPackageName()); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } Loading @@ -6617,58 +6600,35 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } initiateOneRestore(mCurrentPackage, 0); // The PM agent called operationComplete() already, because our invocation // of it is process-local and therefore synchronous. That means that a // RUNNING_QUEUE message is already enqueued. Only if we're unable to // proceed with running the queue do we remove that pending message and // jump straight to the FINAL state. // of it is process-local and therefore synchronous. That means that the // next-state message (RUNNING_QUEUE) is already enqueued. Only if we're // unable to proceed with running the queue do we remove that pending // message and jump straight to the FINAL state. // Verify that the backup set includes metadata. If not, we can't do // signature/version verification etc, so we simply do not proceed with // the restore operation. if (!mPmAgent.hasMetadata()) { Slog.e(TAG, "No restore metadata available, so not restoring settings"); Slog.e(TAG, "No restore metadata available, so not restoring"); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, PACKAGE_MANAGER_SENTINEL, "Package manager restore metadata missing"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } // Success; cache the metadata and continue as expected with the // RUNNING_QUEUE step already enqueued. if (DEBUG) { Slog.v(TAG, "Got metadata; caching and proceeding to restore"); } try { mPmAgent.saveToDisk(metadataFile); } catch (IOException e) { // Something bad; we need to abort Slog.e(TAG, "Unable to write restored metadata"); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, PACKAGE_MANAGER_SENTINEL, "Unable to write restored metadata"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; return; } } else { // We have the PMBA already, so we can proceed directly to // the RUNNING_QUEUE state ourselves. if (MORE_DEBUG) Slog.v(TAG, "PMBA from cache; proceeding to run queue"); nextState = UnifiedRestoreState.RUNNING_QUEUE; } // next state already enqueued } catch (RemoteException e) { // If we lost the transport at any time, halt Slog.e(TAG, "Unable to contact transport for restore"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } finally { executeNextState(nextState); } } Loading Loading @@ -7267,6 +7227,13 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF final UnifiedRestoreState nextState; switch (mState) { case INITIAL: // We've just (manually) restored the PMBA. It doesn't need the // additional restore-finished callback so we bypass that and go // directly to running the queue. nextState = UnifiedRestoreState.RUNNING_QUEUE; break; case RESTORE_KEYVALUE: case RESTORE_FULL: { // Okay, we've just heard back from the agent that it's done with Loading Loading @@ -8187,6 +8154,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF pkg.packageName = packageName; mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "Restore at install of " + packageName); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(transport, dirName, null, restoreSet, pkg, token); Loading Loading @@ -8368,6 +8338,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF if (token == mRestoreSets[i].token) { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restoreAll() kicking off"); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token); Loading Loading @@ -8439,6 +8412,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF if (token == mRestoreSets[i].token) { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restoreSome() of " + packages.length + " packages"); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, packages, packages.length > 1); Loading Loading @@ -8518,6 +8494,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Ready to go: enqueue the restore request and claim success long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restorePackage() : " + packageName); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, app, 0); Loading services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +0 −91 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; Loading @@ -48,9 +47,6 @@ import java.util.List; import java.util.Set; import java.util.Objects; import java.util.Map.Entry; import libcore.io.IoUtils; /** * We back up the signatures of each package so that during a system restore, Loading Loading @@ -132,93 +128,6 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = Build.VERSION.INCREMENTAL; } /** * Reconstitute a PMBA from its on-disk format. This is used for persistence * of the ancestral dataset's metadata. See {@link #saveToDisk()} for * details of the file format. */ PackageManagerBackupAgent(File cache) throws IOException { FileInputStream fin = new FileInputStream(cache); BufferedInputStream bin = new BufferedInputStream(fin, 32 * 1024); DataInputStream in = new DataInputStream(bin); int version = in.readInt(); // We can currently only handle the initial version format if (version == ANCESTRAL_RECORD_VERSION) { mStoredSdkVersion = in.readInt(); mStoredIncrementalVersion = in.readUTF(); int nPackages = in.readInt(); if (nPackages > 0) { HashMap<String, Metadata> restoredMetadata = new HashMap<String, Metadata>(nPackages); ArrayList<byte[]> hashes = null; for (int pack = 0; pack < nPackages; pack++) { final String name = in.readUTF(); final int versionCode = in.readInt(); final int nHashes = in.readInt(); if (nHashes > 0) { hashes = new ArrayList<byte[]>(nHashes); for (int i = 0; i < nHashes; i++) { int len = in.readInt(); byte[] hash = new byte[len]; in.read(hash); hashes.add(hash); } } restoredMetadata.put(name, new Metadata(versionCode, hashes)); } mRestoredSignatures = restoredMetadata; } } } public void saveToDisk(File cache) throws IOException { // On disk format is very similar to the key/value format: // // Int: disk format version, currently 1 // Int: VERSION.SDK_INT of source device // UTF: VERSION.INCREMENTAL string, for reference // // Int: number of packages represented in this file // // Per package if number > 0: // UTF: package name // Int: versionCode of the package // Int: number of signature hash blocks for this package // Per signature hash block: // Int: size of block // byte[]: block itself if size of block > 0 FileOutputStream of = new FileOutputStream(cache); BufferedOutputStream bout = new BufferedOutputStream(of, 32*1024); DataOutputStream out = new DataOutputStream(bout); out.writeInt(ANCESTRAL_RECORD_VERSION); out.writeInt(mStoredSdkVersion); out.writeUTF(mStoredIncrementalVersion); out.writeInt(mRestoredSignatures.size()); if (mRestoredSignatures.size() > 0) { Set<Entry<String, Metadata>> entries = mRestoredSignatures.entrySet(); for (Entry<String, Metadata> i : entries) { final Metadata m = i.getValue(); final int nHashes = (m.sigHashes != null) ? m.sigHashes.size() : 0; out.writeUTF(i.getKey()); out.writeInt(m.versionCode); out.writeInt(nHashes); for (int h = 0; h < nHashes; h++) { byte[] hash = m.sigHashes.get(h); out.writeInt(hash.length); if (hash.length > 0) { out.write(hash); } } } } out.flush(); IoUtils.closeQuietly(out); } // We will need to refresh our understanding of what is eligible for // backup periodically; this entry point serves that purpose. public void evaluateStorablePackages() { Loading Loading
services/backup/java/com/android/server/backup/BackupManagerService.java +70 −91 Original line number Diff line number Diff line Loading @@ -6558,52 +6558,35 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF private void startRestore() { sendStartRestore(mAcceptSet.size()); UnifiedRestoreState nextState = UnifiedRestoreState.RESTORE_FINISHED; try { // If we don't yet have PM metadata for this token, synthesize an // entry for the PM pseudopackage and make it the first to be // restored. String transportDir = mTransport.transportDirName(); mStateDir = new File(mBaseStateDir, transportDir); File metadataDir = new File(mStateDir, "_metadata"); metadataDir.mkdirs(); File metadataFile = new File(metadataDir, Long.toHexString(mToken)); try { // PM info is cached in $BASE/transport/_metadata/$TOKEN mPmAgent = new PackageManagerBackupAgent(metadataFile); } catch (IOException e) { // Nope, we need to get it via restore if (MORE_DEBUG) Slog.v(TAG, "Need to restore @pm@"); // Fetch the current metadata from the dataset first PackageInfo pmPackage = new PackageInfo(); pmPackage.packageName = PACKAGE_MANAGER_SENTINEL; mAcceptSet.add(0, pmPackage); } PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]); mStatus = mTransport.startRestore(mToken, packages); if (mStatus != BackupTransport.TRANSPORT_OK) { Slog.e(TAG, "Transport error " + mStatus + "; no restore possible"); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } if (mPmAgent == null) { if (DEBUG) { Slog.v(TAG, "Need to fetch metadata for token " + Long.toHexString(mToken)); } RestoreDescription desc = mTransport.nextRestorePackage(); if (desc == null) { Slog.e(TAG, "No restore metadata available; halting"); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } if (!PACKAGE_MANAGER_SENTINEL.equals(desc.getPackageName())) { Slog.e(TAG, "Required metadata but got " + desc.getPackageName()); mStatus = BackupTransport.TRANSPORT_ERROR; nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } Loading @@ -6617,58 +6600,35 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } initiateOneRestore(mCurrentPackage, 0); // The PM agent called operationComplete() already, because our invocation // of it is process-local and therefore synchronous. That means that a // RUNNING_QUEUE message is already enqueued. Only if we're unable to // proceed with running the queue do we remove that pending message and // jump straight to the FINAL state. // of it is process-local and therefore synchronous. That means that the // next-state message (RUNNING_QUEUE) is already enqueued. Only if we're // unable to proceed with running the queue do we remove that pending // message and jump straight to the FINAL state. // Verify that the backup set includes metadata. If not, we can't do // signature/version verification etc, so we simply do not proceed with // the restore operation. if (!mPmAgent.hasMetadata()) { Slog.e(TAG, "No restore metadata available, so not restoring settings"); Slog.e(TAG, "No restore metadata available, so not restoring"); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, PACKAGE_MANAGER_SENTINEL, "Package manager restore metadata missing"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } // Success; cache the metadata and continue as expected with the // RUNNING_QUEUE step already enqueued. if (DEBUG) { Slog.v(TAG, "Got metadata; caching and proceeding to restore"); } try { mPmAgent.saveToDisk(metadataFile); } catch (IOException e) { // Something bad; we need to abort Slog.e(TAG, "Unable to write restored metadata"); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, PACKAGE_MANAGER_SENTINEL, "Unable to write restored metadata"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; return; } } else { // We have the PMBA already, so we can proceed directly to // the RUNNING_QUEUE state ourselves. if (MORE_DEBUG) Slog.v(TAG, "PMBA from cache; proceeding to run queue"); nextState = UnifiedRestoreState.RUNNING_QUEUE; } // next state already enqueued } catch (RemoteException e) { // If we lost the transport at any time, halt Slog.e(TAG, "Unable to contact transport for restore"); mStatus = BackupTransport.TRANSPORT_ERROR; mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this); nextState = UnifiedRestoreState.FINAL; executeNextState(UnifiedRestoreState.FINAL); return; } finally { executeNextState(nextState); } } Loading Loading @@ -7267,6 +7227,13 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF final UnifiedRestoreState nextState; switch (mState) { case INITIAL: // We've just (manually) restored the PMBA. It doesn't need the // additional restore-finished callback so we bypass that and go // directly to running the queue. nextState = UnifiedRestoreState.RUNNING_QUEUE; break; case RESTORE_KEYVALUE: case RESTORE_FULL: { // Okay, we've just heard back from the agent that it's done with Loading Loading @@ -8187,6 +8154,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF pkg.packageName = packageName; mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "Restore at install of " + packageName); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(transport, dirName, null, restoreSet, pkg, token); Loading Loading @@ -8368,6 +8338,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF if (token == mRestoreSets[i].token) { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restoreAll() kicking off"); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token); Loading Loading @@ -8439,6 +8412,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF if (token == mRestoreSets[i].token) { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restoreSome() of " + packages.length + " packages"); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, packages, packages.length > 1); Loading Loading @@ -8518,6 +8494,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Ready to go: enqueue the restore request and claim success long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); if (MORE_DEBUG) { Slog.d(TAG, "restorePackage() : " + packageName); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, app, 0); Loading
services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +0 −91 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; Loading @@ -48,9 +47,6 @@ import java.util.List; import java.util.Set; import java.util.Objects; import java.util.Map.Entry; import libcore.io.IoUtils; /** * We back up the signatures of each package so that during a system restore, Loading Loading @@ -132,93 +128,6 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = Build.VERSION.INCREMENTAL; } /** * Reconstitute a PMBA from its on-disk format. This is used for persistence * of the ancestral dataset's metadata. See {@link #saveToDisk()} for * details of the file format. */ PackageManagerBackupAgent(File cache) throws IOException { FileInputStream fin = new FileInputStream(cache); BufferedInputStream bin = new BufferedInputStream(fin, 32 * 1024); DataInputStream in = new DataInputStream(bin); int version = in.readInt(); // We can currently only handle the initial version format if (version == ANCESTRAL_RECORD_VERSION) { mStoredSdkVersion = in.readInt(); mStoredIncrementalVersion = in.readUTF(); int nPackages = in.readInt(); if (nPackages > 0) { HashMap<String, Metadata> restoredMetadata = new HashMap<String, Metadata>(nPackages); ArrayList<byte[]> hashes = null; for (int pack = 0; pack < nPackages; pack++) { final String name = in.readUTF(); final int versionCode = in.readInt(); final int nHashes = in.readInt(); if (nHashes > 0) { hashes = new ArrayList<byte[]>(nHashes); for (int i = 0; i < nHashes; i++) { int len = in.readInt(); byte[] hash = new byte[len]; in.read(hash); hashes.add(hash); } } restoredMetadata.put(name, new Metadata(versionCode, hashes)); } mRestoredSignatures = restoredMetadata; } } } public void saveToDisk(File cache) throws IOException { // On disk format is very similar to the key/value format: // // Int: disk format version, currently 1 // Int: VERSION.SDK_INT of source device // UTF: VERSION.INCREMENTAL string, for reference // // Int: number of packages represented in this file // // Per package if number > 0: // UTF: package name // Int: versionCode of the package // Int: number of signature hash blocks for this package // Per signature hash block: // Int: size of block // byte[]: block itself if size of block > 0 FileOutputStream of = new FileOutputStream(cache); BufferedOutputStream bout = new BufferedOutputStream(of, 32*1024); DataOutputStream out = new DataOutputStream(bout); out.writeInt(ANCESTRAL_RECORD_VERSION); out.writeInt(mStoredSdkVersion); out.writeUTF(mStoredIncrementalVersion); out.writeInt(mRestoredSignatures.size()); if (mRestoredSignatures.size() > 0) { Set<Entry<String, Metadata>> entries = mRestoredSignatures.entrySet(); for (Entry<String, Metadata> i : entries) { final Metadata m = i.getValue(); final int nHashes = (m.sigHashes != null) ? m.sigHashes.size() : 0; out.writeUTF(i.getKey()); out.writeInt(m.versionCode); out.writeInt(nHashes); for (int h = 0; h < nHashes; h++) { byte[] hash = m.sigHashes.get(h); out.writeInt(hash.length); if (hash.length > 0) { out.write(hash); } } } } out.flush(); IoUtils.closeQuietly(out); } // We will need to refresh our understanding of what is eligible for // backup periodically; this entry point serves that purpose. public void evaluateStorablePackages() { Loading