diff options
author | Wale Ogunwale <ogunwale@google.com> | 2015-05-15 12:49:13 -0700 |
---|---|---|
committer | Wale Ogunwale <ogunwale@google.com> | 2015-05-15 13:33:16 -0700 |
commit | ca1c12581a794db7569c7408b3547bf04f9bb3c9 (patch) | |
tree | fa69bf1d0d027f5da60064b20427b95380d9e589 | |
parent | 0c72f4f9d04077f2fe96b486b8501303325a54af (diff) | |
download | frameworks_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
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)) |