Loading services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +135 −66 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.pm.SigningInfo; Loading @@ -32,7 +31,6 @@ import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Slog; import com.android.server.LocalServices; import com.android.server.backup.utils.BackupEligibilityRules; import java.io.BufferedInputStream; Loading @@ -49,16 +47,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; /** * We back up the signatures of each package so that during a system restore, * we can verify that the app whose data we think we have matches the app * actually resident on the device. * We back up the signatures of each package so that during a system restore, we can verify that the * app whose data we think we have matches the app actually resident on the device. * * Since the Package Manager isn't a proper "application" we just provide a * direct IBackupAgent implementation and hand-construct it at need. * <p>Since the Package Manager isn't a proper "application" we just provide a direct IBackupAgent * implementation and hand-construct it at need. */ public class PackageManagerBackupAgent extends BackupAgent { private static final String TAG = "PMBA"; Loading Loading @@ -134,8 +130,8 @@ public class PackageManagerBackupAgent extends BackupAgent { init(packageMgr, packages, userId); } public PackageManagerBackupAgent(PackageManager packageMgr, int userId, BackupEligibilityRules backupEligibilityRules) { public PackageManagerBackupAgent( PackageManager packageMgr, int userId, BackupEligibilityRules backupEligibilityRules) { init(packageMgr, null, userId); evaluateStorablePackages(backupEligibilityRules); Loading @@ -159,8 +155,8 @@ public class PackageManagerBackupAgent extends BackupAgent { } /** Gets all packages installed on user {@code userId} eligible for backup. */ public static List<PackageInfo> getStorableApplications(PackageManager pm, int userId, BackupEligibilityRules backupEligibilityRules) { public static List<PackageInfo> getStorableApplications( PackageManager pm, int userId, BackupEligibilityRules backupEligibilityRules) { List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(PackageManager.GET_SIGNING_CERTIFICATES, userId); int N = pkgs.size(); Loading Loading @@ -204,11 +200,13 @@ public class PackageManagerBackupAgent extends BackupAgent { return mRestoredSignatures.keySet(); } // The backed up data is the signature block for each app, keyed by the package name. public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { @Override public void onBackup( ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { if (DEBUG) Slog.v(TAG, "onBackup()"); // The backed up data is the signature block for each app, keyed by the package name. ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); // we'll reuse these DataOutputStream outputBufferStream = new DataOutputStream(outputBuffer); parseStateFile(oldState); Loading @@ -218,8 +216,13 @@ public class PackageManagerBackupAgent extends BackupAgent { // "already backed up" map built by parseStateFile(). if (mStoredIncrementalVersion == null || !mStoredIncrementalVersion.equals(Build.VERSION.INCREMENTAL)) { Slog.i(TAG, "Previous metadata " + mStoredIncrementalVersion + " mismatch vs " + Build.VERSION.INCREMENTAL + " - rewriting"); Slog.i( TAG, "Previous metadata " + mStoredIncrementalVersion + " mismatch vs " + Build.VERSION.INCREMENTAL + " - rewriting"); mExisting.clear(); } Loading Loading @@ -271,8 +274,9 @@ public class PackageManagerBackupAgent extends BackupAgent { } else { PackageInfo info = null; try { info = mPackageManager.getPackageInfoAsUser(packName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); info = mPackageManager.getPackageInfoAsUser( packName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); } catch (NameNotFoundException e) { // Weird; we just found it, and now are told it doesn't exist. // Treat it as having been removed from the device. Loading @@ -294,7 +298,10 @@ public class PackageManagerBackupAgent extends BackupAgent { SigningInfo signingInfo = info.signingInfo; if (signingInfo == null) { Slog.w(TAG, "Not backing up package " + packName Slog.w( TAG, "Not backing up package " + packName + " since it appears to have no signatures."); continue; } Loading @@ -317,13 +324,18 @@ public class PackageManagerBackupAgent extends BackupAgent { } // retrieve the newest sigs to back up Signature[] infoSignatures = signingInfo.getApkContentsSigners(); writeSignatureHashArray(outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); writeSignatureHashArray( outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); if (DEBUG) { Slog.v(TAG, "+ writing metadata for " + packName + " version=" + info.getLongVersionCode() + " entityLen=" + outputBuffer.size()); Slog.v( TAG, "+ writing metadata for " + packName + " version=" + info.getLongVersionCode() + " entityLen=" + outputBuffer.size()); } // Now we can write the backup entity for this package Loading Loading @@ -363,13 +375,15 @@ public class PackageManagerBackupAgent extends BackupAgent { data.writeEntityData(bytes, bytes.length); } // "Restore" here is a misnomer. What we're really doing is reading back the // set of app signatures associated with each backed-up app in this restore // image. We'll use those later to determine what we can legitimately restore. @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { if (DEBUG) Slog.v(TAG, "onRestore()"); // "Restore" here is a misnomer. What we're really doing is reading back the // set of app signatures associated with each backed-up app in this restore // image. We'll use those later to determine what we can legitimately restore. // we expect the ANCESTRAL_RECORD_KEY ("@ancestral_record@") to always come first in the // restore set - based on that value we use different mechanisms to consume the data; // if the ANCESTRAL_RECORD_KEY is missing in the restore set, it means that the data is Loading @@ -380,7 +394,9 @@ public class PackageManagerBackupAgent extends BackupAgent { RestoreDataConsumer consumer = getRestoreDataConsumer(ancestralRecordVersion); if (consumer == null) { Slog.w(TAG, "Ancestral restore set version is unknown" Slog.w( TAG, "Ancestral restore set version is unknown" + " to this Android version; not restoring"); return; } else { Loading Loading @@ -506,7 +522,10 @@ public class PackageManagerBackupAgent extends BackupAgent { if (pkg.equals(STATE_FILE_HEADER)) { int stateVersion = in.readInt(); if (stateVersion > STATE_FILE_VERSION) { Slog.w(TAG, "Unsupported state file version " + stateVersion Slog.w( TAG, "Unsupported state file version " + stateVersion + ", redoing from start"); return; } Loading Loading @@ -640,10 +659,17 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = inputBufferStream.readUTF(); mHasMetadata = true; if (DEBUG) { Slog.i(TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); Slog.i( TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); } } else if (key.equals(DEFAULT_HOME_KEY)) { String cn = inputBufferStream.readUTF(); Loading @@ -652,10 +678,16 @@ public class PackageManagerBackupAgent extends BackupAgent { mRestoredHomeInstaller = inputBufferStream.readUTF(); mRestoredHomeSigHashes = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); Slog.i( TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); } } else { // it's a file metadata record Loading @@ -668,13 +700,23 @@ public class PackageManagerBackupAgent extends BackupAgent { } ArrayList<byte[]> sigs = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); Slog.i( TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); } if (sigs == null || sigs.size() == 0) { Slog.w(TAG, "Not restoring package " + key Slog.w( TAG, "Not restoring package " + key + " since it appears to have no signatures."); continue; } Loading @@ -687,8 +729,12 @@ public class PackageManagerBackupAgent extends BackupAgent { boolean readNextHeader = data.readNextHeader(); if (!readNextHeader) { if (DEBUG) Slog.v(TAG, "LegacyRestoreDataConsumer:" if (DEBUG) { Slog.v( TAG, "LegacyRestoreDataConsumer:" + " we're done reading all the headers"); } break; } } Loading Loading @@ -725,10 +771,17 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = inputBufferStream.readUTF(); mHasMetadata = true; if (DEBUG) { Slog.i(TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); Slog.i( TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); } } else if (key.equals(DEFAULT_HOME_KEY)) { // Default home app data is no longer backed up by this agent. This code is Loading @@ -739,10 +792,16 @@ public class PackageManagerBackupAgent extends BackupAgent { mRestoredHomeInstaller = inputBufferStream.readUTF(); mRestoredHomeSigHashes = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); Slog.i( TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); } } else { // it's a file metadata record Loading @@ -755,13 +814,23 @@ public class PackageManagerBackupAgent extends BackupAgent { } ArrayList<byte[]> sigs = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); Slog.i( TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); } if (sigs == null || sigs.size() == 0) { Slog.w(TAG, "Not restoring package " + key Slog.w( TAG, "Not restoring package " + key + " since it appears to have no signatures."); continue; } Loading Loading
services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +135 −66 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.pm.SigningInfo; Loading @@ -32,7 +31,6 @@ import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Slog; import com.android.server.LocalServices; import com.android.server.backup.utils.BackupEligibilityRules; import java.io.BufferedInputStream; Loading @@ -49,16 +47,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; /** * We back up the signatures of each package so that during a system restore, * we can verify that the app whose data we think we have matches the app * actually resident on the device. * We back up the signatures of each package so that during a system restore, we can verify that the * app whose data we think we have matches the app actually resident on the device. * * Since the Package Manager isn't a proper "application" we just provide a * direct IBackupAgent implementation and hand-construct it at need. * <p>Since the Package Manager isn't a proper "application" we just provide a direct IBackupAgent * implementation and hand-construct it at need. */ public class PackageManagerBackupAgent extends BackupAgent { private static final String TAG = "PMBA"; Loading Loading @@ -134,8 +130,8 @@ public class PackageManagerBackupAgent extends BackupAgent { init(packageMgr, packages, userId); } public PackageManagerBackupAgent(PackageManager packageMgr, int userId, BackupEligibilityRules backupEligibilityRules) { public PackageManagerBackupAgent( PackageManager packageMgr, int userId, BackupEligibilityRules backupEligibilityRules) { init(packageMgr, null, userId); evaluateStorablePackages(backupEligibilityRules); Loading @@ -159,8 +155,8 @@ public class PackageManagerBackupAgent extends BackupAgent { } /** Gets all packages installed on user {@code userId} eligible for backup. */ public static List<PackageInfo> getStorableApplications(PackageManager pm, int userId, BackupEligibilityRules backupEligibilityRules) { public static List<PackageInfo> getStorableApplications( PackageManager pm, int userId, BackupEligibilityRules backupEligibilityRules) { List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(PackageManager.GET_SIGNING_CERTIFICATES, userId); int N = pkgs.size(); Loading Loading @@ -204,11 +200,13 @@ public class PackageManagerBackupAgent extends BackupAgent { return mRestoredSignatures.keySet(); } // The backed up data is the signature block for each app, keyed by the package name. public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { @Override public void onBackup( ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { if (DEBUG) Slog.v(TAG, "onBackup()"); // The backed up data is the signature block for each app, keyed by the package name. ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); // we'll reuse these DataOutputStream outputBufferStream = new DataOutputStream(outputBuffer); parseStateFile(oldState); Loading @@ -218,8 +216,13 @@ public class PackageManagerBackupAgent extends BackupAgent { // "already backed up" map built by parseStateFile(). if (mStoredIncrementalVersion == null || !mStoredIncrementalVersion.equals(Build.VERSION.INCREMENTAL)) { Slog.i(TAG, "Previous metadata " + mStoredIncrementalVersion + " mismatch vs " + Build.VERSION.INCREMENTAL + " - rewriting"); Slog.i( TAG, "Previous metadata " + mStoredIncrementalVersion + " mismatch vs " + Build.VERSION.INCREMENTAL + " - rewriting"); mExisting.clear(); } Loading Loading @@ -271,8 +274,9 @@ public class PackageManagerBackupAgent extends BackupAgent { } else { PackageInfo info = null; try { info = mPackageManager.getPackageInfoAsUser(packName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); info = mPackageManager.getPackageInfoAsUser( packName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); } catch (NameNotFoundException e) { // Weird; we just found it, and now are told it doesn't exist. // Treat it as having been removed from the device. Loading @@ -294,7 +298,10 @@ public class PackageManagerBackupAgent extends BackupAgent { SigningInfo signingInfo = info.signingInfo; if (signingInfo == null) { Slog.w(TAG, "Not backing up package " + packName Slog.w( TAG, "Not backing up package " + packName + " since it appears to have no signatures."); continue; } Loading @@ -317,13 +324,18 @@ public class PackageManagerBackupAgent extends BackupAgent { } // retrieve the newest sigs to back up Signature[] infoSignatures = signingInfo.getApkContentsSigners(); writeSignatureHashArray(outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); writeSignatureHashArray( outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); if (DEBUG) { Slog.v(TAG, "+ writing metadata for " + packName + " version=" + info.getLongVersionCode() + " entityLen=" + outputBuffer.size()); Slog.v( TAG, "+ writing metadata for " + packName + " version=" + info.getLongVersionCode() + " entityLen=" + outputBuffer.size()); } // Now we can write the backup entity for this package Loading Loading @@ -363,13 +375,15 @@ public class PackageManagerBackupAgent extends BackupAgent { data.writeEntityData(bytes, bytes.length); } // "Restore" here is a misnomer. What we're really doing is reading back the // set of app signatures associated with each backed-up app in this restore // image. We'll use those later to determine what we can legitimately restore. @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { if (DEBUG) Slog.v(TAG, "onRestore()"); // "Restore" here is a misnomer. What we're really doing is reading back the // set of app signatures associated with each backed-up app in this restore // image. We'll use those later to determine what we can legitimately restore. // we expect the ANCESTRAL_RECORD_KEY ("@ancestral_record@") to always come first in the // restore set - based on that value we use different mechanisms to consume the data; // if the ANCESTRAL_RECORD_KEY is missing in the restore set, it means that the data is Loading @@ -380,7 +394,9 @@ public class PackageManagerBackupAgent extends BackupAgent { RestoreDataConsumer consumer = getRestoreDataConsumer(ancestralRecordVersion); if (consumer == null) { Slog.w(TAG, "Ancestral restore set version is unknown" Slog.w( TAG, "Ancestral restore set version is unknown" + " to this Android version; not restoring"); return; } else { Loading Loading @@ -506,7 +522,10 @@ public class PackageManagerBackupAgent extends BackupAgent { if (pkg.equals(STATE_FILE_HEADER)) { int stateVersion = in.readInt(); if (stateVersion > STATE_FILE_VERSION) { Slog.w(TAG, "Unsupported state file version " + stateVersion Slog.w( TAG, "Unsupported state file version " + stateVersion + ", redoing from start"); return; } Loading Loading @@ -640,10 +659,17 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = inputBufferStream.readUTF(); mHasMetadata = true; if (DEBUG) { Slog.i(TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); Slog.i( TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); } } else if (key.equals(DEFAULT_HOME_KEY)) { String cn = inputBufferStream.readUTF(); Loading @@ -652,10 +678,16 @@ public class PackageManagerBackupAgent extends BackupAgent { mRestoredHomeInstaller = inputBufferStream.readUTF(); mRestoredHomeSigHashes = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); Slog.i( TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); } } else { // it's a file metadata record Loading @@ -668,13 +700,23 @@ public class PackageManagerBackupAgent extends BackupAgent { } ArrayList<byte[]> sigs = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); Slog.i( TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); } if (sigs == null || sigs.size() == 0) { Slog.w(TAG, "Not restoring package " + key Slog.w( TAG, "Not restoring package " + key + " since it appears to have no signatures."); continue; } Loading @@ -687,8 +729,12 @@ public class PackageManagerBackupAgent extends BackupAgent { boolean readNextHeader = data.readNextHeader(); if (!readNextHeader) { if (DEBUG) Slog.v(TAG, "LegacyRestoreDataConsumer:" if (DEBUG) { Slog.v( TAG, "LegacyRestoreDataConsumer:" + " we're done reading all the headers"); } break; } } Loading Loading @@ -725,10 +771,17 @@ public class PackageManagerBackupAgent extends BackupAgent { mStoredIncrementalVersion = inputBufferStream.readUTF(); mHasMetadata = true; if (DEBUG) { Slog.i(TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); Slog.i( TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")"); } } else if (key.equals(DEFAULT_HOME_KEY)) { // Default home app data is no longer backed up by this agent. This code is Loading @@ -739,10 +792,16 @@ public class PackageManagerBackupAgent extends BackupAgent { mRestoredHomeInstaller = inputBufferStream.readUTF(); mRestoredHomeSigHashes = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); Slog.i( TAG, " read preferred home app " + mRestoredHome + " version=" + mRestoredHomeVersion + " installer=" + mRestoredHomeInstaller + " sig=" + mRestoredHomeSigHashes); } } else { // it's a file metadata record Loading @@ -755,13 +814,23 @@ public class PackageManagerBackupAgent extends BackupAgent { } ArrayList<byte[]> sigs = readSignatureHashArray(inputBufferStream); if (DEBUG) { Slog.i(TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); Slog.i( TAG, " read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs); } if (sigs == null || sigs.size() == 0) { Slog.w(TAG, "Not restoring package " + key Slog.w( TAG, "Not restoring package " + key + " since it appears to have no signatures."); continue; } Loading