Skip to content

Commit 1bb242e

Browse files
committed
Simple playback status and controls in Android Auto
Expose a MediaBrowserService from within the existing PlayerService, and use the existing MediaSession for Auto. Empty media browser for now. To test, one needs to enable "Unknown sources" in Android Auto's developer settings. Issue: #1758
1 parent 1a4f971 commit 1bb242e

3 files changed

Lines changed: 77 additions & 2 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
<intent-filter>
6565
<action android:name="android.intent.action.MEDIA_BUTTON" />
6666
</intent-filter>
67+
<intent-filter>
68+
<action android:name="android.media.browse.MediaBrowserService"/>
69+
</intent-filter>
6770
</service>
6871

6972
<activity

app/src/main/java/org/schabi/newpipe/player/PlayerService.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,37 +21,49 @@
2121

2222
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
2323

24-
import android.app.Service;
2524
import android.content.Context;
2625
import android.content.Intent;
2726
import android.os.Binder;
27+
import android.os.Bundle;
2828
import android.os.IBinder;
29+
import android.support.v4.media.MediaBrowserCompat.MediaItem;
2930
import android.util.Log;
3031

32+
import androidx.annotation.NonNull;
33+
import androidx.annotation.Nullable;
34+
import androidx.media.MediaBrowserServiceCompat;
35+
3136
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
3237

3338
import org.schabi.newpipe.player.mediabrowser.MediaBrowserConnector;
3439
import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi;
3540
import org.schabi.newpipe.util.ThemeHelper;
3641

42+
import java.util.List;
43+
44+
import io.reactivex.rxjava3.disposables.CompositeDisposable;
45+
3746
/**
3847
* One service for all players.
3948
*/
40-
public final class PlayerService extends Service {
49+
public final class PlayerService extends MediaBrowserServiceCompat {
4150
private static final String TAG = PlayerService.class.getSimpleName();
4251
private static final boolean DEBUG = Player.DEBUG;
4352

4453
private Player player;
4554

4655
private final IBinder mBinder = new LocalBinder();
4756
private MediaBrowserConnector mediaBrowserConnector;
57+
private final CompositeDisposable compositeDisposableLoadChildren = new CompositeDisposable();
4858

4959
/*//////////////////////////////////////////////////////////////////////////
5060
// Service's LifeCycle
5161
//////////////////////////////////////////////////////////////////////////*/
5262

5363
@Override
5464
public void onCreate() {
65+
super.onCreate();
66+
5567
if (DEBUG) {
5668
Log.d(TAG, "onCreate() called");
5769
}
@@ -123,6 +135,7 @@ public void onDestroy() {
123135
mediaBrowserConnector.release();
124136
mediaBrowserConnector = null;
125137
}
138+
compositeDisposableLoadChildren.clear();
126139
}
127140

128141
private void cleanup() {
@@ -144,6 +157,9 @@ protected void attachBaseContext(final Context base) {
144157

145158
@Override
146159
public IBinder onBind(final Intent intent) {
160+
if (SERVICE_INTERFACE.equals(intent.getAction())) {
161+
return super.onBind(intent);
162+
}
147163
return mBinder;
148164
}
149165

@@ -161,4 +177,21 @@ public Player getPlayer() {
161177
return PlayerService.this.player;
162178
}
163179
}
180+
181+
// MediaBrowserServiceCompat methods
182+
@Nullable
183+
@Override
184+
public BrowserRoot onGetRoot(@NonNull final String clientPackageName, final int clientUid,
185+
@Nullable final Bundle rootHints) {
186+
return mediaBrowserConnector.onGetRoot(clientPackageName, clientUid, rootHints);
187+
}
188+
189+
@Override
190+
public void onLoadChildren(@NonNull final String parentId,
191+
@NonNull final Result<List<MediaItem>> result) {
192+
result.detach();
193+
final var disposable = mediaBrowserConnector.onLoadChildren(parentId)
194+
.subscribe(result::sendResult);
195+
compositeDisposableLoadChildren.add(disposable);
196+
}
164197
}

app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserConnector.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
package org.schabi.newpipe.player.mediabrowser;
22

3+
import static org.schabi.newpipe.MainActivity.DEBUG;
4+
5+
import android.os.Bundle;
6+
import android.support.v4.media.MediaBrowserCompat;
7+
import android.support.v4.media.MediaBrowserCompat.MediaItem;
38
import android.support.v4.media.session.MediaSessionCompat;
9+
import android.util.Log;
410

511
import androidx.annotation.NonNull;
12+
import androidx.annotation.Nullable;
13+
import androidx.media.MediaBrowserServiceCompat;
614

715
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
816

917
import org.schabi.newpipe.player.PlayerService;
1018

19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import io.reactivex.rxjava3.core.Single;
23+
1124
public class MediaBrowserConnector {
1225
private static final String TAG = MediaBrowserConnector.class.getSimpleName();
1326

@@ -20,6 +33,7 @@ public MediaBrowserConnector(@NonNull final PlayerService playerService) {
2033
mediaSession = new MediaSessionCompat(playerService, TAG);
2134
sessionConnector = new MediaSessionConnector(mediaSession);
2235
sessionConnector.setMetadataDeduplicationEnabled(true);
36+
playerService.setSessionToken(mediaSession.getSessionToken());
2337
}
2438

2539
public @NonNull MediaSessionConnector getSessionConnector() {
@@ -29,4 +43,29 @@ public MediaBrowserConnector(@NonNull final PlayerService playerService) {
2943
public void release() {
3044
mediaSession.release();
3145
}
46+
47+
@NonNull
48+
private static final String MY_MEDIA_ROOT_ID = "media_root_id";
49+
50+
@Nullable
51+
public MediaBrowserServiceCompat.BrowserRoot onGetRoot(@NonNull final String clientPackageName,
52+
final int clientUid,
53+
@Nullable final Bundle rootHints) {
54+
if (DEBUG) {
55+
Log.d(TAG, String.format("MediaBrowserService.onGetRoot(%s, %s, %s)",
56+
clientPackageName, clientUid, rootHints));
57+
}
58+
59+
return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
60+
}
61+
62+
public Single<List<MediaItem>> onLoadChildren(@NonNull final String parentId) {
63+
if (DEBUG) {
64+
Log.d(TAG, String.format("MediaBrowserService.onLoadChildren(%s)", parentId));
65+
}
66+
67+
final List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
68+
69+
return Single.just(mediaItems);
70+
}
3271
}

0 commit comments

Comments
 (0)