Skip to content

Commit a68c6a2

Browse files
committed
Reworked incorrect choice handling and centralized it
1 parent 733f6aa commit a68c6a2

1 file changed

Lines changed: 137 additions & 93 deletions

File tree

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

Lines changed: 137 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import androidx.annotation.DrawableRes;
2525
import androidx.annotation.NonNull;
2626
import androidx.annotation.Nullable;
27+
import androidx.annotation.StringRes;
2728
import androidx.appcompat.app.AlertDialog;
2829
import androidx.appcompat.app.AppCompatActivity;
2930
import 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

Comments
 (0)