From b5f3b5c2e5108b875fdb21726eeca41f58d59d49 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Mon, 16 May 2016 14:23:04 -0700 Subject: [PATCH] Don't deliver broadcast to apps that are being backed up When doing a full backup, mark the process as being in backup and don't deliver any broadcasts to an app in that state. Bug: 25350780 Change-Id: I1adc95431f709495d3c1141c7c5d3616cf9cc1f0 --- .../server/am/ActivityManagerService.java | 7 +++++ .../com/android/server/am/BroadcastQueue.java | 31 ++++++++++++++----- .../com/android/server/am/ProcessRecord.java | 3 ++ 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 7a59703476672..f5ff70a105817 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 0acc2a07e1533..8ffc6f321c3e7 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 059acbd4190f0..da18f32787bdc 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();