summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Carlsson <johannes.carlsson.x@sonyericsson.com>2010-10-27 10:08:10 +0200
committerSteve Kondik <shade@chemlab.org>2010-11-21 04:22:50 -0500
commit78a97b98a8e53c9b1b808f6011b86621f4918bfe (patch)
treefdebf640c77e996584df75eaea0055608eb580f9
parentfb435619ead394bcb7188143cb49a673ce5c1477 (diff)
downloadframeworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.zip
frameworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.tar.gz
frameworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.tar.bz2
Clear reference to the IIntentReceiver in order to avoid memory leak
When using sendOrderedBroadcast(..) with a BroadcastReceiver the BroadcastReceiver instance was not released. The reason for this was that the resultTo field in the BroadcastRecord kept a reference until it was pushed out of the mBroadcastHistory. This reference in turn kept a reference to the process side IIntentReceiver (implemented in ReceiverDispatcher$InnerReceiver). This in turn had a strong reference (through mStrongRef) to the Context. In order to keep the debug output the resultTo is also kept as a String in the new resultToString variable. Change-Id: I4382a22a541c27b3694fb2b78a04ee820b235f8f
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/java/com/android/server/am/BroadcastRecord.java8
2 files changed, 8 insertions, 3 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0aebc1c..837011e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -13199,6 +13199,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
performReceive(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false);
+ // Set this to null so that the reference
+ // (local and remote) isnt kept in the mBroadcastHistory.
+ r.resultTo = null;
} catch (RemoteException e) {
Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
}
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index c3f0b3e..4faaeca 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -44,7 +44,8 @@ class BroadcastRecord extends Binder {
final boolean initialSticky; // initial broadcast from register to sticky?
final String requiredPermission; // a permission the caller has required
final List receivers; // contains BroadcastFilter and ResolveInfo
- final IIntentReceiver resultTo; // who receives final result if non-null
+ IIntentReceiver resultTo; // who receives final result if non-null
+ private final String resultToString; // resultTo.toString() used for debug purposes
long dispatchTime; // when dispatch started on this set of receivers
long receiverTime; // when current receiver started for timeouts.
long finishTime; // when we finished the broadcast.
@@ -100,8 +101,8 @@ class BroadcastRecord extends Binder {
if (anrCount != 0) {
pw.println(prefix + "anrCount=" + anrCount);
}
- if (resultTo != null || resultCode != -1 || resultData != null) {
- pw.println(prefix + "resultTo=" + resultTo
+ if (resultToString != null || resultCode != -1 || resultData != null) {
+ pw.println(prefix + "resultTo=" + resultToString
+ " resultCode=" + resultCode + " resultData=" + resultData);
}
if (resultExtras != null) {
@@ -164,6 +165,7 @@ class BroadcastRecord extends Binder {
requiredPermission = _requiredPermission;
receivers = _receivers;
resultTo = _resultTo;
+ resultToString = resultTo == null ? null : resultTo.toString();
resultCode = _resultCode;
resultData = _resultData;
resultExtras = _resultExtras;