From 5819546ea9083359d389ad2df4c4f2199725762f Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Feb 2025 18:26:10 +0100 Subject: [PATCH] Have PlayerService implement MediaBrowserServiceCompat Co-authored-by: Haggai Eran --- app/src/main/AndroidManifest.xml | 8 +++ .../newpipe/player/PlayQueueActivity.java | 3 ++ .../schabi/newpipe/player/PlayerService.java | 49 +++++++++++++++++-- .../newpipe/player/helper/PlayerHolder.java | 1 + app/src/main/res/xml/automotive_app_desc.xml | 3 ++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/xml/automotive_app_desc.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d11de9f47..e52dded5e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,9 @@ + + + + + + diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index 195baecbd..f989a68d0 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -183,7 +183,10 @@ public final class PlayQueueActivity extends AppCompatActivity //////////////////////////////////////////////////////////////////////////// private void bind() { + // Note: this code should not really exist, and PlayerHolder should be used instead, but + // it will be rewritten when NewPlayer will replace the current player. final Intent bindIntent = new Intent(this, PlayerService.class); + bindIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); final boolean success = bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE); if (!success) { unbindService(serviceConnection); diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index 61eb3f733..7b9b76cfb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -21,28 +21,36 @@ package org.schabi.newpipe.player; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; -import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; +import android.support.v4.media.MediaBrowserCompat; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media.MediaBrowserServiceCompat; + import org.schabi.newpipe.ktx.BundleKt; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.notification.NotificationPlayerUi; import org.schabi.newpipe.util.ThemeHelper; import java.lang.ref.WeakReference; +import java.util.List; /** * One service for all players. */ -public final class PlayerService extends Service { +public final class PlayerService extends MediaBrowserServiceCompat { private static final String TAG = PlayerService.class.getSimpleName(); private static final boolean DEBUG = Player.DEBUG; + public static final String SHOULD_START_FOREGROUND_EXTRA = "should_start_foreground_extra"; + public static final String BIND_PLAYER_HOLDER_ACTION = "bind_player_holder_action"; private Player player; @@ -55,6 +63,8 @@ public final class PlayerService extends Service { @Override public void onCreate() { + super.onCreate(); + if (DEBUG) { Log.d(TAG, "onCreate() called"); } @@ -148,6 +158,7 @@ public final class PlayerService extends Service { if (DEBUG) { Log.d(TAG, "destroy() called"); } + super.onDestroy(); cleanup(); } @@ -170,7 +181,25 @@ public final class PlayerService extends Service { @Override public IBinder onBind(final Intent intent) { - return mBinder; + if (DEBUG) { + Log.d(TAG, "onBind() called with: intent = [" + intent + + "], extras = [" + BundleKt.toDebugString(intent.getExtras()) + "]"); + } + + if (BIND_PLAYER_HOLDER_ACTION.equals(intent.getAction())) { + // Note that this binder might be reused multiple times while the service is alive, even + // after unbind() has been called: https://stackoverflow.com/a/8794930 . + return mBinder; + + } else if (MediaBrowserServiceCompat.SERVICE_INTERFACE.equals(intent.getAction())) { + // MediaBrowserService also uses its own binder, so for actions related to the media + // browser service, pass the onBind to the superclass. + return super.onBind(intent); + + } else { + // This is an unknown request, avoid returning any binder to not leak objects. + return null; + } } public static class LocalBinder extends Binder { @@ -188,4 +217,18 @@ public final class PlayerService extends Service { return playerService.get().player; } } + + @Nullable + @Override + public BrowserRoot onGetRoot(@NonNull final String clientPackageName, + final int clientUid, + @Nullable final Bundle rootHints) { + return null; + } + + @Override + public void onLoadChildren(@NonNull final String parentId, + @NonNull final Result> result) { + + } } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 11b7379b3..30cdd5582 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -183,6 +183,7 @@ public final class PlayerHolder { } final Intent serviceIntent = new Intent(context, PlayerService.class); + serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); bound = context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); if (!bound) { diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml new file mode 100644 index 000000000..90e6f30ef --- /dev/null +++ b/app/src/main/res/xml/automotive_app_desc.xml @@ -0,0 +1,3 @@ + + +