Skip to content

Commit 38ed1da

Browse files
ProfpatschStypox
authored andcommitted
PlayerHolder: use object class to implement singleton pattern
1 parent cc3ecd4 commit 38ed1da

7 files changed

Lines changed: 43 additions & 53 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ private void openMiniPlayerUponPlayerStarted() {
849849
return;
850850
}
851851

852-
if (PlayerHolder.Companion.getInstance().isPlayerOpen()) {
852+
if (PlayerHolder.INSTANCE.isPlayerOpen()) {
853853
// if the player is already open, no need for a broadcast receiver
854854
openMiniPlayerIfMissing();
855855
} else {
@@ -859,7 +859,7 @@ private void openMiniPlayerUponPlayerStarted() {
859859
public void onReceive(final Context context, final Intent intent) {
860860
if (Objects.equals(intent.getAction(),
861861
VideoDetailFragment.ACTION_PLAYER_STARTED)
862-
&& PlayerHolder.Companion.getInstance().isPlayerOpen()) {
862+
&& PlayerHolder.INSTANCE.isPlayerOpen()) {
863863
openMiniPlayerIfMissing();
864864
// At this point the player is added 100%, we can unregister. Other actions
865865
// are useless since the fragment will not be removed after that.
@@ -874,7 +874,7 @@ public void onReceive(final Context context, final Intent intent) {
874874

875875
// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
876876
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
877-
PlayerHolder.Companion.getInstance().tryBindIfNeeded(this);
877+
PlayerHolder.INSTANCE.tryBindIfNeeded(this);
878878
}
879879
}
880880

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ private boolean canHandleChoiceLikeShowInfo(final String selectedChoiceKey) {
701701
}
702702

703703
// ...the player is not running or in normal Video-mode/type
704-
final PlayerType playerType = PlayerHolder.Companion.getInstance().getType();
704+
final PlayerType playerType = PlayerHolder.INSTANCE.getType();
705705
return playerType == null || playerType == PlayerType.MAIN;
706706
}
707707

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.kt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ import org.schabi.newpipe.player.PlayerType
100100
import org.schabi.newpipe.player.event.OnKeyDownListener
101101
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener
102102
import org.schabi.newpipe.player.helper.PlayerHelper
103-
import org.schabi.newpipe.player.helper.PlayerHolder.Companion.getInstance
103+
import org.schabi.newpipe.player.helper.PlayerHolder
104104
import org.schabi.newpipe.player.playqueue.PlayQueue
105105
import org.schabi.newpipe.player.playqueue.SinglePlayQueue
106106
import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent
@@ -212,7 +212,6 @@ class VideoDetailFragment :
212212
private var settingsContentObserver: ContentObserver? = null
213213
private var playerService: PlayerService? = null
214214
private var player: Player? = null
215-
private val playerHolder = getInstance()
216215

217216
/*//////////////////////////////////////////////////////////////////////////
218217
// Service management
@@ -367,9 +366,9 @@ class VideoDetailFragment :
367366
// Stop the service when user leaves the app with double back press
368367
// if video player is selected. Otherwise unbind
369368
if (activity.isFinishing() && this.isPlayerAvailable && player!!.videoPlayerSelected()) {
370-
playerHolder.stopService()
369+
PlayerHolder.stopService()
371370
} else {
372-
playerHolder.setListener(null)
371+
PlayerHolder.setListener(null)
373372
}
374373

375374
PreferenceManager.getDefaultSharedPreferences(activity)
@@ -768,10 +767,10 @@ class VideoDetailFragment :
768767
)
769768

770769
setupBottomPlayer()
771-
if (!playerHolder.isBound) {
770+
if (!PlayerHolder.isBound) {
772771
setHeightThumbnail()
773772
} else {
774-
playerHolder.startService(false, this)
773+
PlayerHolder.startService(false, this)
775774
}
776775
}
777776

@@ -1175,7 +1174,7 @@ class VideoDetailFragment :
11751174

11761175
// See UI changes while remote playQueue changes
11771176
if (!this.isPlayerAvailable) {
1178-
playerHolder.startService(false, this)
1177+
PlayerHolder.startService(false, this)
11791178
} else {
11801179
// FIXME Workaround #7427
11811180
player!!.setRecovery()
@@ -1245,7 +1244,7 @@ class VideoDetailFragment :
12451244
private fun openNormalBackgroundPlayer(append: Boolean) {
12461245
// See UI changes while remote playQueue changes
12471246
if (!this.isPlayerAvailable) {
1248-
playerHolder.startService(false, this)
1247+
PlayerHolder.startService(false, this)
12491248
}
12501249

12511250
val queue = setupPlayQueueForIntent(append)
@@ -1263,7 +1262,7 @@ class VideoDetailFragment :
12631262

12641263
private fun openMainPlayer() {
12651264
if (noPlayerServiceAvailable()) {
1266-
playerHolder.startService(autoPlayEnabled, this)
1265+
PlayerHolder.startService(autoPlayEnabled, this)
12671266
return
12681267
}
12691268
if (currentInfo == null) {
@@ -1298,7 +1297,7 @@ class VideoDetailFragment :
12981297
playerService!!.stopForImmediateReusing()
12991298
root.ifPresent(Consumer { view: View -> view.setVisibility(View.GONE) })
13001299
} else {
1301-
playerHolder.stopService()
1300+
PlayerHolder.stopService()
13021301
}
13031302
}
13041303

@@ -1551,8 +1550,8 @@ class VideoDetailFragment :
15511550
bottomSheetBehavior!!.setState(BottomSheetBehavior.STATE_COLLAPSED)
15521551
}
15531552
// Rebound to the service if it was closed via notification or mini player
1554-
if (!playerHolder.isBound) {
1555-
playerHolder.startService(
1553+
if (!PlayerHolder.isBound) {
1554+
PlayerHolder.startService(
15561555
false, this@VideoDetailFragment
15571556
)
15581557
}
@@ -2472,7 +2471,7 @@ class VideoDetailFragment :
24722471
if (currentWorker != null) {
24732472
currentWorker!!.dispose()
24742473
}
2475-
playerHolder.stopService()
2474+
PlayerHolder.stopService()
24762475
setInitialData(0, null, "", null)
24772476
currentInfo = null
24782477
updateOverlayData(null, null, mutableListOf<Image>())

app/src/main/java/org/schabi/newpipe/info_list/dialog/InfoItemDialog.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public Builder setAction(@NonNull final StreamDialogDefaultEntry entry,
252252
* @return the current {@link Builder} instance
253253
*/
254254
public Builder addEnqueueEntriesIfNeeded() {
255-
final PlayerHolder holder = PlayerHolder.Companion.getInstance();
255+
final PlayerHolder holder = PlayerHolder.INSTANCE;
256256
if (holder.isPlayQueueReady()) {
257257
addEntry(StreamDialogDefaultEntry.ENQUEUE);
258258

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

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,19 @@ import org.schabi.newpipe.player.playqueue.PlayQueue
2222
import org.schabi.newpipe.util.NavigationHelper
2323
import java.util.function.Consumer
2424

25-
class PlayerHolder private constructor() {
25+
private val DEBUG = MainActivity.DEBUG
26+
private val TAG: String = PlayerHolder::class.java.getSimpleName()
27+
28+
/**
29+
* Singleton that manages a `PlayerService`
30+
* and can be used to control the player instance through the service.
31+
*/
32+
object PlayerHolder {
2633
private var listener: PlayerServiceExtendedEventListener? = null
2734

28-
private val serviceConnection = PlayerServiceConnection()
2935
var isBound: Boolean = false
3036
private set
37+
3138
private var playerService: PlayerService? = null
3239

3340
private val player: Player?
@@ -110,7 +117,7 @@ class PlayerHolder private constructor() {
110117
val intent = Intent(context, PlayerService::class.java)
111118
intent.putExtra(PlayerService.SHOULD_START_FOREGROUND_EXTRA, true)
112119
ContextCompat.startForegroundService(context, intent)
113-
serviceConnection.doPlayAfterConnect(playAfterConnect)
120+
PlayerServiceConnection.doPlayAfterConnect(playAfterConnect)
114121
bind(context)
115122
}
116123

@@ -126,7 +133,7 @@ class PlayerHolder private constructor() {
126133
context.stopService(Intent(context, PlayerService::class.java))
127134
}
128135

129-
internal inner class PlayerServiceConnection : ServiceConnection {
136+
internal object PlayerServiceConnection : ServiceConnection {
130137
internal var playAfterConnect = false
131138

132139
/**
@@ -185,7 +192,7 @@ class PlayerHolder private constructor() {
185192
// BIND_AUTO_CREATE starts the service if it's not already running
186193
this.isBound = bind(context, Context.BIND_AUTO_CREATE)
187194
if (!this.isBound) {
188-
context.unbindService(serviceConnection)
195+
context.unbindService(PlayerServiceConnection)
189196
}
190197
}
191198

@@ -201,7 +208,7 @@ class PlayerHolder private constructor() {
201208
private fun bind(context: Context, flags: Int): Boolean {
202209
val serviceIntent = Intent(context, PlayerService::class.java)
203210
serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION)
204-
return context.bindService(serviceIntent, serviceConnection, flags)
211+
return context.bindService(serviceIntent, PlayerServiceConnection, flags)
205212
}
206213

207214
private fun unbind(context: Context) {
@@ -210,7 +217,7 @@ class PlayerHolder private constructor() {
210217
}
211218

212219
if (this.isBound) {
213-
context.unbindService(serviceConnection)
220+
context.unbindService(PlayerServiceConnection)
214221
this.isBound = false
215222
stopPlayerListener()
216223
playerService = null
@@ -223,18 +230,18 @@ class PlayerHolder private constructor() {
223230
// setting the player listener will take care of calling relevant callbacks if the
224231
// player in the service is (not) already active, also see playerStateListener below
225232
playerService?.setPlayerListener(playerStateListener)
226-
this.player?.setFragmentListener(internalListener)
233+
this.player?.setFragmentListener(HolderPlayerServiceEventListener)
227234
}
228235

229236
private fun stopPlayerListener() {
230237
playerService?.setPlayerListener(null)
231-
this.player?.removeFragmentListener(internalListener)
238+
this.player?.removeFragmentListener(HolderPlayerServiceEventListener)
232239
}
233240

234241
/**
235242
* This listener will be held by the players created by [PlayerService].
236243
*/
237-
private val internalListener: PlayerServiceEventListener = object : PlayerServiceEventListener {
244+
private object HolderPlayerServiceEventListener : PlayerServiceEventListener {
238245
override fun onViewCreated() {
239246
listener?.onViewCreated()
240247
}
@@ -307,26 +314,11 @@ class PlayerHolder private constructor() {
307314
// before setting its player to null
308315
l.onPlayerDisconnected()
309316
} else {
310-
l.onPlayerConnected(player, serviceConnection.playAfterConnect)
317+
l.onPlayerConnected(player, PlayerServiceConnection.playAfterConnect)
311318
// reset the value of playAfterConnect: if it was true before, it is now "consumed"
312-
serviceConnection.playAfterConnect = false;
313-
player.setFragmentListener(internalListener)
319+
PlayerServiceConnection.playAfterConnect = false
320+
player.setFragmentListener(HolderPlayerServiceEventListener)
314321
}
315322
}
316323
}
317-
318-
companion object {
319-
private var instance: PlayerHolder? = null
320-
321-
@Synchronized
322-
fun getInstance(): PlayerHolder {
323-
if (instance == null) {
324-
instance = PlayerHolder()
325-
}
326-
return instance!!
327-
}
328-
329-
private val DEBUG = MainActivity.DEBUG
330-
private val TAG: String = PlayerHolder::class.java.getSimpleName()
331-
}
332324
}

app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamMenu.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ fun StreamMenu(
2828
) {
2929
val context = LocalContext.current
3030
val streamViewModel = viewModel<StreamViewModel>()
31-
val playerHolder = PlayerHolder.Companion.getInstance()
3231

3332
DropdownMenu(expanded = expanded, onDismissRequest = onDismissRequest) {
34-
if (playerHolder.isPlayQueueReady) {
33+
if (PlayerHolder.isPlayQueueReady) {
3534
DropdownMenuItem(
3635
text = { Text(text = stringResource(R.string.enqueue_stream)) },
3736
onClick = {
@@ -42,7 +41,7 @@ fun StreamMenu(
4241
}
4342
)
4443

45-
if (playerHolder.queuePosition < playerHolder.queueSize - 1) {
44+
if (PlayerHolder.queuePosition < PlayerHolder.queueSize - 1) {
4645
DropdownMenuItem(
4746
text = { Text(text = stringResource(R.string.enqueue_next_stream)) },
4847
onClick = {

app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public static void enqueueOnPlayer(final Context context,
200200
}
201201

202202
public static void enqueueOnPlayer(final Context context, final PlayQueue queue) {
203-
PlayerType playerType = PlayerHolder.Companion.getInstance().getType();
203+
PlayerType playerType = PlayerHolder.INSTANCE.getType();
204204
if (playerType == null) {
205205
Log.e(TAG, "Enqueueing but no player is open; defaulting to background player");
206206
playerType = PlayerType.AUDIO;
@@ -211,7 +211,7 @@ public static void enqueueOnPlayer(final Context context, final PlayQueue queue)
211211

212212
/* ENQUEUE NEXT */
213213
public static void enqueueNextOnPlayer(final Context context, final PlayQueue queue) {
214-
PlayerType playerType = PlayerHolder.Companion.getInstance().getType();
214+
PlayerType playerType = PlayerHolder.INSTANCE.getType();
215215
if (playerType == null) {
216216
Log.e(TAG, "Enqueueing next but no player is open; defaulting to background player");
217217
playerType = PlayerType.AUDIO;
@@ -421,13 +421,13 @@ public static void openVideoDetailFragment(@NonNull final Context context,
421421
final boolean switchingPlayers) {
422422

423423
final boolean autoPlay;
424-
@Nullable final PlayerType playerType = PlayerHolder.Companion.getInstance().getType();
424+
@Nullable final PlayerType playerType = PlayerHolder.INSTANCE.getType();
425425
if (playerType == null) {
426426
// no player open
427427
autoPlay = PlayerHelper.isAutoplayAllowedByUser(context);
428428
} else if (switchingPlayers) {
429429
// switching player to main player
430-
autoPlay = PlayerHolder.Companion.getInstance().isPlaying(); // keep play/pause state
430+
autoPlay = PlayerHolder.INSTANCE.isPlaying(); // keep play/pause state
431431
} else if (playerType == PlayerType.MAIN) {
432432
// opening new stream while already playing in main player
433433
autoPlay = PlayerHelper.isAutoplayAllowedByUser(context);

0 commit comments

Comments
 (0)