Skip to content

fix: support Android 17 (getActiveSessionsForUser(ComponentName, int) was removed) - #293

Merged
Hepolise merged 2 commits into
Hepolise:mainfrom
Andy-Dunne:pr
Sep 14, 2026
Merged

Hepolise merged 2 commits into
Hepolise:mainfrom
Andy-Dunne:pr

Conversation

@Andy-Dunne

Copy link
Copy Markdown
Contributor

Problem

On Android 17 (SDK 37) the module stops switching tracks: every volume key event throws
java.lang.NoSuchMethodException for
android.media.session.MediaSessionManager.getActiveSessionsForUser [ComponentName, int].

Root cause

AOSP refactored MediaSessionManager:

  • the (ComponentName, int) overload this module called with UserHandle.USER_ALL is gone;
  • it was replaced by a private (ComponentName, int, String) overload returning Tokens,
    a @​SystemApi (ComponentName, UserHandle) overload, and a new getActiveSessionsForPackage().

Fix

Replace the single reflective call with a fallback chain:

  1. legacy getActiveSessionsForUser(ComponentName, int) with -1 -> unchanged behaviour on Android <= 16;
  2. getActiveSessionsForUser(ComponentName, UserHandle.ALL) -> Android 14+ overload, same "all users" intent;
  3. public getActiveSessions(null) -> API 21+, current user (system_server holds MEDIA_CONTENT_CONTROL).
    UserHandle.ALL is resolved reflectively because it is not part of the public SDK.

Compatibility / Testing

Tested on HyperOS 4 (Android 17, SDK 37), module scope = system:
long-press volume keys with screen off switches tracks as expected.

@Andy-Dunne
Andy-Dunne marked this pull request as ready for review September 13, 2026 14:53
@Hepolise

Copy link
Copy Markdown
Owner

A couple of small cleanup points before merging:

  1. Could you move the companion object to the top of the class? This is the structure I use throughout the project.

  2. About the logging in getActiveControllers():

The class introduces its own TAG and uses android.util.Log.e(...), but VolumeControlModule already has the shared TAG and logging mechanism. It also already passes the logger down to the helper classes (logger = ::log).

Could you please avoid introducing a separate logging mechanism here? If this error does not need to be logged, I'd prefer to just remove the Log.e(...). If the error is useful to have in the logs, please pass the existing logger into this class and use it instead.

At the very least, please don't duplicate the VolumeControl tag here — VolumeControlModule.TAG is already the shared tag.

The Android 17 compatibility fix itself looks good to me.

@Andy-Dunne

Andy-Dunne commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

I made the fix as you suggested:

  1. Moved the companion object to the top of the class (same structure as VolumeControlModule).
  2. Removed the separate logging: dropped the Log.e(...) call, the android.util.Log import and the duplicated "VolumeControl" TAG. Failure of all fallbacks now just returns null.

The only remaining companion member is USER_ALL = -1 (used twice for the reflective calls).

@Hepolise
Hepolise merged commit 874767d into Hepolise:main Sep 14, 2026
1 check passed
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