2424import androidx .annotation .DrawableRes ;
2525import androidx .annotation .NonNull ;
2626import androidx .annotation .Nullable ;
27+ import androidx .annotation .StringRes ;
2728import androidx .appcompat .app .AlertDialog ;
2829import androidx .appcompat .app .AppCompatActivity ;
2930import androidx .appcompat .content .res .AppCompatResources ;
@@ -259,68 +260,110 @@ private void showUnsupportedUrlDialog(final String url) {
259260 protected void onSuccess () {
260261 final SharedPreferences preferences = PreferenceManager
261262 .getDefaultSharedPreferences (this );
262- final String selectedChoiceKey = preferences
263- .getString (getString (R .string .preferred_open_action_key ),
264- getString (R .string .preferred_open_action_default ));
265263
266- final String showInfoKey = getString (R .string .show_info_key );
264+ final ChoiceAvailabilityChecker choiceChecker = new ChoiceAvailabilityChecker (
265+ getChoicesForService (currentService , currentLinkType ),
266+ preferences .getString (getString (R .string .preferred_open_action_key ),
267+ getString (R .string .preferred_open_action_default )));
268+
269+ // Check for non-player related choices
270+ if (choiceChecker .isAvailableAndSelected (
271+ R .string .show_info_key ,
272+ R .string .download_key ,
273+ R .string .add_to_playlist_key )) {
274+ handleChoice (choiceChecker .getSelectedChoiceKey ());
275+ return ;
276+ }
277+ // Check if the choice is player related
278+ if (choiceChecker .isAvailableAndSelected (
279+ R .string .video_player_key ,
280+ R .string .background_player_key ,
281+ R .string .popup_player_key )) {
267282
268- if (selectedChoiceKey .equals (getString (R .string .always_ask_open_action_key ))) {
269- final List <AdapterChoiceItem > choices =
270- getChoicesForService (currentService , currentLinkType );
283+ final String selectedChoice = choiceChecker .getSelectedChoiceKey ();
271284
272- switch (choices .size ()) {
273- case 1 :
274- handleChoice (choices .get (0 ).key );
275- break ;
276- case 0 :
277- handleChoice (showInfoKey );
278- break ;
279- default :
280- showDialog (choices );
281- break ;
282- }
283- } else if (selectedChoiceKey .equals (showInfoKey )
284- || selectedChoiceKey .equals (getString (R .string .download_key ))
285- || selectedChoiceKey .equals (getString (R .string .add_to_playlist_key ))
286- ) {
287- handleChoice (selectedChoiceKey );
288- } else {
289285 final boolean isExtVideoEnabled = preferences .getBoolean (
290286 getString (R .string .use_external_video_player_key ), false );
291287 final boolean isExtAudioEnabled = preferences .getBoolean (
292288 getString (R .string .use_external_audio_player_key ), false );
293289 final boolean isVideoPlayerSelected =
294- selectedChoiceKey .equals (getString (R .string .video_player_key ))
295- || selectedChoiceKey .equals (getString (R .string .popup_player_key ));
290+ selectedChoice .equals (getString (R .string .video_player_key ))
291+ || selectedChoice .equals (getString (R .string .popup_player_key ));
296292 final boolean isAudioPlayerSelected =
297- selectedChoiceKey .equals (getString (R .string .background_player_key ));
293+ selectedChoice .equals (getString (R .string .background_player_key ));
298294
299295 if (currentLinkType != LinkType .STREAM
300296 && (isExtAudioEnabled && isAudioPlayerSelected
301297 || isExtVideoEnabled && isVideoPlayerSelected )
302298 ) {
303299 Toast .makeText (this , R .string .external_player_unsupported_link_type ,
304300 Toast .LENGTH_LONG ).show ();
305- handleChoice (showInfoKey );
301+ handleChoice (getString ( R . string . show_info_key ) );
306302 return ;
307303 }
308304
309305 final List <StreamingService .ServiceInfo .MediaCapability > capabilities =
310306 currentService .getServiceInfo ().getMediaCapabilities ();
311307
312- boolean serviceSupportsChoice = false ;
313- if (isVideoPlayerSelected ) {
314- serviceSupportsChoice = capabilities .contains (VIDEO );
315- } else if (isAudioPlayerSelected ) {
316- serviceSupportsChoice = capabilities .contains (AUDIO );
308+ // Check if the service supports the choice
309+ if (isVideoPlayerSelected && capabilities .contains (VIDEO )
310+ || isAudioPlayerSelected && capabilities .contains (AUDIO )) {
311+ handleChoice (selectedChoice );
312+ } else {
313+ handleChoice (getString (R .string .show_info_key ));
317314 }
315+ return ;
316+ }
318317
319- if (serviceSupportsChoice ) {
320- handleChoice (selectedChoiceKey );
321- } else {
322- handleChoice (showInfoKey );
318+ // Default / Ask always
319+ final List <AdapterChoiceItem > availableChoices = choiceChecker .getAvailableChoices ();
320+ switch (availableChoices .size ()) {
321+ case 1 :
322+ handleChoice (availableChoices .get (0 ).key );
323+ break ;
324+ case 0 :
325+ handleChoice (getString (R .string .show_info_key ));
326+ break ;
327+ default :
328+ showDialog (availableChoices );
329+ break ;
330+ }
331+ }
332+
333+ /**
334+ * This is a helper class for checking if the choices are available and/or selected.
335+ */
336+ class ChoiceAvailabilityChecker {
337+ private final List <AdapterChoiceItem > availableChoices ;
338+ private final String selectedChoiceKey ;
339+
340+ ChoiceAvailabilityChecker (
341+ @ NonNull final List <AdapterChoiceItem > availableChoices ,
342+ @ NonNull final String selectedChoiceKey ) {
343+ this .availableChoices = availableChoices ;
344+ this .selectedChoiceKey = selectedChoiceKey ;
345+ }
346+
347+ public List <AdapterChoiceItem > getAvailableChoices () {
348+ return availableChoices ;
349+ }
350+
351+ public String getSelectedChoiceKey () {
352+ return selectedChoiceKey ;
353+ }
354+
355+ public boolean isAvailableAndSelected (@ StringRes final int ... wantedKeys ) {
356+ return Arrays .stream (wantedKeys ).anyMatch (this ::isAvailableAndSelected );
357+ }
358+
359+ public boolean isAvailableAndSelected (@ StringRes final int wantedKey ) {
360+ final String wanted = getString (wantedKey );
361+ // Check if the wanted option is selected
362+ if (!selectedChoiceKey .equals (wanted )) {
363+ return false ;
323364 }
365+ // Check if it's available
366+ return availableChoices .stream ().anyMatch (item -> wanted .equals (item .key ));
324367 }
325368 }
326369
@@ -425,87 +468,61 @@ private void showDialog(final List<AdapterChoiceItem> choices) {
425468
426469 private List <AdapterChoiceItem > getChoicesForService (final StreamingService service ,
427470 final LinkType linkType ) {
428- final Context context = getThemeWrapperContext ();
429-
430- final List <AdapterChoiceItem > returnList = new ArrayList <>();
431- final List <StreamingService .ServiceInfo .MediaCapability > capabilities
432- = service .getServiceInfo ().getMediaCapabilities ();
433-
434- final SharedPreferences preferences = PreferenceManager
435- .getDefaultSharedPreferences (this );
436- final boolean isExtVideoEnabled = preferences .getBoolean (
437- getString (R .string .use_external_video_player_key ), false );
438- final boolean isExtAudioEnabled = preferences .getBoolean (
439- getString (R .string .use_external_audio_player_key ), false );
440-
441- final AdapterChoiceItem videoPlayer = new AdapterChoiceItem (
442- getString (R .string .video_player_key ), getString (R .string .video_player ),
443- R .drawable .ic_play_arrow );
444471 final AdapterChoiceItem showInfo = new AdapterChoiceItem (
445472 getString (R .string .show_info_key ), getString (R .string .show_info ),
446473 R .drawable .ic_info_outline );
447- final AdapterChoiceItem popupPlayer = new AdapterChoiceItem (
448- getString (R .string .popup_player_key ), getString (R .string .popup_player ),
449- R .drawable .ic_picture_in_picture );
474+ final AdapterChoiceItem videoPlayer = new AdapterChoiceItem (
475+ getString (R .string .video_player_key ), getString (R .string .video_player ),
476+ R .drawable .ic_play_arrow );
450477 final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem (
451478 getString (R .string .background_player_key ), getString (R .string .background_player ),
452479 R .drawable .ic_headset );
453- final AdapterChoiceItem addToPlaylist = new AdapterChoiceItem (
454- getString (R .string .add_to_playlist_key ), getString (R .string .add_to_playlist ),
455- R .drawable .ic_add );
480+ final AdapterChoiceItem popupPlayer = new AdapterChoiceItem (
481+ getString (R .string .popup_player_key ), getString (R .string .popup_player ),
482+ R .drawable .ic_picture_in_picture );
456483
484+ final List <AdapterChoiceItem > returnedItems = new ArrayList <>();
485+ returnedItems .add (showInfo ); // Always present
486+ final List <StreamingService .ServiceInfo .MediaCapability > capabilities =
487+ service .getServiceInfo ().getMediaCapabilities ();
457488
458489 if (linkType == LinkType .STREAM ) {
459- if (isExtVideoEnabled ) {
460- // show both "show info" and "video player", they are two different activities
461- returnList .add (showInfo );
462- returnList .add (videoPlayer );
463- } else {
464- final MainPlayer .PlayerType playerType = PlayerHolder .getInstance ().getType ();
465- if (capabilities .contains (VIDEO )
466- && PlayerHelper .isAutoplayAllowedByUser (context )
467- && playerType == null || playerType == MainPlayer .PlayerType .VIDEO ) {
468- // show only "video player" since the details activity will be opened and the
469- // video will be auto played there. Since "show info" would do the exact same
470- // thing, use that as a key to let VideoDetailFragment load the stream instead
471- // of using FetcherService (see comment in handleChoice())
472- returnList .add (new AdapterChoiceItem (
473- showInfo .key , videoPlayer .description , videoPlayer .icon ));
474- } else {
475- // show only "show info" if video player is not applicable, auto play is
476- // disabled or a video is playing in a player different than the main one
477- returnList .add (showInfo );
478- }
479- }
480-
481490 if (capabilities .contains (VIDEO )) {
482- returnList .add (popupPlayer );
491+ returnedItems .add (videoPlayer );
492+ returnedItems .add (popupPlayer );
483493 }
484494 if (capabilities .contains (AUDIO )) {
485- returnList .add (backgroundPlayer );
495+ returnedItems .add (backgroundPlayer );
486496 }
487497 // download is redundant for linkType CHANNEL AND PLAYLIST (till playlist downloading is
488498 // not supported )
489- returnList .add (new AdapterChoiceItem (getString (R .string .download_key ),
499+ returnedItems .add (new AdapterChoiceItem (getString (R .string .download_key ),
490500 getString (R .string .download ),
491501 R .drawable .ic_file_download ));
492502
493503 // Add to playlist is not necessary for CHANNEL and PLAYLIST linkType since those can
494504 // not be added to a playlist
495- returnList .add (addToPlaylist );
496-
505+ returnedItems .add (new AdapterChoiceItem (getString (R .string .add_to_playlist_key ),
506+ getString (R .string .add_to_playlist ),
507+ R .drawable .ic_add ));
497508 } else {
498- returnList .add (showInfo );
509+ final SharedPreferences preferences = PreferenceManager
510+ .getDefaultSharedPreferences (this );
511+ final boolean isExtVideoEnabled = preferences .getBoolean (
512+ getString (R .string .use_external_video_player_key ), false );
513+ final boolean isExtAudioEnabled = preferences .getBoolean (
514+ getString (R .string .use_external_audio_player_key ), false );
515+
499516 if (capabilities .contains (VIDEO ) && !isExtVideoEnabled ) {
500- returnList .add (videoPlayer );
501- returnList .add (popupPlayer );
517+ returnedItems .add (videoPlayer );
518+ returnedItems .add (popupPlayer );
502519 }
503520 if (capabilities .contains (AUDIO ) && !isExtAudioEnabled ) {
504- returnList .add (backgroundPlayer );
521+ returnedItems .add (backgroundPlayer );
505522 }
506523 }
507524
508- return returnList ;
525+ return returnedItems ;
509526 }
510527
511528 private Context getThemeWrapperContext () {
@@ -567,7 +584,8 @@ private void handleChoice(final String selectedChoiceKey) {
567584
568585 // stop and bypass FetcherService if InfoScreen was selected since
569586 // StreamDetailFragment can fetch data itself
570- if (selectedChoiceKey .equals (getString (R .string .show_info_key ))) {
587+ if (selectedChoiceKey .equals (getString (R .string .show_info_key ))
588+ || canHandleChoiceLikeShowInfo (selectedChoiceKey )) {
571589 disposables .add (Observable
572590 .fromCallable (() -> NavigationHelper .getIntentByLink (this , currentUrl ))
573591 .subscribeOn (Schedulers .io ())
@@ -590,6 +608,32 @@ private void handleChoice(final String selectedChoiceKey) {
590608 finish ();
591609 }
592610
611+ // show only "video player" since the details activity will be opened and the
612+ // video will be auto played there.
613+ private boolean canHandleChoiceLikeShowInfo (final String selectedChoiceKey ) {
614+ // "video player" can be handled like "show info" when...
615+ if (selectedChoiceKey .equals (getString (R .string .video_player_key ))) {
616+ // Autoplay is enabled
617+ if (!PlayerHelper .isAutoplayAllowedByUser (getThemeWrapperContext ())) {
618+ return false ;
619+ }
620+
621+ final boolean isExtVideoEnabled = PreferenceManager .getDefaultSharedPreferences (this )
622+ .getBoolean (getString (R .string .use_external_video_player_key ), false );
623+ // Ignore it when it's done via an external player
624+ if (isExtVideoEnabled ) {
625+ return false ;
626+ }
627+
628+ // The player is not running or in Video-mode/type
629+ final MainPlayer .PlayerType playerType = PlayerHolder .getInstance ().getType ();
630+ return playerType == null || playerType == MainPlayer .PlayerType .VIDEO ;
631+ // Since "show info" would do the exact same thing, use that as a key to let
632+ // VideoDetailFragment load the stream instead of using FetcherService
633+ }
634+ return false ;
635+ }
636+
593637 private void openAddToPlaylistDialog () {
594638 // Getting the stream info usually takes a moment
595639 // Notifying the user here to ensure that no confusion arises
@@ -672,8 +716,8 @@ private static class AdapterChoiceItem {
672716 final int icon ;
673717
674718 AdapterChoiceItem (final String key , final String description , final int icon ) {
675- this .description = description ;
676719 this .key = key ;
720+ this .description = description ;
677721 this .icon = icon ;
678722 }
679723 }
0 commit comments