Skip to content

Fix single-bud NPE crashes, BluetoothSocket reflection, and add rootless Charging Case Sounds - #763

Closed
bshea-1 wants to merge 1 commit into
librepods-org:mainfrom
bshea-1:fix/airpods-stability-and-case-sounds
Closed

Fix single-bud NPE crashes, BluetoothSocket reflection, and add rootless Charging Case Sounds#763
bshea-1 wants to merge 1 commit into
librepods-org:mainfrom
bshea-1:fix/airpods-stability-and-case-sounds

Conversation

@bshea-1

@bshea-1 bshea-1 commented Sep 3, 2026

Copy link
Copy Markdown

Summary of Changes

This PR resolves several background service crashes, improves Bluetooth socket reflection compatibility, optimizes notification resource usage, and adds rootless Charging Case Sounds toggle support.

1. Background Stability & Crash Prevention

  • Single-Bud Battery NPE: In AirPodsService, querying battery state when only one earbud is connected or before battery packets arrive caused multiple NullPointerException crashes on ?.level!!. Added a safe getDisplayBatteryLevel() helper to coalesce left and right bud levels safely.
  • Intent Extra Null Safety: Handled nullable intent.getParcelableExtra("device") without force unwraps (!!) and guarded device access.
  • Array Bounds Check: Added bounds check in onBatteryInfoReceived() before indexing battery status elements.

2. Bluetooth Connection Hardening

  • Socket File Descriptor: Fixed invalid fd = 1 parameter (STDOUT_FILENO) passed to reflected BluetoothSocket constructors (changed to -1 for uninitialized socket state).
  • Dynamic Constructor Fallback: Added dynamic constructor inspection fallback to match available constructor signatures across various Android vendor builds.
  • Early Hidden API Exemption: Loaded bluetooth_socket early in LibrePodsApplication.onCreate().

3. Battery & Notification Optimization

  • Removed high-frequency updateNotificationContent() calls from the tight raw socket packet read loop (while (socket.isConnected)), preventing SystemUI notification spam and reducing CPU wakeups.

4. Media Controller Typo Fix

  • Fixed MediaController conversational awareness default volume calculation from / 0.4 to * 0.4.

5. New Feature: Charging Case Sounds Toggle (Rootless)

  • Added Capability.CASE_SOUNDS for AirPods Pro 2 and AirPods 4 ANC.
  • Exposed a toggle under Connection Settings controlling IN_CASE_TONE_CONFIG (0x31 over AACP), allowing rootless control of case speaker chimes.

…e sounds toggle

- Fix KotlinNullPointerException on single-bud usage and uninitialized battery states in AirPodsService
- Fix BluetoothSocket reflection constructor with valid fd (-1) and add dynamic fallback resolver
- Add rootless Charging Case Sounds toggle for AirPods Pro 2 and AirPods 4 ANC via AACP
- Remove per-packet notification updates in raw socket read loop
- Fix default conversational awareness volume calculation in MediaController
- Add NativeBridge and ProGuard hardening for JNI bindings
- Update README with concise feature overview and patch documentation
@bshea-1

bshea-1 commented Sep 3, 2026

Copy link
Copy Markdown
Author

Closing PR for local modifications.

@bshea-1 bshea-1 closed this Sep 3, 2026
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