diff options
author | riddle_hsu <riddle_hsu@htc.com> | 2015-01-03 15:38:21 +0800 |
---|---|---|
committer | riddle_hsu <riddle_hsu@htc.com> | 2015-01-03 15:38:21 +0800 |
commit | 1f5ac4d322d76ca76fdf5dee40fe9549aad7437e (patch) | |
tree | 068aa441af936858f9764c0333a91080e46c0799 /core/java/android/content/BroadcastReceiver.java | |
parent | 38c2dae5f12003ff39a5b1a5e46f079174fcedca (diff) | |
download | frameworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.zip frameworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.tar.gz frameworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.tar.bz2 |
[ActivityManager] Distinguish FG or BG receiver finished
Symptom:
Assume a foreground broadcast FG and a background BG.
If a recevier registers both FG and BG. When sending
BG and FG to the receiver, and the receiver BG receiver
completes first, its finishReceiver will trigger next FG
receiver rather than BG, and also deliver wrong result
code/data to the next.
More detail and sample:
https://code.google.com/p/android/issues/detail?id=92917
Root cause:
Due to BroadcastQueue:getMatchingOrderedReceiver will match
by receiver(IBinder), so the caller ActivityManagerService:
broadcastRecordForReceiverLocked will always match the first
queue(fg) if a receiver is both receiving fg and bg.
Solution:
Add a parameter flags to finishReceiver, then server side
could know the finished receiver should belong to which queue.
Another general solution but with bigger scope:
I60dce4a48e20c1002a61a979e4d78b9b0a8b94a0
Change-Id: I913ca6f101ac8ec6c7a8e42754e6781f80247b7f
Diffstat (limited to 'core/java/android/content/BroadcastReceiver.java')
-rw-r--r-- | core/java/android/content/BroadcastReceiver.java | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index 9a32fdf..af74e73 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -238,6 +238,7 @@ public abstract class BroadcastReceiver { final boolean mInitialStickyHint; final IBinder mToken; final int mSendingUser; + final int mFlags; int mResultCode; String mResultData; @@ -246,8 +247,8 @@ public abstract class BroadcastReceiver { boolean mFinished; /** @hide */ - public PendingResult(int resultCode, String resultData, Bundle resultExtras, - int type, boolean ordered, boolean sticky, IBinder token, int userId) { + public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, + boolean ordered, boolean sticky, IBinder token, int userId, int flags) { mResultCode = resultCode; mResultData = resultData; mResultExtras = resultExtras; @@ -256,6 +257,7 @@ public abstract class BroadcastReceiver { mInitialStickyHint = sticky; mToken = token; mSendingUser = userId; + mFlags = flags; } /** @@ -417,11 +419,11 @@ public abstract class BroadcastReceiver { } if (mOrderedHint) { am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, - mAbortBroadcast); + mAbortBroadcast, mFlags); } else { // This broadcast was sent to a component; it is not ordered, // but we still need to tell the activity manager we are done. - am.finishReceiver(mToken, 0, null, null, false); + am.finishReceiver(mToken, 0, null, null, false, mFlags); } } catch (RemoteException ex) { } |