Implement battery data reliability checks #6727
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Added battery data reliability checks to ensure valid battery levels are used for decision making.
Fixes #6710 #5305
Description of the Change
This PR fixes a bug in the Android client where computation would be incorrectly suspended when the screen turns off. The issue occurred because the client receives stale or erroneous battery data (often reported as 0%) from the GUI when the device screen is off, triggering an unnecessary low-battery suspension.
The fix introduces a reliability layer for battery data within CLIENT_STATE::check_suspend_processing() in client/cs_prefs.cpp. Before making a suspension decision based on battery level, the code now:
Checks for stale data: If the last update from the GUI is older than a defined threshold (5 minutes), the battery check is skipped entirely for that cycle to avoid decisions based on outdated information.
Detects improbable values: If the reported battery charge drops from a previously known reliable level (e.g., >5%) directly to 0%, this is treated as an error (a physical impossibility). In this case, the last known reliable battery level is used for the suspension decision instead of the erroneous 0%.
Tracks reliable levels: A valid, positive battery reading is stored as the new "last reliable" level for future comparison.
This approach ensures that suspension decisions are based on sensible data, preventing unnecessary interruptions to computation, especially during screen-off scenarios common for mobile devices. The fix is保守的; it only intervenes when data is clearly problematic (stale or physically impossible) and logs its actions for transparency.
Alternate Designs
Modifying the Android GUI (report_device_status RPC): The root cause is in the battery data source. We could try to make the GUI more robust in reporting battery levels when the screen is off (e.g., using a foreground service, different Android APIs like BatteryManager). However, this would require changes to the Android GUI app, which is a separate codebase, and the behavior might still be limited by Android's power-saving restrictions.
Ignoring battery checks during screen-off: We could suspend battery checks entirely when the user_active flag is false (screen off). This is simpler but less precise, as it would also disable legitimate low-battery suspensions during screen-off, which is undesirable.
Using Android system APIs directly in the core client: The core client could attempt to read battery status directly via Android NDK/JNI. This would add complexity, platform-specific code, and might not be permitted under all device states or Android versions.
Selected Design Rationale: The implemented solution was chosen because it:
Minimizes change: It's a localized fix in the core client logic, requiring no changes to the Android GUI, RPC protocol, or project servers.
Is robust: It handles the specific error pattern (stale data, 0% spikes) observed in the issue.
Preserves safety: It does not disable battery checks; it tries to correct them. Legitimate low-battery conditions (e.g., a gradual drain to 5%) will still trigger a suspension correctly.
Is transparent: Actions are logged, aiding in future debugging.
Release Notes
For Android Users: Fixed an issue where BOINC would incorrectly pause computation when your phone's screen was off, even if the battery was not actually low.
Summary by cubic
Prevents false low‑battery suspensions on Android by validating battery data before making suspend decisions; fixes #6710 and #5305.
Written for commit 34b2e1b. Summary will update automatically on new commits.