From f90b813374cd941ce20569ed5f7f424b6d84c928 Mon Sep 17 00:00:00 2001 From: ezio84 Date: Sun, 8 Nov 2020 09:32:34 +0100 Subject: [PATCH] LineageButtons: Add support for skipping tracks with remote control For Spotify and other players that allow music controls for remote devices (PC, PS4) through the media notification Change-Id: I38887f8b1cff1a0c1e3adadbfe37d5af59b5cdcc --- .../internal/buttons/LineageButtons.java | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/sdk/src/java/org/lineageos/internal/buttons/LineageButtons.java b/sdk/src/java/org/lineageos/internal/buttons/LineageButtons.java index 70c5657c..1b006e7d 100644 --- a/sdk/src/java/org/lineageos/internal/buttons/LineageButtons.java +++ b/sdk/src/java/org/lineageos/internal/buttons/LineageButtons.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2017 The LineageOS Project + * Copyright (C) 2018,2020 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,10 @@ import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; import android.media.AudioManager; +import android.media.session.MediaController; import android.media.session.MediaSessionLegacyHelper; +import android.media.session.MediaSessionManager; +import android.media.session.PlaybackState; import android.os.Handler; import android.os.Message; import android.os.UserHandle; @@ -31,6 +34,8 @@ import android.view.ViewConfiguration; import lineageos.providers.LineageSettings; +import java.util.List; + public final class LineageButtons { private final String TAG = "LineageButtons"; private final boolean DEBUG = false; @@ -38,7 +43,8 @@ public final class LineageButtons { private static final int MSG_DISPATCH_VOLKEY_WITH_WAKELOCK = 1; private final Context mContext; - private ButtonHandler mHandler; + private final ButtonHandler mHandler; + private final MediaSessionManager mMediaSessionManager; private boolean mIsLongPress = false; @@ -54,8 +60,7 @@ public final class LineageButtons { if (DEBUG) { Slog.d(TAG, "Dispatching key to audio service"); } - dispatchMediaKeyToAudioService(ev); - dispatchMediaKeyToAudioService(KeyEvent.changeAction(ev, KeyEvent.ACTION_UP)); + onSkipTrackEvent(ev); break; } } @@ -64,6 +69,7 @@ public final class LineageButtons { public LineageButtons(Context context) { mContext = context; mHandler = new ButtonHandler(); + mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); SettingsObserver observer = new SettingsObserver(new Handler()); observer.observe(); @@ -129,11 +135,34 @@ public final class LineageButtons { return true; } - void dispatchMediaKeyToAudioService(KeyEvent ev) { - if (DEBUG) { - Slog.d(TAG, "Dispatching KeyEvent " + ev + " to audio service"); + private void triggerKeyEvents(KeyEvent evDown, MediaController controller) { + final KeyEvent evUp = KeyEvent.changeAction(evDown, KeyEvent.ACTION_UP); + mHandler.post(() -> controller.dispatchMediaButtonEvent(evDown)); + mHandler.postDelayed(() -> controller.dispatchMediaButtonEvent(evUp), 20); + } + + public void onSkipTrackEvent(KeyEvent ev) { + if (mMediaSessionManager != null) { + final List sessions = mMediaSessionManager.getActiveSessionsForUser( + null, UserHandle.USER_ALL); + for (MediaController mediaController : sessions) { + if (PlaybackState.STATE_PLAYING == + getMediaControllerPlaybackState(mediaController)) { + triggerKeyEvents(ev, mediaController); + break; + } + } } - MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(ev, true); + } + + private int getMediaControllerPlaybackState(MediaController controller) { + if (controller != null) { + final PlaybackState playbackState = controller.getPlaybackState(); + if (playbackState != null) { + return playbackState.getState(); + } + } + return PlaybackState.STATE_NONE; } class SettingsObserver extends ContentObserver {