summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWale Ogunwale <ogunwale@google.com>2015-05-15 12:49:13 -0700
committerWale Ogunwale <ogunwale@google.com>2015-05-15 13:33:16 -0700
commitca1c12581a794db7569c7408b3547bf04f9bb3c9 (patch)
treefa69bf1d0d027f5da60064b20427b95380d9e589
parent0c72f4f9d04077f2fe96b486b8501303325a54af (diff)
downloadframeworks_base-ca1c12581a794db7569c7408b3547bf04f9bb3c9.zip
frameworks_base-ca1c12581a794db7569c7408b3547bf04f9bb3c9.tar.gz
frameworks_base-ca1c12581a794db7569c7408b3547bf04f9bb3c9.tar.bz2
Clean-up broadcast receivers when component is disabled.
Bug: 15804187 Change-Id: Ib672f720bd5c8d81d3846568ef53f7723685f317
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java16
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java31
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java34
3 files changed, 75 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2158395..f4bd803 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5299,7 +5299,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, String reason) {
- ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
+ ArrayList<ProcessRecord> procs = new ArrayList<>();
// Remove all processes this package may have touched: all with the
// same UID (except for the system or root user), and all whose name
@@ -5446,6 +5446,13 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i = providers.size() - 1; i >= 0; i--) {
removeDyingProviderLocked(null, providers.get(i), true);
}
+
+ // Clean-up disabled broadcast receivers.
+ for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
+ mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
+ packageName, disabledClasses, userId, true);
+ }
+
}
private final boolean forceStopPackageLocked(String packageName, int appId,
@@ -5542,6 +5549,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// Remove transient permissions granted from/to this package/user
removeUriPermissionsForPackageLocked(packageName, userId, false);
+ if (doit) {
+ for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
+ didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
+ packageName, null, userId, doit);
+ }
+ }
+
if (packageName == null || uninstalling) {
// Remove pending intents. For now we only do this when force
// stopping users, because we have some problems when doing this
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index e89ef57..745cb7e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -21,6 +21,7 @@ import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Set;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -209,7 +210,7 @@ public final class BroadcastQueue {
}
public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
- for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"***** DROPPING PARALLEL ["
@@ -222,7 +223,7 @@ public final class BroadcastQueue {
}
public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
- for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
+ for (int i = mOrderedBroadcasts.size() - 1; i > 0; i--) {
if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"***** DROPPING ORDERED ["
@@ -1097,6 +1098,28 @@ public final class BroadcastQueue {
mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
}
+ boolean cleanupDisabledPackageReceiversLocked(
+ String packageName, Set<String> filterByClasses, int userId, boolean doit) {
+ boolean didSomething = false;
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
+ didSomething |= mParallelBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
+ packageName, filterByClasses, userId, doit);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+
+ for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
+ didSomething |= mOrderedBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
+ packageName, filterByClasses, userId, doit);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+
+ return didSomething;
+ }
+
final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
if (r.nextReceiver > 0) {
Object curReceiver = r.receivers.get(r.nextReceiver-1);
@@ -1130,7 +1153,7 @@ public final class BroadcastQueue {
if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
|| mPendingBroadcast != null) {
boolean printed = false;
- for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
BroadcastRecord br = mParallelBroadcasts.get(i);
if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
continue;
@@ -1148,7 +1171,7 @@ public final class BroadcastQueue {
}
printed = false;
needSep = true;
- for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
BroadcastRecord br = mOrderedBroadcasts.get(i);
if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
continue;
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 9a4d7a0..c050d03 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -26,12 +26,14 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
+import java.util.Set;
/**
* An active intent broadcast.
@@ -164,7 +166,7 @@ final class BroadcastRecord extends Binder {
final int N = receivers != null ? receivers.size() : 0;
String p2 = prefix + " ";
PrintWriterPrinter printer = new PrintWriterPrinter(pw);
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
Object o = receivers.get(i);
pw.print(prefix); pw.print("Receiver #"); pw.print(i);
pw.print(": "); pw.println(o);
@@ -205,6 +207,36 @@ final class BroadcastRecord extends Binder {
state = IDLE;
}
+ boolean cleanupDisabledPackageReceiversLocked(
+ String packageName, Set<String> filterByClasses, int userId, boolean doit) {
+ if ((userId != UserHandle.USER_ALL && this.userId != userId) || receivers == null) {
+ return false;
+ }
+
+ boolean didSomething = false;
+ Object o;
+ for (int i = receivers.size() - 1; i >= 0; i--) {
+ o = receivers.get(i);
+ if (!(o instanceof ResolveInfo)) {
+ continue;
+ }
+ ActivityInfo info = ((ResolveInfo)o).activityInfo;
+
+ final boolean sameComponent = packageName == null
+ || (info.applicationInfo.packageName.equals(packageName)
+ && (filterByClasses == null || filterByClasses.contains(info.name)));
+ if (sameComponent) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ receivers.remove(i);
+ }
+ }
+
+ return didSomething;
+ }
+
public String toString() {
return "BroadcastRecord{"
+ Integer.toHexString(System.identityHashCode(this))