Skip to content

Commit 4dd64f6

Browse files
committed
PlayerHolder: use object class to implement singleton pattern
1 parent 9a6b21c commit 4dd64f6

7 files changed

Lines changed: 42 additions & 52 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
@@ -833,7 +833,7 @@ private void openMiniPlayerUponPlayerStarted() {
833833
return;
834834
}
835835

836-
if (PlayerHolder.Companion.getInstance().isPlayerOpen()) {
836+
if (PlayerHolder.INSTANCE.isPlayerOpen()) {
837837
// if the player is already open, no need for a broadcast receiver
838838
openMiniPlayerIfMissing();
839839
} else {
@@ -843,7 +843,7 @@ private void openMiniPlayerUponPlayerStarted() {
843843
public void onReceive(final Context context, final Intent intent) {
844844
if (Objects.equals(intent.getAction(),
845845
VideoDetailFragment.ACTION_PLAYER_STARTED)
846-
&& PlayerHolder.Companion.getInstance().isPlayerOpen()) {
846+
&& PlayerHolder.INSTANCE.isPlayerOpen()) {
847847
openMiniPlayerIfMissing();
848848
// At this point the player is added 100%, we can unregister. Other actions
849849
// are useless since the fragment will not be removed after that.
@@ -858,7 +858,7 @@ public void onReceive(final Context context, final Intent intent) {
858858

859859
// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
860860
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
861-
PlayerHolder.Companion.getInstance().tryBindIfNeeded(this);
861+
PlayerHolder.INSTANCE.tryBindIfNeeded(this);
862862
}
863863
}
864864

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

@@ -1177,7 +1176,7 @@ class VideoDetailFragment :
11771176

11781177
// See UI changes while remote playQueue changes
11791178
if (!this.isPlayerAvailable) {
1180-
playerHolder.startService(false, this)
1179+
PlayerHolder.startService(false, this)
11811180
} else {
11821181
// FIXME Workaround #7427
11831182
player!!.setRecovery()
@@ -1247,7 +1246,7 @@ class VideoDetailFragment :
12471246
private fun openNormalBackgroundPlayer(append: Boolean) {
12481247
// See UI changes while remote playQueue changes
12491248
if (!this.isPlayerAvailable) {
1250-
playerHolder.startService(false, this)
1249+
PlayerHolder.startService(false, this)
12511250
}
12521251

12531252
val queue = setupPlayQueueForIntent(append)
@@ -1265,7 +1264,7 @@ class VideoDetailFragment :
12651264

12661265
private fun openMainPlayer() {
12671266
if (noPlayerServiceAvailable()) {
1268-
playerHolder.startService(autoPlayEnabled, this)
1267+
PlayerHolder.startService(autoPlayEnabled, this)
12691268
return
12701269
}
12711270
if (currentInfo == null) {
@@ -1300,7 +1299,7 @@ class VideoDetailFragment :
13001299
playerService!!.stopForImmediateReusing()
13011300
root.ifPresent(Consumer { view: View -> view.setVisibility(View.GONE) })
13021301
} else {
1303-
playerHolder.stopService()
1302+
PlayerHolder.stopService()
13041303
}
13051304
}
13061305

@@ -1553,8 +1552,8 @@ class VideoDetailFragment :
15531552
bottomSheetBehavior!!.setState(BottomSheetBehavior.STATE_COLLAPSED)
15541553
}
15551554
// Rebound to the service if it was closed via notification or mini player
1556-
if (!playerHolder.isBound) {
1557-
playerHolder.startService(
1555+
if (!PlayerHolder.isBound) {
1556+
PlayerHolder.startService(
15581557
false, this@VideoDetailFragment
15591558
)
15601559
}
@@ -2474,7 +2473,7 @@ class VideoDetailFragment :
24742473
if (currentWorker != null) {
24752474
currentWorker!!.dispose()
24762475
}
2477-
playerHolder.stopService()
2476+
PlayerHolder.stopService()
24782477
setInitialData(0, null, "", null)
24792478
currentInfo = null
24802479
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: 19 additions & 27 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
fun doPlayAfterConnect(playAfterConnection: Boolean) {
@@ -180,7 +187,7 @@ class PlayerHolder private constructor() {
180187
// BIND_AUTO_CREATE starts the service if it's not already running
181188
this.isBound = bind(context, Context.BIND_AUTO_CREATE)
182189
if (!this.isBound) {
183-
context.unbindService(serviceConnection)
190+
context.unbindService(PlayerServiceConnection)
184191
}
185192
}
186193

@@ -196,7 +203,7 @@ class PlayerHolder private constructor() {
196203
private fun bind(context: Context, flags: Int): Boolean {
197204
val serviceIntent = Intent(context, PlayerService::class.java)
198205
serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION)
199-
return context.bindService(serviceIntent, serviceConnection, flags)
206+
return context.bindService(serviceIntent, PlayerServiceConnection, flags)
200207
}
201208

202209
private fun unbind(context: Context) {
@@ -205,7 +212,7 @@ class PlayerHolder private constructor() {
205212
}
206213

207214
if (this.isBound) {
208-
context.unbindService(serviceConnection)
215+
context.unbindService(PlayerServiceConnection)
209216
this.isBound = false
210217
stopPlayerListener()
211218
playerService = null
@@ -218,18 +225,18 @@ class PlayerHolder private constructor() {
218225
// setting the player listener will take care of calling relevant callbacks if the
219226
// player in the service is (not) already active, also see playerStateListener below
220227
playerService?.setPlayerListener(playerStateListener)
221-
this.player?.setFragmentListener(internalListener)
228+
this.player?.setFragmentListener(HolderPlayerServiceEventListener)
222229
}
223230

224231
private fun stopPlayerListener() {
225232
playerService?.setPlayerListener(null)
226-
this.player?.removeFragmentListener(internalListener)
233+
this.player?.removeFragmentListener(HolderPlayerServiceEventListener)
227234
}
228235

229236
/**
230237
* This listener will be held by the players created by [PlayerService].
231238
*/
232-
private val internalListener: PlayerServiceEventListener = object : PlayerServiceEventListener {
239+
private object HolderPlayerServiceEventListener : PlayerServiceEventListener {
233240
override fun onViewCreated() {
234241
listener?.onViewCreated()
235242
}
@@ -302,24 +309,9 @@ class PlayerHolder private constructor() {
302309
// before setting its player to null
303310
l.onPlayerDisconnected()
304311
} else {
305-
l.onPlayerConnected(player, serviceConnection.playAfterConnect)
306-
player.setFragmentListener(internalListener)
312+
l.onPlayerConnected(player, PlayerServiceConnection.playAfterConnect)
313+
player.setFragmentListener(HolderPlayerServiceEventListener)
307314
}
308315
}
309316
}
310-
311-
companion object {
312-
private var instance: PlayerHolder? = null
313-
314-
@Synchronized
315-
fun getInstance(): PlayerHolder {
316-
if (instance == null) {
317-
instance = PlayerHolder()
318-
}
319-
return instance!!
320-
}
321-
322-
private val DEBUG = MainActivity.DEBUG
323-
private val TAG: String = PlayerHolder::class.java.getSimpleName()
324-
}
325317
}

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)