Hold a wake lock during playback to reduce background playback stops#5491
Hold a wake lock during playback to reduce background playback stops#5491joashrajin wants to merge 3 commits into
Conversation
Set a source-aware ExoPlayer wake mode (WAKE_MODE_LOCAL for downloaded, WAKE_MODE_NETWORK for streams) in SimplePlayer.prepare() so the player holds a wake lock for the duration of playback instead of the Media3 default WAKE_MODE_NONE. Without a wake lock the system can suspend the CPU / drop Wi-Fi and aggressively freeze or reclaim the foreground-service process during long uninterrupted background playback. This re-introduces only the setWakeMode line, decoupled from the audio offload code it was previously bundled with (added in #5059, reverted in #5105). The WAKE_LOCK permission is already declared. Related to PCDROID-555.
|
Claude finished @joashrajin's task in 1m 6s —— View job Code ReviewI reviewed the single-line change to
AssessmentThe change adds Correctness ✅
Permissions ✅ (with one thing to confirm)
Minor observations (non-blocking)
Testing History context Nice, focused change. The only thing I'd actively suggest before merge is confirming the |
Generated by 🚫 Danger |
|
Claude finished @joashrajin's task in 1m 44s —— View job Code Review
Reviewed the change in Correctness ✅
Minor considerations (non-blocking)
TestingAgree with the PR's stance that this isn't meaningfully unit-testable ( No changes requested — looks good to merge once on-device verification and |
SimplePlayer's ExoPlayer wake mode needs WAKE_LOCK. It already merged in transitively (via the analytics/localization modules), but declaring it in the module that actually uses it makes the requirement self-documenting and guarantees coverage for the app, wear, and automotive builds. Related to PCDROID-555.
|
Claude finished @joashrajin's task in 39s —— View job Code Review
This update addresses the one actionable item from the previous reviews: Looks correct and ready to merge (pending the on-device verification the PR description lays out). Correctness ✅
Manifest declaration ✅
Minor, unchanged from prior reviews (non-blocking)
TestingAgree this isn't meaningfully unit-testable ( No changes requested. |
Project manifest changes for automotiveThe following changes in the --- ./build/reports/diff_manifest/automotive/release/base_manifest.txt 2026-06-30 09:30:56.434897196 +0000
+++ ./build/reports/diff_manifest/automotive/release/head_manifest.txt 2026-06-30 09:30:57.860626038 +0000
@@ -54,8 +54,14 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
- <uses-permission android:name="android.permission.INTERNET" />
+ <!--
+ Required by ExoPlayer's wake mode (SimplePlayer) to hold a wake lock
+ during background playback. Declared here, in the module that uses it,
+ so every consumer (app, wear, automotive) gets it without relying on
+ transitive merge from unrelated modules.
+ -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />Go to https://buildkite.com/automattic/pocket-casts-android/builds/17359/canvas?sid=019f17dc-44d4-4db9-bb10-c33c876a02af, click on the |
Description
Background playback of a long local Files episode can silently stop on its own (Pixel 6 / Android 16). The logs in PCDROID-555 show the system SIGKILLing the Pocket Casts foreground-service process mid-playback (
reason=2 SIGNALED status=9,importance=125), with frequentFREEZER/cached-app activity on surrounding days — not an internal pause or audio-focus loss.Root cause (closed gap): the background-audio
ExoPlayeris built with no wake mode set, so it defaults toWAKE_MODE_NONEand holds no wake lock during playback. That's the missing standard configuration for background audio — without a wake lock the system is free to suspend the CPU / drop Wi-Fi and aggressively freeze/reclaim the process during long uninterrupted playback.This sets a source-aware wake mode on the one background-audio player (
SimplePlayer, shared by both the Media3 and legacy service paths):WAKE_MODE_LOCAL(partial CPU wake lock) for downloaded/local episodes, andWAKE_MODE_NETWORK(partial wake lock + Wi-Fi lock) for streams.isStreamingis known at build time, theWAKE_LOCKpermission is already declared, and Media3 ties the lock to the playing state (it's released automatically on pause/stop), so there's no paused-but-locked battery drain.Changes
SimplePlayer.prepare()— add.setWakeMode(if (isStreaming) C.WAKE_MODE_NETWORK else C.WAKE_MODE_LOCAL)to theExoPlayer.Builderchain, with an explanatory comment. No manifest, import, or permission changes needed (Calready imported;WAKE_LOCKalready declared).Testing Instructions
adb shell dumpsys power | grep -i wakeshows a lock held by the package during playback.adb shell dumpsys wifi | grep -i lock).adb shell dumpsys activity exit-info <pkg>and confirm theSIGKILLduring playback no longer recurs (or recurs less often). If it still recurs, the residual cause is likely memory pressure — see follow-ups below.Not easily unit-testable: this is
ExoPlayer.Builderconfiguration that the Media3 API doesn't expose for assertion. Behaviour is validated on-device. Follow-ups if the kill persists after verification:onTrimMemoryhandling in the playback service and moving episode-metadata decode off the player thread (tracked separately, lower confidence).Screenshots or Screencast
n/a — no UI changes.
Checklist
./gradlew spotlessApplyto automatically apply formatting/linting)modules/services/localization/src/main/res/values/strings.xml— n/a (no strings)I have tested any UI changes...
n/a — this PR contains no UI changes.