ANR caused by incorrect cleanup in BroadcastQueue.

Pulled from aosp.

Fixes bug 18593454.

Two broadcasts could be sent to the same app simultaneously:
one foreground, one background. For example, LOCALE_CHANGED
and PACKAGE_CHANGED are delievered to com.android.vending
at the same time.
1. AMS started new vending process to handle LOCALE_CHANGED.
   And set app.curReceiver = LOCALE_CHANGED.
2. Before LOCALE_CHANGED is handled by vending process,
   PACKAGE_CHANGED was delievered to vending process too.
   AMS set app.curReceiver = PACKAGE_CHANGED. Bad!
3. Vending process finished handling LOCALE_CHANGED.
   AMS clear app.curReceiver = NULL. Bad!
   And Vending process  killed itself without handling
   PACKAGE_CHANGED.
4. AMS known vending process has died, but didn't know that
   BgBroadcastQueue was still waiting for finish message
   for PACKAGE_CHANGED.
At last, BgBroadcastQueue reported ANR for PACKAGE_CHANGED.

This patch adds protection before clearing app.curReceiver,
only set to NULL if the finishing receiver = app.curReceiver
So handleAppDied would know that PACKAGE_CHANGED was not
finished yet, it will abort the broadcast and continue.

Change-Id: Ic4f31b35e21823d4a3c27712391ecbede213a494
Signed-off-by: Guobin Zhang <guobin.zhang@intel.com>
This commit is contained in:
Guobin Zhang
2014-03-07 17:47:10 +08:00
committed by Craig Mautner
parent 932c332147
commit 53964dac4b

View File

@@ -352,7 +352,7 @@ public final class BroadcastQueue {
}
r.receiver = null;
r.intent.setComponent(null);
if (r.curApp != null) {
if (r.curApp != null && r.curApp.curReceiver == r) {
r.curApp.curReceiver = null;
}
if (r.curFilter != null) {