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 @@
+
+
+