Skip to content

Require gapless support for offload playback - #76

Open
lostf1sh wants to merge 4 commits into
mainfrom
gapples
Open

Require gapless support for offload playback#76
lostf1sh wants to merge 4 commits into
mainfrom
gapples

Conversation

@lostf1sh

@lostf1sh lostf1sh commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Require gapless support when configuring audio offload to prevent playback gaps on unsupported HALs.
  • Fall back to PCM playback when gapless offload is unavailable.
  • Improve crossfade-disabled logging with the resolved transition source.

Testing

- Fall back to PCM when gapless offload is unavailable
- Treat crossfade as disabled for all disabled transition settings
@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a real-device audio gap bug by requiring gapless support when enabling audio offload, so HALs that only support plain offload fall back to PCM instead of dropping pre-buffered data at an automatic track transition. It also tightens the crossfade global toggle into a true master kill-switch, cleans up a few Compose API call sites, and bumps several build/runtime dependencies.

  • DualPlayerEngine: adds .setIsGaplessSupportRequired(true) to AudioOffloadPreferences; offload is now only used when the HAL explicitly supports gapless transitions.
  • TransitionController: removes the resolution.source == GLOBAL_DEFAULT guard so the global crossfade toggle prevents all crossfade regardless of per-track or per-playlist resolution source.
  • Build tooling: Gradle wrapper bumped to 9.6.1, AGP to 9.3.1, Kotlin to 2.4.10, Ktor/BouncyCastle/JUnit 5 minor patches, and GitHub Actions Gradle action pinned to a specific point release.

Confidence Score: 5/5

Safe to merge — the core offload fix is correct and well-documented, and no existing behaviour is broken.

The offload change correctly gates gapless transitions at the HAL level; when offload is disabled the new flag is a no-op. The TransitionController kill-switch expansion was already flagged in a prior review and is now explicitly documented in-code. Compose call-site cleanups and version bumps are low-risk. Testing was not run by the author, but the CI workflows exercise compile + lint + unit tests on every push, so that gap is covered.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
app/src/main/java/com/lostf1sh/pixelplayeross/data/service/player/DualPlayerEngine.kt Adds .setIsGaplessSupportRequired(true) to AudioOffloadPreferences; when offload mode is disabled the flag is a no-op, so both code paths are safe.
app/src/main/java/com/lostf1sh/pixelplayeross/data/service/player/TransitionController.kt Expands the global crossfade kill-switch to fire regardless of resolution source; documented in an inline comment; previous review comment addressed.
app/src/main/java/com/lostf1sh/pixelplayeross/presentation/components/subcomps/LibraryActionRow.kt Moves @OptIn(ExperimentalMaterial3Api::class) from the call-site inside the function to the function-level annotation; correct and cleaner placement.
app/src/main/java/com/lostf1sh/pixelplayeross/presentation/screens/SearchScreen.kt Removes redundant shapes = ToggleButtonDefaults.shapes() from ToggleButton call site; no behavioral change.
app/src/main/java/com/lostf1sh/pixelplayeross/presentation/screens/StatsScreen.kt Removes redundant shapes = ToggleButtonDefaults.shapes() from two ToggleButton call sites; no behavioral change.
gradle/libs.versions.toml Routine version bumps: AGP 9.3.1, Kotlin 2.4.10, Ktor 3.5.2, BouncyCastle 1.85, JUnit Jupiter 6.1.2, baselineprofile 1.5.0-beta01, constraintlayoutCompose 1.1.2.
gradle/wrapper/gradle-wrapper.properties Gradle wrapper bumped from 9.5.1 to 9.6.1 with updated SHA-256 checksum.
.github/workflows/nightly-apk.yml Pins gradle/actions/setup-gradle from the floating @v6 tag to the specific @v6.2.0 point release across all three CI workflows.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[buildPlayer called] --> B{audioOffloadEnabled?}
    B -- Yes --> C[AUDIO_OFFLOAD_MODE_ENABLED]
    B -- No --> D[AUDIO_OFFLOAD_MODE_DISABLED]
    C --> E[setIsGaplessSupportRequired true]
    D --> E
    E --> F[Build AudioOffloadPreferences]
    F --> G{Device HAL supports\ngapless offload?}
    G -- Yes --> H[Audio offload active\ngapless transitions enabled]
    G -- No --> I[Fall back to PCM path\nno track-start gap]
Loading

Reviews (4): Last reviewed commit: "Delete app/.attach_pid191510" | Re-trigger Greptile

- Document global crossfade toggle precedence
- Apply Material 3 opt-in at the component level
- Update toggle button styling for search and stats
…profile

Applies the bumps from the open Dependabot PRs directly on this branch,
since they were all branched off a main that does not compile:

  agp                     9.2.1         -> 9.3.1
  kotlin                  2.4.0         -> 2.4.10
  ktor                    3.5.1         -> 3.5.2
  junitJupiter / junit5   6.1.1         -> 6.1.2
  constraintlayoutCompose 1.1.1         -> 1.1.2
  bouncycastle            1.84          -> 1.85
  baselineprofile         1.5.0-alpha07 -> 1.5.0-beta01
  Gradle wrapper          9.5.1         -> 9.6.1
  gradle/actions          v6            -> v6.2.0

Verified with :app:compileDebugKotlin and :app:testDebugUnitTest.
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.

[Bug]: Cutting off the beginnings of songs?

1 participant