Don't assume r.curApp is valid when finalizing broadcasts

There is an inherent race with process death such that r.curApp can wind
up null before we're trying to validate identity bookkeeping around
future broadcast policy.  Deal with this gracefully.

Bug: 160199815
Test: manual
Test: tests/ActivityTests
Change-Id: Ia6b2e973be64abb927838ad4b7d040b2f8839c71
This commit is contained in:
Christopher Tate
2020-07-06 17:27:54 -07:00
committed by Chris Tate
parent 3aa9980879
commit e57d0f5e45

View File

@@ -470,22 +470,23 @@ public final class BroadcastQueue {
// if this receiver was slow, impose deferral policy on the app. This will kick in
// when processNextBroadcastLocked() next finds this uid as a receiver identity.
if (!r.timeoutExempt) {
if (mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
// r.curApp can be null if finish has raced with process death - benign
// edge case, and we just ignore it because we're already cleaning up
// as expected.
if (r.curApp != null
&& mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
// Core system packages are exempt from deferral policy
if (!UserHandle.isCore(r.curApp.uid)) {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
+ " was slow: " + receiver + " br=" + r);
}
if (r.curApp != null) {
mDispatcher.startDeferring(r.curApp.uid);
} else {
Slog.d(TAG_BROADCAST, "finish receiver curApp is null? " + r);
}
mDispatcher.startDeferring(r.curApp.uid);
} else {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
+ " receiver was slow but not deferring: " + receiver + " br=" + r);
+ " receiver was slow but not deferring: "
+ receiver + " br=" + r);
}
}
}