Feature/jrc 4201.api.to.check.previous.anr.2#8110
Conversation
Implements firebase-android-sdk#4201 by exposing a new public API method that detects whether the app was killed by an ANR in the previous run, mirroring the existing didCrashOnPreviousExecution() pattern. On Android API 30+ the method queries ApplicationExitInfo (already used internally for ANR session reporting) against the previous session's start timestamp. On older API levels it always returns false.
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
|
/gemini review |
📝 PRs merging into main branchOur main branch should always be in a releasable state. If you are working on a larger change, or if you don't want this change to see the light of the day just yet, consider using a feature branch first, and only merge into the main branch when the code complete and ready to be released. |
There was a problem hiding this comment.
Code Review
This pull request adds the didANRKillOnPreviousExecution() method to FirebaseCrashlytics, allowing apps on Android API 30+ to detect if the previous run ended in an ANR. The implementation queries ActivityManager for historical process exit reasons during initialization. Reviewers suggested adding a null check for the ActivityManager service and logging exceptions during the ANR check to improve robustness and diagnosability.
| ActivityManager activityManager = | ||
| (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); |
There was a problem hiding this comment.
The getSystemService call can return null. It is safer to perform a null check on activityManager before calling getHistoricalProcessExitReasons to avoid a potential NullPointerException.
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager == null) {
return false;
}
List<ApplicationExitInfo> applicationExitInfoList =| } catch (Exception ignored) { | ||
| didANROnPreviousExecution = false; | ||
| return; | ||
| } |
There was a problem hiding this comment.
While ignoring the exception is consistent with checkForPreviousCrash, it is generally better to log the error (at least at a verbose or debug level) to help diagnose why the ANR check might have failed or timed out.
| } catch (Exception ignored) { | |
| didANROnPreviousExecution = false; | |
| return; | |
| } | |
| } catch (Exception ex) { | |
| Logger.getLogger().v("Error checking for previous ANR: " + ex.getMessage()); | |
| didANROnPreviousExecution = false; | |
| return; | |
| } |
… log ANR check failures - Add null guard on ActivityManager from getSystemService() before calling getHistoricalProcessExitReasons() to avoid potential NPE. - Log exceptions in checkForPreviousAnr() at verbose level instead of silently ignoring them, to aid diagnosability.
Add didANRKillOnPreviousExecution() to FirebaseCrashlytics
Implements #4201.
Background
Crashlytics already detects ANRs and files reports for them, and developers have long been able to call
didCrashOnPreviousExecution()to gate logic that should only run after a fatal crash. However, there was no equivalent API for ANRs: developers who want to adapt their app's behavior after an ANR (e.g., disable a heavy feature on the next cold start, log a custom key, or show a recovery dialog) had no supported way to do so.didCrashOnPreviousExecution()works by reading a marker file written at crash time. ANRs cannot use that mechanism because the main thread is frozen and the crash handler never runs. Instead, the new method usesApplicationExitInfo(API 30+), which records process-exit reasons at the OS level — the same source already queried internally bySessionReportingCoordinatorwhen filing ANR reports. The new API delegates to that existing infrastructure rather than introducing a separate detection path.Risk
publicmethod onFirebaseCrashlytics(didANRKillOnPreviousExecution()). No existing method signatures changed.false; noApplicationExitInfoaccess attempted.getHistoricalProcessExitReasonsonce at startup on the background thread with a bounded timeout. This is the sameActivityManagercall already made by the ANR-reporting path; no new system service is introduced.