Skip to content

[2661] Fix BroadcastReceiver ANR at ScreenOffTrigger#2732

Merged
pyricau merged 2 commits intosquare:mainfrom
FranAguilera:franjam/fix_broadcast_receiver_anr
Mar 24, 2026
Merged

[2661] Fix BroadcastReceiver ANR at ScreenOffTrigger#2732
pyricau merged 2 commits intosquare:mainfrom
FranAguilera:franjam/fix_broadcast_receiver_anr

Conversation

@FranAguilera
Copy link
Copy Markdown
Contributor

@FranAguilera FranAguilera commented Dec 18, 2024

Resolves #2661

Issue

BroadcastReceiver#onReceive runs by default on the main thread. If onReceive doesn't complete in a timely manner, the system will report an Application Not Responding

We've seen instances of this occurring frequently on internal builds

Solution

NOTE: Kudos to @pyricau for the guidance on adding a delay.

Let the broadcast receiver complete immediately and schedule the executor with an initial delay to avoid issues with the broadcast receiver not completing

Verification

Verified that the the ANR no longer occurs and reporting still completes without issues on one of our main apps (internal release build)

This was heavily tested on internal builds

analysisClient.newJob(JobContext(ScreenOffTrigger::class))
currentJob = job
analysisExecutor.execute {
analysisExecutor.execute {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If analysisExecutor.execute runs the task quickly enough, there's a chance that we might dump the heap & freeze the VM before the process has had a chance to report back to system_server, right?

Looks to me like if we want to avoid that, we need to execute with a delay instead"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I just updated it with a delayed executor. So far seems to be working as well and ANR is no longer reproducible internally

@FranAguilera FranAguilera requested a review from pyricau December 28, 2024 00:01
@FranAguilera FranAguilera marked this pull request as draft January 1, 2025 00:50
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jan 14, 2025

CLA assistant check
All committers have signed the CLA.

@FranAguilera FranAguilera marked this pull request as ready for review January 14, 2025 23:54
currentJob = null
analysisCallback(result)
if(currentJob.compareAndSet(null, job)){
delayedScheduledExecutorService.schedule {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this have been a simple Handler(Looper.getMainLooper()).postDelayed({}, 500) ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(you can cancel runnables on handler just fine)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, simplified to use Handler

@FranAguilera FranAguilera requested a review from pyricau January 15, 2025 22:59
*
* If not specified, the initial delay is 500 ms
*/
private val analysisExecutorDelayMillis: Long = INITIAL_EXECUTOR_DELAY_MILLIS
Copy link
Copy Markdown
Member

@pyricau pyricau Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API nit: take in a Duration instead, rename the field to analysisExecutorDelay

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good callout, updated now

@FranAguilera FranAguilera requested a review from pyricau January 16, 2025 14:08
@FranAguilera FranAguilera force-pushed the franjam/fix_broadcast_receiver_anr branch from 2668668 to d55327c Compare March 14, 2025 22:00
@FranAguilera FranAguilera reopened this Mar 14, 2025
@FranAguilera FranAguilera force-pushed the franjam/fix_broadcast_receiver_anr branch 7 times, most recently from c2d8541 to 6146c35 Compare March 18, 2025 22:35
@FranAguilera FranAguilera reopened this Mar 24, 2025
@FranAguilera FranAguilera force-pushed the franjam/fix_broadcast_receiver_anr branch 4 times, most recently from eff1023 to a9147ce Compare March 24, 2025 22:37
@FranAguilera FranAguilera force-pushed the franjam/fix_broadcast_receiver_anr branch 2 times, most recently from ba4b3f6 to 51e25f9 Compare March 24, 2025 22:51
Adding delay

Add a delayedScheduledExecutorService

Fix BroadcastReceiver ANR

PR feedback

Fix typo
@FranAguilera FranAguilera force-pushed the franjam/fix_broadcast_receiver_anr branch from 51e25f9 to 0ad89b1 Compare September 16, 2025 07:49
@square square deleted a comment from Jlb252423 Oct 2, 2025
@square square deleted a comment from Jlb252423 Oct 2, 2025
@pyricau pyricau merged commit 0f9b924 into square:main Mar 24, 2026
9 checks passed
@pyricau
Copy link
Copy Markdown
Member

pyricau commented Mar 24, 2026

Context from the past: the key issue here wasn't that we were actively blocking the main thread, but rather that we were starting the analysis immediately, which triggered a heap dump, so the VM froze and the receiver wouldn't respond in time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Background ANR at ScreenOffTrigger BroadcastReceiver [leakcanary on release]

3 participants