Merge "Properly handle PACKAGE_REPLACED in addition to _ADDED and _REMOVED"
This commit is contained in:
committed by
Android (Google) Code Review
commit
8ec83219e8
@@ -197,14 +197,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
= new SparseArray<HashSet<ApplicationInfo>>();
|
= new SparseArray<HashSet<ApplicationInfo>>();
|
||||||
// set of backup services that have pending changes
|
// set of backup services that have pending changes
|
||||||
class BackupRequest {
|
class BackupRequest {
|
||||||
public ApplicationInfo appInfo;
|
public String packageName;
|
||||||
|
|
||||||
BackupRequest(ApplicationInfo app) {
|
BackupRequest(String pkgName) {
|
||||||
appInfo = app;
|
packageName = pkgName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BackupRequest{app=" + appInfo + "}";
|
return "BackupRequest{pkg=" + packageName + "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Backups that we haven't started yet. Keys are package names.
|
// Backups that we haven't started yet. Keys are package names.
|
||||||
@@ -877,6 +877,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||||
|
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
|
||||||
filter.addDataScheme("package");
|
filter.addDataScheme("package");
|
||||||
mContext.registerReceiver(mBroadcastReceiver, filter);
|
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||||
// Register for events related to sdcard installation.
|
// Register for events related to sdcard installation.
|
||||||
@@ -1174,7 +1175,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
String pkgList[] = null;
|
String pkgList[] = null;
|
||||||
if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
|
if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
|
||||||
Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
|
Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
|
||||||
|
Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return;
|
return;
|
||||||
@@ -1183,8 +1185,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (pkgName != null) {
|
if (pkgName != null) {
|
||||||
pkgList = new String[] { pkgName };
|
pkgList = new String[] { pkgName };
|
||||||
}
|
}
|
||||||
added = Intent.ACTION_PACKAGE_ADDED.equals(action);
|
if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
|
||||||
replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
|
// use the existing "add with replacement" logic
|
||||||
|
if (MORE_DEBUG) Slog.d(TAG, "PACKAGE_REPLACED, updating package " + pkgName);
|
||||||
|
added = replacing = true;
|
||||||
|
} else {
|
||||||
|
added = Intent.ACTION_PACKAGE_ADDED.equals(action);
|
||||||
|
replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
|
||||||
|
}
|
||||||
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
|
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
|
||||||
added = true;
|
added = true;
|
||||||
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
||||||
@@ -1192,6 +1200,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
added = false;
|
added = false;
|
||||||
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkgList == null || pkgList.length == 0) {
|
if (pkgList == null || pkgList.length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1665,9 +1674,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (status == BackupConstants.TRANSPORT_OK) {
|
if (status == BackupConstants.TRANSPORT_OK) {
|
||||||
PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
|
PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
|
||||||
mPackageManager, allAgentPackages());
|
mPackageManager, allAgentPackages());
|
||||||
BackupRequest pmRequest = new BackupRequest(new ApplicationInfo());
|
status = processOneBackup(PACKAGE_MANAGER_SENTINEL,
|
||||||
pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
|
|
||||||
status = processOneBackup(pmRequest,
|
|
||||||
IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
|
IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1716,7 +1723,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (status != BackupConstants.TRANSPORT_OK) {
|
if (status != BackupConstants.TRANSPORT_OK) {
|
||||||
Slog.w(TAG, "Backup pass unsuccessful, restaging");
|
Slog.w(TAG, "Backup pass unsuccessful, restaging");
|
||||||
for (BackupRequest req : mQueue) {
|
for (BackupRequest req : mQueue) {
|
||||||
dataChangedImpl(req.appInfo.packageName);
|
dataChangedImpl(req.packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also want to reset the backup schedule based on whatever
|
// We also want to reset the backup schedule based on whatever
|
||||||
@@ -1750,9 +1757,11 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// Verify that the requested app exists; it might be something that
|
// Verify that the requested app exists; it might be something that
|
||||||
// requested a backup but was then uninstalled. The request was
|
// requested a backup but was then uninstalled. The request was
|
||||||
// journalled and rather than tamper with the journal it's safer
|
// journalled and rather than tamper with the journal it's safer
|
||||||
// to sanity-check here.
|
// to sanity-check here. This also gives us the classname of the
|
||||||
|
// package's backup agent.
|
||||||
|
PackageInfo pkg;
|
||||||
try {
|
try {
|
||||||
mPackageManager.getPackageInfo(request.appInfo.packageName, 0);
|
pkg = mPackageManager.getPackageInfo(request.packageName, 0);
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
Slog.d(TAG, "Package does not exist; skipping");
|
Slog.d(TAG, "Package does not exist; skipping");
|
||||||
continue;
|
continue;
|
||||||
@@ -1760,11 +1769,11 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
IBackupAgent agent = null;
|
IBackupAgent agent = null;
|
||||||
try {
|
try {
|
||||||
mWakelock.setWorkSource(new WorkSource(request.appInfo.uid));
|
mWakelock.setWorkSource(new WorkSource(pkg.applicationInfo.uid));
|
||||||
agent = bindToAgentSynchronous(request.appInfo,
|
agent = bindToAgentSynchronous(pkg.applicationInfo,
|
||||||
IApplicationThread.BACKUP_MODE_INCREMENTAL);
|
IApplicationThread.BACKUP_MODE_INCREMENTAL);
|
||||||
if (agent != null) {
|
if (agent != null) {
|
||||||
int result = processOneBackup(request, agent, transport);
|
int result = processOneBackup(request.packageName, agent, transport);
|
||||||
if (result != BackupConstants.TRANSPORT_OK) return result;
|
if (result != BackupConstants.TRANSPORT_OK) return result;
|
||||||
}
|
}
|
||||||
} catch (SecurityException ex) {
|
} catch (SecurityException ex) {
|
||||||
@@ -1772,7 +1781,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
Slog.d(TAG, "error in bind/backup", ex);
|
Slog.d(TAG, "error in bind/backup", ex);
|
||||||
} finally {
|
} finally {
|
||||||
try { // unbind even on timeout, just in case
|
try { // unbind even on timeout, just in case
|
||||||
mActivityManager.unbindBackupAgent(request.appInfo);
|
mActivityManager.unbindBackupAgent(pkg.applicationInfo);
|
||||||
} catch (RemoteException e) {}
|
} catch (RemoteException e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1782,9 +1791,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
return BackupConstants.TRANSPORT_OK;
|
return BackupConstants.TRANSPORT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int processOneBackup(BackupRequest request, IBackupAgent agent,
|
private int processOneBackup(String packageName, IBackupAgent agent,
|
||||||
IBackupTransport transport) {
|
IBackupTransport transport) {
|
||||||
final String packageName = request.appInfo.packageName;
|
|
||||||
if (DEBUG) Slog.d(TAG, "processOneBackup doBackup() on " + packageName);
|
if (DEBUG) Slog.d(TAG, "processOneBackup doBackup() on " + packageName);
|
||||||
|
|
||||||
File savedStateName = new File(mStateDir, packageName);
|
File savedStateName = new File(mStateDir, packageName);
|
||||||
@@ -4207,7 +4215,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (app.packageName.equals(packageName)) {
|
if (app.packageName.equals(packageName)) {
|
||||||
// Add the caller to the set of pending backups. If there is
|
// Add the caller to the set of pending backups. If there is
|
||||||
// one already there, then overwrite it, but no harm done.
|
// one already there, then overwrite it, but no harm done.
|
||||||
BackupRequest req = new BackupRequest(app);
|
BackupRequest req = new BackupRequest(packageName);
|
||||||
if (mPendingBackups.put(app.packageName, req) == null) {
|
if (mPendingBackups.put(app.packageName, req) == null) {
|
||||||
// Journal this request in case of crash. The put()
|
// Journal this request in case of crash. The put()
|
||||||
// operation returned null when this package was not already
|
// operation returned null when this package was not already
|
||||||
@@ -4218,7 +4226,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
int numKeys = mPendingBackups.size();
|
int numKeys = mPendingBackups.size();
|
||||||
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
|
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
|
||||||
for (BackupRequest b : mPendingBackups.values()) {
|
for (BackupRequest b : mPendingBackups.values()) {
|
||||||
Slog.d(TAG, " + " + b + " agent=" + b.appInfo.backupAgentName);
|
Slog.d(TAG, " + " + b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user