diff options
3 files changed, 34 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7a5970347667..f5ff70a10581 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16863,6 +16863,13 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } + // If the app is a regular app (uid >= 10000) and not the system server or phone + // process, etc, then mark it as being in full backup so that certain calls to the + // process can be blocked. This is not reset to false anywhere because we kill the + // process after the full backup is done and the ProcessRecord will vaporize anyway. + if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) { + proc.inFullBackup = true; + } r.app = proc; mBackupTarget = r; mBackupAppName = app.packageName; diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 0acc2a07e153..8ffc6f321c3e 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -258,6 +258,11 @@ public final class BroadcastQueue { if (app.thread == null) { throw new RemoteException(); } + if (app.inFullBackup) { + skipReceiverLocked(r); + return; + } + r.receiver = app.thread.asBinder(); r.curApp = app; app.curReceiver = r; @@ -341,13 +346,17 @@ public final class BroadcastQueue { } if (r != null) { - logBroadcastReceiverDiscardLocked(r); - finishReceiverLocked(r, r.resultCode, r.resultData, - r.resultExtras, r.resultAbort, false); - scheduleBroadcastsLocked(); + skipReceiverLocked(r); } } + private void skipReceiverLocked(BroadcastRecord r) { + logBroadcastReceiverDiscardLocked(r); + finishReceiverLocked(r, r.resultCode, r.resultData, + r.resultExtras, r.resultAbort, false); + scheduleBroadcastsLocked(); + } + public void scheduleBroadcastsLocked() { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts [" + mQueueName + "]: current=" @@ -641,9 +650,17 @@ public final class BroadcastQueue { try { if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST, "Delivering to " + filter + " : " + r); - performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, - new Intent(r.intent), r.resultCode, r.resultData, - r.resultExtras, r.ordered, r.initialSticky, r.userId); + if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) { + // Skip delivery if full backup in progress + // If it's an ordered broadcast, we need to continue to the next receiver. + if (ordered) { + skipReceiverLocked(r); + } + } else { + performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, + new Intent(r.intent), r.resultCode, r.resultData, + r.resultExtras, r.ordered, r.initialSticky, r.userId); + } if (ordered) { r.state = BroadcastRecord.CALL_DONE_RECEIVE; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 059acbd4190f..da18f32787bd 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -192,6 +192,9 @@ final class ProcessRecord { // app that installed the package. ComponentName errorReportReceiver; + // Process is currently hosting a backup agent for backup or restore + public boolean inFullBackup; + void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); |