Skip to content

Commit d157609

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 8786d82 commit d157609

3 files changed

Lines changed: 71 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
}
@@ -124,6 +136,7 @@ public void onDestroy() {
124136
mediaBrowserConnector.release();
125137
mediaBrowserConnector = null;
126138
}
139+
compositeDisposableLoadChildren.clear();
127140
}
128141

129142
private void cleanup() {
@@ -145,6 +158,9 @@ protected void attachBaseContext(final Context base) {
145158

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

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

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

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

3+
import android.os.Bundle;
4+
import android.support.v4.media.MediaBrowserCompat;
5+
import android.support.v4.media.MediaBrowserCompat.MediaItem;
36
import android.support.v4.media.session.MediaSessionCompat;
7+
import android.util.Log;
48

59
import androidx.annotation.NonNull;
10+
import androidx.annotation.Nullable;
11+
import androidx.media.MediaBrowserServiceCompat;
612

713
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
814

915
import org.schabi.newpipe.player.PlayerService;
1016

17+
import java.util.ArrayList;
18+
import java.util.List;
19+
20+
import io.reactivex.rxjava3.core.Single;
21+
1122
public class MediaBrowserConnector {
1223
private static final String TAG = MediaBrowserConnector.class.getSimpleName();
1324

@@ -20,6 +31,7 @@ public MediaBrowserConnector(@NonNull final PlayerService playerService) {
2031
mediaSession = new MediaSessionCompat(playerService, TAG);
2132
sessionConnector = new MediaSessionConnector(mediaSession);
2233
sessionConnector.setMetadataDeduplicationEnabled(true);
34+
playerService.setSessionToken(mediaSession.getSessionToken());
2335
}
2436

2537
public @NonNull MediaSessionConnector getSessionConnector() {
@@ -29,4 +41,25 @@ public MediaBrowserConnector(@NonNull final PlayerService playerService) {
2941
public void release() {
3042
mediaSession.release();
3143
}
44+
45+
@NonNull
46+
private static final String MY_MEDIA_ROOT_ID = "media_root_id";
47+
48+
@Nullable
49+
public MediaBrowserServiceCompat.BrowserRoot onGetRoot(@NonNull final String clientPackageName,
50+
final int clientUid,
51+
@Nullable final Bundle rootHints) {
52+
Log.d(TAG, String.format("MediaBrowserService.onGetRoot(%s, %s, %s)",
53+
clientPackageName, clientUid, rootHints));
54+
55+
return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
56+
}
57+
58+
public Single<List<MediaItem>> onLoadChildren(@NonNull final String parentId) {
59+
Log.d(TAG, String.format("MediaBrowserService.onLoadChildren(%s)", parentId));
60+
61+
final List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
62+
63+
return Single.just(mediaItems);
64+
}
3265
}

0 commit comments

Comments
 (0)