Skip to content

Commit c6eb915

Browse files
Koji Fukuicodex-corp
authored andcommitted
Skip broadcasting to a receiver if the receiver seems to be dead
If an application that has a broadcast receiver is killed during broadcasting, thread variable of ProcessRecord becomes null so that IIntentReceiver#performReceive() is called in BroadcastQueue#performReceiveLocked(). But if binder driver has not noticed the death of the application yet, it can't throw DeadObjectException. After that, binder driver notices. But it can't notify DeadObjectException to the caller because performReceive() is async call. So broadcasting keeps on waiting for finishing performReceive() until timeout. This change checks the death of the application before calling performReceive() and skips broadcasting to the receiver if the application has already died. Change-Id: Ifa02b8b1a7e7b6fd314de90fedff5b7a5326825d
1 parent f702dfd commit c6eb915

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

services/java/com/android/server/am/BroadcastQueue.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,16 @@ private static void performReceiveLocked(ProcessRecord app, IIntentReceiver rece
422422
Intent intent, int resultCode, String data, Bundle extras,
423423
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
424424
// Send the intent to the receiver asynchronously using one-way binder calls.
425-
if (app != null && app.thread != null) {
426-
// If we have an app thread, do the call through that so it is
427-
// correctly ordered with other one-way calls.
428-
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
429-
data, extras, ordered, sticky, sendingUser, app.repProcState);
425+
if (app != null) {
426+
if (app.thread != null) {
427+
// If we have an app thread, do the call through that so it is
428+
// correctly ordered with other one-way calls.
429+
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
430+
data, extras, ordered, sticky, sendingUser, app.repProcState);
431+
} else {
432+
// Application has died. Receiver doesn't exist.
433+
throw new RemoteException("app.thread must not be null");
434+
}
430435
} else {
431436
receiver.performReceive(intent, resultCode, data, extras, ordered,
432437
sticky, sendingUser);
@@ -675,6 +680,7 @@ final void processNextBroadcast(boolean fromMsg) {
675680
// (local and remote) isn't kept in the mBroadcastHistory.
676681
r.resultTo = null;
677682
} catch (RemoteException e) {
683+
r.resultTo = null;
678684
Slog.w(TAG, "Failure ["
679685
+ mQueueName + "] sending broadcast result of "
680686
+ r.intent, e);

0 commit comments

Comments
 (0)