Loading core/java/android/backup/RestoreSet.java +5 −5 Original line number Diff line number Diff line Loading @@ -43,14 +43,14 @@ public class RestoreSet implements Parcelable { * transport. This is guaranteed to be valid for the duration of a restore * session, but is meaningless once the session has ended. */ public int token; public long token; public RestoreSet() { // Leave everything zero / null } public RestoreSet(String _name, String _dev, int _token) { public RestoreSet(String _name, String _dev, long _token) { name = _name; device = _dev; token = _token; Loading @@ -65,7 +65,7 @@ public class RestoreSet implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeString(name); out.writeString(device); out.writeInt(token); out.writeLong(token); } public static final Parcelable.Creator<RestoreSet> CREATOR Loading @@ -82,6 +82,6 @@ public class RestoreSet implements Parcelable { private RestoreSet(Parcel in) { name = in.readString(); device = in.readString(); token = in.readInt(); token = in.readLong(); } } core/java/com/android/internal/backup/IBackupTransport.aidl +42 −35 Original line number Diff line number Diff line Loading @@ -54,63 +54,70 @@ interface IBackupTransport { long requestBackupTime(); /** * Establish a connection to the back-end data repository, if necessary. If the transport * needs to initialize state that is not tied to individual applications' backup operations, * this is where it should be done. * * @return Zero on success; a nonzero error code on failure. */ int startSession(); /** * Send one application's data to the backup destination. * Send one application's data to the backup destination. The transport may send * the data immediately, or may buffer it. After this is called, {@link #finishBackup} * must be called to ensure the data is sent and recorded successfully. * * @param packageInfo The identity of the application whose data is being backed up. * This specifically includes the signature list for the package. * @param data The data stream that resulted from invoking the application's * BackupService.doBackup() method. This may be a pipe rather than a file on * persistent media, so it may not be seekable. * @return Zero on success; a nonzero error code on failure. * @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). */ int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor data); boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd); /** * Finish sending application data to the backup destination. This must be * called after {@link #performBackup} to ensure that all data is sent. Only * when this method returns true can the backup be assumed to have succeeded. * * @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). */ boolean finishBackup(); /** * Get the set of backups currently available over this transport. * * @return Descriptions of the set of restore images available for this device. * @return Descriptions of the set of restore images available for this device, * or null if an error occurred (the attempt should be rescheduled). **/ RestoreSet[] getAvailableRestoreSets(); /** * Get the set of applications from a given restore image. * Start restoring application data from backup. After calling this function, * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData} * to walk through the actual application data. * * @param token A backup token as returned by {@link #getAvailableRestoreSets}. * @return An array of PackageInfo objects describing all of the applications * available for restore from this restore image. This should include the list * of signatures for each package so that the Backup Manager can filter using that * information. * @param packages List of applications to restore (if data is available). * Application data will be restored in the order given. * @return false if errors occurred (the restore should be aborted and rescheduled), * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}). */ PackageInfo[] getAppSet(int token); boolean startRestore(long token, in PackageInfo[] packages); /** * Retrieve one application's data from the backing store. * * @param token The backup record from which a restore is being requested. * @param packageInfo The identity of the application whose data is being restored. * This must include the signature list for the package; it is up to the transport * to verify that the requested app's signatures match the saved backup record * because the transport cannot necessarily trust the client device. * @param data An open, writable file into which the backup image should be stored. * @return Zero on success; a nonzero error code on failure. * Get the package name of the next application with data in the backup store. * @return The name of one of the packages supplied to {@link #startRestore}, * or "" (the empty string) if no more backup data is available, * or null if an error occurred (the restore should be aborted and rescheduled). */ int getRestoreData(int token, in PackageInfo packageInfo, in ParcelFileDescriptor data); String nextRestorePackage(); /** * Terminate the backup session, closing files, freeing memory, and cleaning up whatever * other state the transport required. * * @return Zero on success; a nonzero error code on failure. Even on failure, the session * is torn down and must be restarted if another backup is attempted. * Get the data for the application returned by {@link #nextRestorePackage}. * @param data An open, writable file into which the backup data should be stored. * @return false if errors occurred (the restore should be aborted and rescheduled), * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}). */ boolean getRestoreData(in ParcelFileDescriptor outFd); /** * End a restore session (aborting any in-process data transfer as necessary), * freeing any resources and connections used during the restore process. */ int endSession(); void finishRestore(); } core/java/com/android/internal/backup/LocalTransport.java +58 −77 Original line number Diff line number Diff line Loading @@ -33,11 +33,8 @@ public class LocalTransport extends IBackupTransport.Stub { private Context mContext; private PackageManager mPackageManager; private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup"); private FileFilter mDirFileFilter = new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } }; private PackageInfo[] mRestorePackages = null; private int mRestorePackage = -1; // Index into mRestorePackages public LocalTransport(Context context) { Loading @@ -51,21 +48,9 @@ public class LocalTransport extends IBackupTransport.Stub { return 0; } public int startSession() throws RemoteException { if (DEBUG) Log.v(TAG, "session started"); mDataDir.mkdirs(); return 0; } public int endSession() throws RemoteException { if (DEBUG) Log.v(TAG, "session ended"); return 0; } public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) throws RemoteException { if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName); int err = 0; File packageDir = new File(mDataDir, packageInfo.packageName); packageDir.mkdirs(); Loading Loading @@ -101,9 +86,8 @@ public class LocalTransport extends IBackupTransport.Stub { try { entity.write(buf, 0, dataSize); } catch (IOException e) { Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); err = -1; Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); return false; } finally { entity.close(); } Loading @@ -111,14 +95,17 @@ public class LocalTransport extends IBackupTransport.Stub { entityFile.delete(); } } return true; } catch (IOException e) { // oops, something went wrong. abort the operation and return error. Log.v(TAG, "Exception reading backup input:"); e.printStackTrace(); err = -1; Log.v(TAG, "Exception reading backup input:", e); return false; } } return err; public boolean finishBackup() throws RemoteException { if (DEBUG) Log.v(TAG, "finishBackup()"); return true; } // Restore handling Loading @@ -129,72 +116,66 @@ public class LocalTransport extends IBackupTransport.Stub { return array; } public PackageInfo[] getAppSet(int token) throws android.os.RemoteException { if (DEBUG) Log.v(TAG, "getting app set " + token); // the available packages are the extant subdirs of mDatadir File[] packageDirs = mDataDir.listFiles(mDirFileFilter); ArrayList<PackageInfo> packages = new ArrayList<PackageInfo>(); for (File dir : packageDirs) { try { PackageInfo pkg = mPackageManager.getPackageInfo(dir.getName(), PackageManager.GET_SIGNATURES); if (pkg != null) { packages.add(pkg); } } catch (NameNotFoundException e) { // restore set contains data for a package not installed on the // phone -- just ignore it. } public boolean startRestore(long token, PackageInfo[] packages) { if (DEBUG) Log.v(TAG, "start restore " + token); mRestorePackages = packages; mRestorePackage = -1; return true; } if (DEBUG) { Log.v(TAG, "Built app set of " + packages.size() + " entries:"); for (PackageInfo p : packages) { Log.v(TAG, " + " + p.packageName); public String nextRestorePackage() { if (mRestorePackages == null) throw new IllegalStateException("startRestore not called"); while (++mRestorePackage < mRestorePackages.length) { String name = mRestorePackages[mRestorePackage].packageName; if (new File(mDataDir, name).isDirectory()) { if (DEBUG) Log.v(TAG, " nextRestorePackage() = " + name); return name; } } PackageInfo[] result = new PackageInfo[packages.size()]; return packages.toArray(result); if (DEBUG) Log.v(TAG, " no more packages to restore"); return ""; } public int getRestoreData(int token, PackageInfo packageInfo, ParcelFileDescriptor outFd) throws android.os.RemoteException { if (DEBUG) Log.v(TAG, "getting restore data " + token + " : " + packageInfo.packageName); // we only support one hardcoded restore set if (token != 0) return -1; // the data for a given package is at a known location File packageDir = new File(mDataDir, packageInfo.packageName); public boolean getRestoreData(ParcelFileDescriptor outFd) { if (mRestorePackages == null) throw new IllegalStateException("startRestore not called"); if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called"); File packageDir = new File(mDataDir, mRestorePackages[mRestorePackage].packageName); // The restore set is the concatenation of the individual record blobs, // each of which is a file in the package's directory File[] blobs = packageDir.listFiles(); if (DEBUG) Log.v(TAG, " found " + blobs.length + " key files"); int err = 0; if (blobs != null && blobs.length > 0) { if (blobs == null) { Log.e(TAG, "Error listing directory: " + packageDir); return false; // nextRestorePackage() ensures the dir exists, so this is an error } // We expect at least some data if the directory exists in the first place if (DEBUG) Log.v(TAG, " getRestoreData() found " + blobs.length + " key files"); BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor()); try { for (File f : blobs) { copyToRestoreData(f, out); } } catch (Exception e) { Log.e(TAG, "Unable to read backup records"); err = -1; } } return err; } private void copyToRestoreData(File f, BackupDataOutput out) throws IOException { FileInputStream in = new FileInputStream(f); try { int size = (int) f.length(); byte[] buf = new byte[size]; in.read(buf); String key = new String(Base64.decode(f.getName())); if (DEBUG) Log.v(TAG, " ... copy to stream: key=" + key + " size=" + size); if (DEBUG) Log.v(TAG, " ... key=" + key + " size=" + size); out.writeEntityHeader(key, size); out.writeEntityData(buf, size); } finally { in.close(); } } return true; } catch (IOException e) { Log.e(TAG, "Unable to read backup records", e); return false; } } public void finishRestore() { if (DEBUG) Log.v(TAG, "finishRestore()"); } } services/java/com/android/server/BackupManagerService.java +172 −205 File changed.Preview size limit exceeded, changes collapsed. Show changes services/java/com/android/server/PackageManagerBackupAgent.java +9 −9 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class PackageManagerBackupAgent extends BackupAgent { // is stored using the package name as a key) private static final String GLOBAL_METADATA_KEY = "@meta@"; private List<ApplicationInfo> mAllApps; private List<PackageInfo> mAllPackages; private PackageManager mPackageManager; private HashMap<String, Metadata> mRestoredSignatures; Loading @@ -73,9 +73,9 @@ public class PackageManagerBackupAgent extends BackupAgent { // We're constructed with the set of applications that are participating // in backup. This set changes as apps are installed & removed. PackageManagerBackupAgent(PackageManager packageMgr, List<ApplicationInfo> apps) { PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) { mPackageManager = packageMgr; mAllApps = apps; mAllPackages = packages; mRestoredSignatures = null; } Loading Loading @@ -118,8 +118,8 @@ public class PackageManagerBackupAgent extends BackupAgent { // For each app we have on device, see if we've backed it up yet. If not, // write its signature block to the output, keyed on the package name. for (ApplicationInfo app : mAllApps) { String packName = app.packageName; for (PackageInfo pkg : mAllPackages) { String packName = pkg.packageName; if (!existing.contains(packName)) { // We haven't stored this app's signatures yet, so we do that now try { Loading Loading @@ -186,7 +186,7 @@ public class PackageManagerBackupAgent extends BackupAgent { } // Finally, write the new state blob -- just the list of all apps we handled writeStateFile(mAllApps, newState); writeStateFile(mAllPackages, newState); } // "Restore" here is a misnomer. What we're really doing is reading back the Loading Loading @@ -327,7 +327,7 @@ public class PackageManagerBackupAgent extends BackupAgent { } // Util: write out our new backup state file private void writeStateFile(List<ApplicationInfo> apps, ParcelFileDescriptor stateFile) { private void writeStateFile(List<PackageInfo> pkgs, ParcelFileDescriptor stateFile) { FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); Loading @@ -338,8 +338,8 @@ public class PackageManagerBackupAgent extends BackupAgent { out.write(metaNameBuf); // now write all the app names too for (ApplicationInfo app : apps) { byte[] pkgNameBuf = app.packageName.getBytes(); for (PackageInfo pkg : pkgs) { byte[] pkgNameBuf = pkg.packageName.getBytes(); out.writeInt(pkgNameBuf.length); out.write(pkgNameBuf); } Loading Loading
core/java/android/backup/RestoreSet.java +5 −5 Original line number Diff line number Diff line Loading @@ -43,14 +43,14 @@ public class RestoreSet implements Parcelable { * transport. This is guaranteed to be valid for the duration of a restore * session, but is meaningless once the session has ended. */ public int token; public long token; public RestoreSet() { // Leave everything zero / null } public RestoreSet(String _name, String _dev, int _token) { public RestoreSet(String _name, String _dev, long _token) { name = _name; device = _dev; token = _token; Loading @@ -65,7 +65,7 @@ public class RestoreSet implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeString(name); out.writeString(device); out.writeInt(token); out.writeLong(token); } public static final Parcelable.Creator<RestoreSet> CREATOR Loading @@ -82,6 +82,6 @@ public class RestoreSet implements Parcelable { private RestoreSet(Parcel in) { name = in.readString(); device = in.readString(); token = in.readInt(); token = in.readLong(); } }
core/java/com/android/internal/backup/IBackupTransport.aidl +42 −35 Original line number Diff line number Diff line Loading @@ -54,63 +54,70 @@ interface IBackupTransport { long requestBackupTime(); /** * Establish a connection to the back-end data repository, if necessary. If the transport * needs to initialize state that is not tied to individual applications' backup operations, * this is where it should be done. * * @return Zero on success; a nonzero error code on failure. */ int startSession(); /** * Send one application's data to the backup destination. * Send one application's data to the backup destination. The transport may send * the data immediately, or may buffer it. After this is called, {@link #finishBackup} * must be called to ensure the data is sent and recorded successfully. * * @param packageInfo The identity of the application whose data is being backed up. * This specifically includes the signature list for the package. * @param data The data stream that resulted from invoking the application's * BackupService.doBackup() method. This may be a pipe rather than a file on * persistent media, so it may not be seekable. * @return Zero on success; a nonzero error code on failure. * @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). */ int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor data); boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd); /** * Finish sending application data to the backup destination. This must be * called after {@link #performBackup} to ensure that all data is sent. Only * when this method returns true can the backup be assumed to have succeeded. * * @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). */ boolean finishBackup(); /** * Get the set of backups currently available over this transport. * * @return Descriptions of the set of restore images available for this device. * @return Descriptions of the set of restore images available for this device, * or null if an error occurred (the attempt should be rescheduled). **/ RestoreSet[] getAvailableRestoreSets(); /** * Get the set of applications from a given restore image. * Start restoring application data from backup. After calling this function, * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData} * to walk through the actual application data. * * @param token A backup token as returned by {@link #getAvailableRestoreSets}. * @return An array of PackageInfo objects describing all of the applications * available for restore from this restore image. This should include the list * of signatures for each package so that the Backup Manager can filter using that * information. * @param packages List of applications to restore (if data is available). * Application data will be restored in the order given. * @return false if errors occurred (the restore should be aborted and rescheduled), * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}). */ PackageInfo[] getAppSet(int token); boolean startRestore(long token, in PackageInfo[] packages); /** * Retrieve one application's data from the backing store. * * @param token The backup record from which a restore is being requested. * @param packageInfo The identity of the application whose data is being restored. * This must include the signature list for the package; it is up to the transport * to verify that the requested app's signatures match the saved backup record * because the transport cannot necessarily trust the client device. * @param data An open, writable file into which the backup image should be stored. * @return Zero on success; a nonzero error code on failure. * Get the package name of the next application with data in the backup store. * @return The name of one of the packages supplied to {@link #startRestore}, * or "" (the empty string) if no more backup data is available, * or null if an error occurred (the restore should be aborted and rescheduled). */ int getRestoreData(int token, in PackageInfo packageInfo, in ParcelFileDescriptor data); String nextRestorePackage(); /** * Terminate the backup session, closing files, freeing memory, and cleaning up whatever * other state the transport required. * * @return Zero on success; a nonzero error code on failure. Even on failure, the session * is torn down and must be restarted if another backup is attempted. * Get the data for the application returned by {@link #nextRestorePackage}. * @param data An open, writable file into which the backup data should be stored. * @return false if errors occurred (the restore should be aborted and rescheduled), * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}). */ boolean getRestoreData(in ParcelFileDescriptor outFd); /** * End a restore session (aborting any in-process data transfer as necessary), * freeing any resources and connections used during the restore process. */ int endSession(); void finishRestore(); }
core/java/com/android/internal/backup/LocalTransport.java +58 −77 Original line number Diff line number Diff line Loading @@ -33,11 +33,8 @@ public class LocalTransport extends IBackupTransport.Stub { private Context mContext; private PackageManager mPackageManager; private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup"); private FileFilter mDirFileFilter = new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } }; private PackageInfo[] mRestorePackages = null; private int mRestorePackage = -1; // Index into mRestorePackages public LocalTransport(Context context) { Loading @@ -51,21 +48,9 @@ public class LocalTransport extends IBackupTransport.Stub { return 0; } public int startSession() throws RemoteException { if (DEBUG) Log.v(TAG, "session started"); mDataDir.mkdirs(); return 0; } public int endSession() throws RemoteException { if (DEBUG) Log.v(TAG, "session ended"); return 0; } public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) throws RemoteException { if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName); int err = 0; File packageDir = new File(mDataDir, packageInfo.packageName); packageDir.mkdirs(); Loading Loading @@ -101,9 +86,8 @@ public class LocalTransport extends IBackupTransport.Stub { try { entity.write(buf, 0, dataSize); } catch (IOException e) { Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); err = -1; Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath()); return false; } finally { entity.close(); } Loading @@ -111,14 +95,17 @@ public class LocalTransport extends IBackupTransport.Stub { entityFile.delete(); } } return true; } catch (IOException e) { // oops, something went wrong. abort the operation and return error. Log.v(TAG, "Exception reading backup input:"); e.printStackTrace(); err = -1; Log.v(TAG, "Exception reading backup input:", e); return false; } } return err; public boolean finishBackup() throws RemoteException { if (DEBUG) Log.v(TAG, "finishBackup()"); return true; } // Restore handling Loading @@ -129,72 +116,66 @@ public class LocalTransport extends IBackupTransport.Stub { return array; } public PackageInfo[] getAppSet(int token) throws android.os.RemoteException { if (DEBUG) Log.v(TAG, "getting app set " + token); // the available packages are the extant subdirs of mDatadir File[] packageDirs = mDataDir.listFiles(mDirFileFilter); ArrayList<PackageInfo> packages = new ArrayList<PackageInfo>(); for (File dir : packageDirs) { try { PackageInfo pkg = mPackageManager.getPackageInfo(dir.getName(), PackageManager.GET_SIGNATURES); if (pkg != null) { packages.add(pkg); } } catch (NameNotFoundException e) { // restore set contains data for a package not installed on the // phone -- just ignore it. } public boolean startRestore(long token, PackageInfo[] packages) { if (DEBUG) Log.v(TAG, "start restore " + token); mRestorePackages = packages; mRestorePackage = -1; return true; } if (DEBUG) { Log.v(TAG, "Built app set of " + packages.size() + " entries:"); for (PackageInfo p : packages) { Log.v(TAG, " + " + p.packageName); public String nextRestorePackage() { if (mRestorePackages == null) throw new IllegalStateException("startRestore not called"); while (++mRestorePackage < mRestorePackages.length) { String name = mRestorePackages[mRestorePackage].packageName; if (new File(mDataDir, name).isDirectory()) { if (DEBUG) Log.v(TAG, " nextRestorePackage() = " + name); return name; } } PackageInfo[] result = new PackageInfo[packages.size()]; return packages.toArray(result); if (DEBUG) Log.v(TAG, " no more packages to restore"); return ""; } public int getRestoreData(int token, PackageInfo packageInfo, ParcelFileDescriptor outFd) throws android.os.RemoteException { if (DEBUG) Log.v(TAG, "getting restore data " + token + " : " + packageInfo.packageName); // we only support one hardcoded restore set if (token != 0) return -1; // the data for a given package is at a known location File packageDir = new File(mDataDir, packageInfo.packageName); public boolean getRestoreData(ParcelFileDescriptor outFd) { if (mRestorePackages == null) throw new IllegalStateException("startRestore not called"); if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called"); File packageDir = new File(mDataDir, mRestorePackages[mRestorePackage].packageName); // The restore set is the concatenation of the individual record blobs, // each of which is a file in the package's directory File[] blobs = packageDir.listFiles(); if (DEBUG) Log.v(TAG, " found " + blobs.length + " key files"); int err = 0; if (blobs != null && blobs.length > 0) { if (blobs == null) { Log.e(TAG, "Error listing directory: " + packageDir); return false; // nextRestorePackage() ensures the dir exists, so this is an error } // We expect at least some data if the directory exists in the first place if (DEBUG) Log.v(TAG, " getRestoreData() found " + blobs.length + " key files"); BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor()); try { for (File f : blobs) { copyToRestoreData(f, out); } } catch (Exception e) { Log.e(TAG, "Unable to read backup records"); err = -1; } } return err; } private void copyToRestoreData(File f, BackupDataOutput out) throws IOException { FileInputStream in = new FileInputStream(f); try { int size = (int) f.length(); byte[] buf = new byte[size]; in.read(buf); String key = new String(Base64.decode(f.getName())); if (DEBUG) Log.v(TAG, " ... copy to stream: key=" + key + " size=" + size); if (DEBUG) Log.v(TAG, " ... key=" + key + " size=" + size); out.writeEntityHeader(key, size); out.writeEntityData(buf, size); } finally { in.close(); } } return true; } catch (IOException e) { Log.e(TAG, "Unable to read backup records", e); return false; } } public void finishRestore() { if (DEBUG) Log.v(TAG, "finishRestore()"); } }
services/java/com/android/server/BackupManagerService.java +172 −205 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/java/com/android/server/PackageManagerBackupAgent.java +9 −9 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class PackageManagerBackupAgent extends BackupAgent { // is stored using the package name as a key) private static final String GLOBAL_METADATA_KEY = "@meta@"; private List<ApplicationInfo> mAllApps; private List<PackageInfo> mAllPackages; private PackageManager mPackageManager; private HashMap<String, Metadata> mRestoredSignatures; Loading @@ -73,9 +73,9 @@ public class PackageManagerBackupAgent extends BackupAgent { // We're constructed with the set of applications that are participating // in backup. This set changes as apps are installed & removed. PackageManagerBackupAgent(PackageManager packageMgr, List<ApplicationInfo> apps) { PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) { mPackageManager = packageMgr; mAllApps = apps; mAllPackages = packages; mRestoredSignatures = null; } Loading Loading @@ -118,8 +118,8 @@ public class PackageManagerBackupAgent extends BackupAgent { // For each app we have on device, see if we've backed it up yet. If not, // write its signature block to the output, keyed on the package name. for (ApplicationInfo app : mAllApps) { String packName = app.packageName; for (PackageInfo pkg : mAllPackages) { String packName = pkg.packageName; if (!existing.contains(packName)) { // We haven't stored this app's signatures yet, so we do that now try { Loading Loading @@ -186,7 +186,7 @@ public class PackageManagerBackupAgent extends BackupAgent { } // Finally, write the new state blob -- just the list of all apps we handled writeStateFile(mAllApps, newState); writeStateFile(mAllPackages, newState); } // "Restore" here is a misnomer. What we're really doing is reading back the Loading Loading @@ -327,7 +327,7 @@ public class PackageManagerBackupAgent extends BackupAgent { } // Util: write out our new backup state file private void writeStateFile(List<ApplicationInfo> apps, ParcelFileDescriptor stateFile) { private void writeStateFile(List<PackageInfo> pkgs, ParcelFileDescriptor stateFile) { FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); Loading @@ -338,8 +338,8 @@ public class PackageManagerBackupAgent extends BackupAgent { out.write(metaNameBuf); // now write all the app names too for (ApplicationInfo app : apps) { byte[] pkgNameBuf = app.packageName.getBytes(); for (PackageInfo pkg : pkgs) { byte[] pkgNameBuf = pkg.packageName.getBytes(); out.writeInt(pkgNameBuf.length); out.write(pkgNameBuf); } Loading