Skip to content

feat(aod,share): interactive AOD screen saver shortcuts, battery rules, 1-tap lyrics controls & 9:16 canvas story sharing - #1142

Open
Balajitechlabs wants to merge 14 commits into
rukamori:devfrom
Balajitechlabs:feat/aod-screensaver-battery-gestures
Open

feat(aod,share): interactive AOD screen saver shortcuts, battery rules, 1-tap lyrics controls & 9:16 canvas story sharing#1142
Balajitechlabs wants to merge 14 commits into
rukamori:devfrom
Balajitechlabs:feat/aod-screensaver-battery-gestures

Conversation

@Balajitechlabs

Copy link
Copy Markdown
Contributor

Pull Request

Summary

This pull request introduces interactive features across AOD/Screen Saver, Lyrics, and Story Sharing, along with critical Android 15/16 stability fixes:

  1. Adds a 1-Tap Screen Saver shortcut card in AOD Settings, battery-aware automatic screen saver rules, track-skipping swipe gestures, and long-press album artwork Keyguard unlock integration.
  2. Adds 1-Tap Romanization (Romaji/Pinyin) and Translation quick toggle buttons directly to the Lyrics screen surface.
  3. Introduces 9:16 Instagram/WhatsApp Story Card generation with live playback timelines (position & duration) rendered off-thread via native Canvas, eliminating SnapshotStateObserver multithreading crashes.
  4. Resolves Android 15/16 (SDK 35/36) runtime crashes in AodPlayerScreen (LocalOnBackPressedDispatcherOwner) and ExoDownloadService (ForegroundServiceStartNotAllowedException).

Linked Work

  • Related: AOD Screen Saver & Media Sharing Improvements

Change Type

  • Feature
  • Bug fix
  • UI / UX
  • Performance / memory
  • Playback / Media3
  • Lyrics / provider integration
  • Search / YouTube / network data
  • Local library / Room database
  • Widgets / notification / shortcuts
  • Settings / preferences / DataStore
  • Discord / Last.fm / ListenBrainz / external integration
  • Localization / strings / fastlane metadata
  • Build / Gradle / CI / release packaging
  • Dependency update
  • Documentation only

Affected Surfaces

  • :app
  • :core
  • :lyrics
  • :lastfm
  • :canvas
  • :shazamkit
  • :spotifycore
  • Other:

Screenshots / Recordings

Before After
Static AOD info card Interactive 1-tap Screen Saver launch card & Battery rules
Menu-only story sharing 9:16 Canvas Story Cards with live progress timeline in PlayerMenu & SongMenu

Behavior Notes

  • AOD Screen Saver Launch: Tapping the shortcut card in AOD settings launches system DreamService directly.
  • AOD Keyguard Unlock: Long-pressing album artwork on AOD triggers haptic feedback and invokes KeyguardManager.requestDismissKeyguard so users can authenticate with Fingerprint/Face ID/PIN and return directly to the player.
  • AOD DreamService Guard: BackHandler safely checks LocalOnBackPressedDispatcherOwner.current != null to prevent IllegalStateException when rendering inside DreamService windows.
  • Android 15/16 Foreground Service Quotas: ExoDownloadService.onStartCommand() gracefully handles ForegroundServiceStartNotAllowedException returning START_NOT_STICKY.
  • Canvas Story Share: ComposeToImage.createStoryImage draws high-resolution 1080x1920 9:16 cards on a background thread via native Canvas + Coil, bypassing Compose view tree capture.

Architecture Checklist

  • The change preserves UDF flow: UI -> ViewModel -> UseCase/domain -> Repository/data.
  • Screen state is represented structurally with Loading, Success, Empty, and Error where this PR introduces or changes screen state.
  • Composables receive immutable, UI-specific domain models instead of raw Room, network, or service entities.
  • Business work is not triggered directly from composition.
  • Exceptions are surfaced through explicit state or result types instead of being swallowed.
  • No runBlocking is introduced in app execution paths.

Compose / Material Checklist

  • UI state is hoisted out of composable layout code.
  • Reactive state is collected with collectAsStateWithLifecycle().
  • New UI models are annotated with @Immutable or @Stable.
  • Lazy layouts use stable key values and explicit contentType.
  • Non-primitive constants, structural lambdas, and allocation-heavy objects in hot paths are remembered.
  • Rapidly changing inputs such as scroll, gesture, animation, or playback progress use derivedStateOf where appropriate.
  • UI strings come from stringResource() and duplicated visible strings on the same screen are avoided.
  • Interactive elements keep a minimum 48dp touch target.
  • Material 3 / Material 3 Expressive tokens are used for color, typography, shape, and motion instead of hardcoded UI values.
  • Edge-to-edge layouts handle and consume WindowInsets correctly when this PR changes screen layout.

Concurrency / Performance Checklist

  • Business coroutines are scoped to viewModelScope or an existing lifecycle-owned application/service scope.
  • Disk, database, network, parsing, and heavy mapping work is dispatched to Dispatchers.IO or Dispatchers.Default.
  • Cancellation is handled explicitly where long-running work, playback, downloads, sync, lyrics fetching, or recognition is involved.
  • The change avoids blocking the main thread.
  • The change avoids unnecessary allocations in recomposition loops, playback loops, polling loops, and provider parsing paths.
  • Large lists, images, lyrics payloads, and network responses are bounded, streamed, cached, paged, or mapped off the main thread as appropriate.

Data / Persistence Checklist

  • Room entity, DAO, or database changes include a schema update under app/schemas.
  • Database migrations preserve existing user data and fail clearly when migration is impossible.
  • DataStore or preference-key changes are backward compatible.
  • Network DTOs remain isolated from UI models.
  • Provider responses handle missing, malformed, regional, or rate-limited data without crashing the app.

Playback / Integration Checklist

  • Media3 playback, queue, cache, and service behavior remains stable across foreground, background, notification, and process recreation paths.
  • Audio focus, notification controls, widgets, shortcuts, and media session actions are considered when playback behavior changes.
  • External integrations handle absent credentials, revoked auth, network failure, and API changes.
  • Native, AAR, or ABI-sensitive changes account for mobile/tv and universal, arm64, armeabi, x86, and x86_64 variants.

Localization / Assets Checklist

  • User-facing strings are added to the base resources and translated resources are updated or intentionally left for translation follow-up.
  • Unused string resources, drawables, and metadata are removed when replaced.
  • Image assets have explicit display dimensions and are decoded at the displayed size.
  • Fastlane metadata, screenshots, icons, or release text are updated when user-facing store behavior changes.

Privacy / Security Checklist

  • No secrets, keys, tokens, keystores, signing files, private certificates, or local machine paths are committed.
  • Logs do not expose access tokens, cookies, auth headers, user identifiers, listening history, or local file paths.
  • New network calls are justified by the feature and use existing client, proxy, timeout, and error-handling patterns.
  • User data remains local unless the PR explicitly documents the integration and consent path.

Verification

  • Android Studio sync: Verified clean sync & compilation.
  • Manual device/emulator verification: Verified on Android 16 (SDK 36) device.
  • UI screenshot/recording attached: Story Share dialog and AOD settings verified.
  • Accessibility or touch-target review: Touch targets meet minimum 48dp guidelines.
  • Regression areas checked: AOD screen saver, lyrics toggles, menu story sharing, download service.
  • CI expectation: All Gradle tasks pass cleanly.

Reviewer Focus

  • AodPlayerScreen.kt: LocalOnBackPressedDispatcherOwner guard for DreamService and remember for onRequestUnlock.
  • ComposeToImage.kt: createStoryImage background canvas rendering off the Compose view hierarchy.
  • ExoDownloadService.kt: ForegroundServiceStartNotAllowedException handling for Android 15/16 6-hour quotas.

Release Notes

Added interactive Screen Saver shortcut, battery rules, 1-tap lyrics Romanize/Translate toggles, and live progress timeline 9:16 Canvas Story Cards.

Balajitechlabs and others added 11 commits August 9, 2026 11:05
…d swipe to skip tracks

- Make System Screen Saver card interactive with a 1-tap shortcut to
  system Dream Settings and live configuration badge.
- Add battery-aware AOD rules: 'Only while charging' toggle and configurable
  low battery safety cutoff (15%, 20%, 30%).
- Implement horizontal swipe gestures on the AOD screen to skip to Next/Previous
  track with interaction reset.
…ion repeat badges

- Add StoryShareDialog to export 9:16 vertical social cards with artwork,
  listening stats, and dynamic gradient for Instagram/WhatsApp/Telegram.
- Make ListeningByDayChart and ListeningByHourChart interactive with tap tooltips,
  spring animations, and haptic feedback showing exact listening durations.
- Add '48 Hours' continuous timeframe filter and glowing '🔥 On Repeat'
  obsession badge on top-played tracks.
…le buttons

- Add 1-tap Romanize button in LyricsScreen header to toggle Romaji, Pinyin,
  and Korean romanization instantly with active highlight.
- Add 1-tap Translate button in LyricsScreen header to toggle multi-language
  lyrics translation on the fly with active highlight.
…taSync ForegroundServiceStartNotAllowedException

- Guard BackHandler in AodPlayerScreen with LocalOnBackPressedDispatcherOwner.current != null
  to prevent IllegalStateException when rendered inside AodDreamService window.
- Catch ForegroundServiceStartNotAllowedException/Exception in ExoDownloadService.onStartCommand
  when Android 15/16 6-hour dataSync runtime quota is exhausted.
…apshotStateObserver crash

- Add createStoryImage to ComposeToImage to render high-resolution 1080x1920 Story cards
  directly via Android Canvas and Coil, avoiding off-main-thread Compose View hierarchy
  measurements that triggered SnapshotStateObserver multithreading crashes.
- Update StoryShareDialog to use createStoryImage and saveBitmapAsFile.
… SongMenu

- Support sharing any playing song as a 9:16 Story Card directly from PlayerMenu.
- Support sharing any library/online song as a 9:16 Story Card from SongMenu and YouTubeSongMenu.
- Render high-resolution 1080x1920 Story Cards via ComposeToImage.createStoryImage with:
  * Dynamic blurred ambient artwork background & multi-stop dark gradient.
  * Live playback timeline progress bar with elapsed time & duration.
  * Elevated album art card with soft drop shadow.
  * Bold typography for title, artist, and album.
  * ArchiveTune branding and 'NOW PLAYING' badge.
…& open full app

- Long-pressing album artwork on AOD triggers haptic feedback.
- Requests system Keyguard dismissal via KeyguardManager.requestDismissKeyguard.
- Prompts device PIN / Password / Fingerprint / Face ID if locked, then smoothly exits AOD into the full player screen.
@rukamori
rukamori force-pushed the feat/aod-screensaver-battery-gestures branch from 3604a8b to 28f27ba Compare August 9, 2026 11:18
@rukamori
rukamori force-pushed the dev branch 2 times, most recently from c47f989 to 2ba97fe Compare August 29, 2026 08:41
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.

2 participants