Skip to content

Commit 6558794

Browse files
committed
Try to bind to PlayerService when MainActivity starts
Fixes mini-player not appearing on app start if the player service is already playing something. The PlayerService (and the player) may be started from an external intent that does not involve the MainActivity (e.g. RouterActivity or Android Auto's media browser interface). This PR tries to bind to the PlayerService as soon as the MainActivity starts, but only does so in a passive way, i.e. if the service is not already running it is not started. Once the connection between PlayerHolder and PlayerService is setup, the ACTION_PLAYER_STARTED broadcast is sent to MainActivity so that it can setup the bottom mini-player. Another important thing this commit does is to check whether the player is open before actually adding the mini-player view, since the PlayerService could be bound even without a running player (e.g. Android Auto's media browser is being used). This is a consequence of commit "Drop some assumptions on how PlayerService is started and reused".
1 parent 1d98518 commit 6558794

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

app/src/main/java/org/schabi/newpipe/MainActivity.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,8 @@ private void openMiniPlayerUponPlayerStarted() {
848848
@Override
849849
public void onReceive(final Context context, final Intent intent) {
850850
if (Objects.equals(intent.getAction(),
851-
VideoDetailFragment.ACTION_PLAYER_STARTED)) {
851+
VideoDetailFragment.ACTION_PLAYER_STARTED)
852+
&& PlayerHolder.getInstance().isPlayerOpen()) {
852853
openMiniPlayerIfMissing();
853854
// At this point the player is added 100%, we can unregister. Other actions
854855
// are useless since the fragment will not be removed after that.
@@ -860,6 +861,10 @@ public void onReceive(final Context context, final Intent intent) {
860861
final IntentFilter intentFilter = new IntentFilter();
861862
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
862863
registerReceiver(broadcastReceiver, intentFilter);
864+
865+
// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
866+
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
867+
PlayerHolder.getInstance().tryBindIfNeeded(this);
863868
}
864869
}
865870

app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.schabi.newpipe.player.event.PlayerServiceEventListener;
2323
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
2424
import org.schabi.newpipe.player.playqueue.PlayQueue;
25+
import org.schabi.newpipe.util.NavigationHelper;
2526

2627
public final class PlayerHolder {
2728

@@ -121,6 +122,9 @@ private Context getCommonContext() {
121122

122123
public void startService(final boolean playAfterConnect,
123124
final PlayerServiceExtendedEventListener newListener) {
125+
if (DEBUG) {
126+
Log.d(TAG, "startService() called with playAfterConnect=" + playAfterConnect);
127+
}
124128
final Context context = getCommonContext();
125129
setListener(newListener);
126130
if (bound) {
@@ -182,23 +186,39 @@ public void onServiceConnected(final ComponentName compName, final IBinder servi
182186
listener.onServiceConnected(player, playerService, playAfterConnect);
183187
}
184188
startPlayerListener();
189+
190+
// notify the main activity that binding the service has completed, so that it can
191+
// open the bottom mini-player
192+
NavigationHelper.sendPlayerStartedEvent(localBinder.getService());
185193
}
186194
}
187195

188196
private void bind(final Context context) {
189197
if (DEBUG) {
190198
Log.d(TAG, "bind() called");
191199
}
192-
193-
final Intent serviceIntent = new Intent(context, PlayerService.class);
194-
serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION);
195-
bound = context.bindService(serviceIntent, serviceConnection,
196-
Context.BIND_AUTO_CREATE);
200+
// BIND_AUTO_CREATE starts the service if it's not already running
201+
bound = bind(context, Context.BIND_AUTO_CREATE);
197202
if (!bound) {
198203
context.unbindService(serviceConnection);
199204
}
200205
}
201206

207+
public void tryBindIfNeeded(final Context context) {
208+
if (!bound) {
209+
// flags=0 means the service will not be started if it does not already exist. In this
210+
// case the return value is not useful, as a value of "true" does not really indicate
211+
// that the service is going to be bound.
212+
bind(context, 0);
213+
}
214+
}
215+
216+
private boolean bind(final Context context, final int flags) {
217+
final Intent serviceIntent = new Intent(context, PlayerService.class);
218+
serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION);
219+
return context.bindService(serviceIntent, serviceConnection, flags);
220+
}
221+
202222
private void unbind(final Context context) {
203223
if (DEBUG) {
204224
Log.d(TAG, "unbind() called");

0 commit comments

Comments
 (0)