am 65634a79: Merge "Don\'t block in the BackupManagerService.dataChanged() Binder call." into gingerbread
Merge commit '65634a7935ed6f173179e7ac91a05288693b2bbf' into gingerbread-plus-aosp * commit '65634a7935ed6f173179e7ac91a05288693b2bbf': Don't block in the BackupManagerService.dataChanged() Binder call.
This commit is contained in:
@@ -668,7 +668,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
while (true) {
|
while (true) {
|
||||||
String packageName = in.readUTF();
|
String packageName = in.readUTF();
|
||||||
Slog.i(TAG, " + " + packageName);
|
Slog.i(TAG, " + " + packageName);
|
||||||
dataChanged(packageName);
|
dataChangedImpl(packageName);
|
||||||
}
|
}
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
// no more data; we're done
|
// no more data; we're done
|
||||||
@@ -740,7 +740,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
int uid = mBackupParticipants.keyAt(i);
|
int uid = mBackupParticipants.keyAt(i);
|
||||||
HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
|
HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
|
||||||
for (ApplicationInfo app: participants) {
|
for (ApplicationInfo app: participants) {
|
||||||
dataChanged(app.packageName);
|
dataChangedImpl(app.packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -896,7 +896,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (!mEverStoredApps.contains(pkg.packageName)) {
|
if (!mEverStoredApps.contains(pkg.packageName)) {
|
||||||
if (DEBUG) Slog.i(TAG, "New app " + pkg.packageName
|
if (DEBUG) Slog.i(TAG, "New app " + pkg.packageName
|
||||||
+ " never backed up; scheduling");
|
+ " never backed up; scheduling");
|
||||||
dataChanged(pkg.packageName);
|
dataChangedImpl(pkg.packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1327,7 +1327,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) {
|
||||||
dataChanged(req.appInfo.packageName);
|
dataChangedImpl(req.appInfo.packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also want to reset the backup schedule based on whatever
|
// We also want to reset the backup schedule based on whatever
|
||||||
@@ -1997,25 +1997,66 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dataChangedImpl(String packageName) {
|
||||||
|
HashSet<ApplicationInfo> targets = dataChangedTargets(packageName);
|
||||||
|
dataChangedImpl(packageName, targets);
|
||||||
|
}
|
||||||
|
|
||||||
// ----- IBackupManager binder interface -----
|
private void dataChangedImpl(String packageName, HashSet<ApplicationInfo> targets) {
|
||||||
|
|
||||||
public void dataChanged(String packageName) {
|
|
||||||
// Record that we need a backup pass for the caller. Since multiple callers
|
// Record that we need a backup pass for the caller. Since multiple callers
|
||||||
// may share a uid, we need to note all candidates within that uid and schedule
|
// may share a uid, we need to note all candidates within that uid and schedule
|
||||||
// a backup pass for each of them.
|
// a backup pass for each of them.
|
||||||
EventLog.writeEvent(EventLogTags.BACKUP_DATA_CHANGED, packageName);
|
EventLog.writeEvent(EventLogTags.BACKUP_DATA_CHANGED, packageName);
|
||||||
|
|
||||||
|
if (targets == null) {
|
||||||
|
Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
|
||||||
|
+ " uid=" + Binder.getCallingUid());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
// Note that this client has made data changes that need to be backed up
|
||||||
|
for (ApplicationInfo app : targets) {
|
||||||
|
// validate the caller-supplied package name against the known set of
|
||||||
|
// packages associated with this uid
|
||||||
|
if (app.packageName.equals(packageName)) {
|
||||||
|
// Add the caller to the set of pending backups. If there is
|
||||||
|
// one already there, then overwrite it, but no harm done.
|
||||||
|
BackupRequest req = new BackupRequest(app, false);
|
||||||
|
if (mPendingBackups.put(app, req) == null) {
|
||||||
|
// Journal this request in case of crash. The put()
|
||||||
|
// operation returned null when this package was not already
|
||||||
|
// in the set; we want to avoid touching the disk redundantly.
|
||||||
|
writeToJournalLocked(packageName);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
int numKeys = mPendingBackups.size();
|
||||||
|
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
|
||||||
|
for (BackupRequest b : mPendingBackups.values()) {
|
||||||
|
Slog.d(TAG, " + " + b + " agent=" + b.appInfo.backupAgentName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: packageName is currently unused, but may be in the future
|
||||||
|
private HashSet<ApplicationInfo> dataChangedTargets(String packageName) {
|
||||||
// If the caller does not hold the BACKUP permission, it can only request a
|
// If the caller does not hold the BACKUP permission, it can only request a
|
||||||
// backup of its own data.
|
// backup of its own data.
|
||||||
HashSet<ApplicationInfo> targets;
|
|
||||||
if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
|
if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
|
||||||
Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
|
Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
|
||||||
targets = mBackupParticipants.get(Binder.getCallingUid());
|
synchronized (mBackupParticipants) {
|
||||||
} else {
|
return mBackupParticipants.get(Binder.getCallingUid());
|
||||||
// a caller with full permission can ask to back up any participating app
|
}
|
||||||
// !!! TODO: allow backup of ANY app?
|
}
|
||||||
targets = new HashSet<ApplicationInfo>();
|
|
||||||
|
// a caller with full permission can ask to back up any participating app
|
||||||
|
// !!! TODO: allow backup of ANY app?
|
||||||
|
HashSet<ApplicationInfo> targets = new HashSet<ApplicationInfo>();
|
||||||
|
synchronized (mBackupParticipants) {
|
||||||
int N = mBackupParticipants.size();
|
int N = mBackupParticipants.size();
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i);
|
HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i);
|
||||||
@@ -2024,37 +2065,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targets != null) {
|
return targets;
|
||||||
synchronized (mQueueLock) {
|
|
||||||
// Note that this client has made data changes that need to be backed up
|
|
||||||
for (ApplicationInfo app : targets) {
|
|
||||||
// validate the caller-supplied package name against the known set of
|
|
||||||
// packages associated with this uid
|
|
||||||
if (app.packageName.equals(packageName)) {
|
|
||||||
// Add the caller to the set of pending backups. If there is
|
|
||||||
// one already there, then overwrite it, but no harm done.
|
|
||||||
BackupRequest req = new BackupRequest(app, false);
|
|
||||||
if (mPendingBackups.put(app, req) == null) {
|
|
||||||
// Journal this request in case of crash. The put()
|
|
||||||
// operation returned null when this package was not already
|
|
||||||
// in the set; we want to avoid touching the disk redundantly.
|
|
||||||
writeToJournalLocked(packageName);
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
int numKeys = mPendingBackups.size();
|
|
||||||
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
|
|
||||||
for (BackupRequest b : mPendingBackups.values()) {
|
|
||||||
Slog.d(TAG, " + " + b + " agent=" + b.appInfo.backupAgentName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
|
|
||||||
+ " uid=" + Binder.getCallingUid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToJournalLocked(String str) {
|
private void writeToJournalLocked(String str) {
|
||||||
@@ -2072,6 +2083,23 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----- IBackupManager binder interface -----
|
||||||
|
|
||||||
|
public void dataChanged(final String packageName) {
|
||||||
|
final HashSet<ApplicationInfo> targets = dataChangedTargets(packageName);
|
||||||
|
if (targets == null) {
|
||||||
|
Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
|
||||||
|
+ " uid=" + Binder.getCallingUid());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBackupHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
dataChangedImpl(packageName, targets);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Clear the given package's backup data from the current transport
|
// Clear the given package's backup data from the current transport
|
||||||
public void clearBackupData(String packageName) {
|
public void clearBackupData(String packageName) {
|
||||||
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName);
|
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName);
|
||||||
|
|||||||
Reference in New Issue
Block a user