Skip to content

Commit 8797669

Browse files
authored
Merge pull request #9285 from Isira-Seneviratne/Optional_cleanup
Clean up Optional-related code.
2 parents 1bb166a + 9c7ed80 commit 8797669

7 files changed

Lines changed: 184 additions & 217 deletions

File tree

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

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,10 @@ public void onServiceConnected(final Player connectedPlayer,
255255
playerUi.ifPresent(MainPlayerUi::toggleFullscreen);
256256
}
257257

258-
//noinspection SimplifyOptionalCallChains
259258
if (playAfterConnect
260259
|| (currentInfo != null
261260
&& isAutoplayEnabled()
262-
&& !playerUi.isPresent())) {
261+
&& playerUi.isEmpty())) {
263262
autoPlayEnabled = true; // forcefully start playing
264263
openVideoPlayerAutoFullscreen();
265264
}
@@ -1174,16 +1173,15 @@ private void openMainPlayer() {
11741173
* be reused in a few milliseconds and the flickering would be annoying.
11751174
*/
11761175
private void hideMainPlayerOnLoadingNewStream() {
1177-
//noinspection SimplifyOptionalCallChains
1178-
if (!isPlayerServiceAvailable() || !getRoot().isPresent()
1179-
|| !player.videoPlayerSelected()) {
1176+
final var root = getRoot();
1177+
if (!isPlayerServiceAvailable() || root.isEmpty() || !player.videoPlayerSelected()) {
11801178
return;
11811179
}
11821180

11831181
removeVideoPlayerView();
11841182
if (isAutoplayEnabled()) {
11851183
playerService.stopForImmediateReusing();
1186-
getRoot().ifPresent(view -> view.setVisibility(View.GONE));
1184+
root.ifPresent(view -> view.setVisibility(View.GONE));
11871185
} else {
11881186
playerHolder.stopService();
11891187
}
@@ -1887,10 +1885,9 @@ public void onServiceStopped() {
18871885
@Override
18881886
public void onFullscreenStateChanged(final boolean fullscreen) {
18891887
setupBrightness();
1890-
//noinspection SimplifyOptionalCallChains
18911888
if (!isPlayerAndPlayerServiceAvailable()
1892-
|| !player.UIs().get(MainPlayerUi.class).isPresent()
1893-
|| getRoot().map(View::getParent).orElse(null) == null) {
1889+
|| player.UIs().get(MainPlayerUi.class).isEmpty()
1890+
|| getRoot().flatMap(v -> Optional.ofNullable(v.getParent())).isEmpty()) {
18941891
return;
18951892
}
18961893

@@ -2429,23 +2426,20 @@ private void setOverlayElementsClickable(final boolean enable) {
24292426

24302427
// helpers to check the state of player and playerService
24312428
boolean isPlayerAvailable() {
2432-
return (player != null);
2429+
return player != null;
24332430
}
24342431

24352432
boolean isPlayerServiceAvailable() {
2436-
return (playerService != null);
2433+
return playerService != null;
24372434
}
24382435

24392436
boolean isPlayerAndPlayerServiceAvailable() {
2440-
return (player != null && playerService != null);
2437+
return player != null && playerService != null;
24412438
}
24422439

24432440
public Optional<View> getRoot() {
2444-
if (player == null) {
2445-
return Optional.empty();
2446-
}
2447-
2448-
return player.UIs().get(VideoPlayerUi.class)
2441+
return Optional.ofNullable(player)
2442+
.flatMap(player1 -> player1.UIs().get(VideoPlayerUi.class))
24492443
.map(playerUi -> playerUi.getBinding().getRoot());
24502444
}
24512445

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,26 +1695,25 @@ private void registerStreamViewed() {
16951695
}
16961696

16971697
private void saveStreamProgressState(final long progressMillis) {
1698-
//noinspection SimplifyOptionalCallChains
1699-
if (!getCurrentStreamInfo().isPresent()
1700-
|| !prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) {
1701-
return;
1702-
}
1703-
if (DEBUG) {
1704-
Log.d(TAG, "saveStreamProgressState() called with: progressMillis=" + progressMillis
1705-
+ ", currentMetadata=[" + getCurrentStreamInfo().get().getName() + "]");
1706-
}
1698+
getCurrentStreamInfo().ifPresent(info -> {
1699+
if (!prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) {
1700+
return;
1701+
}
1702+
if (DEBUG) {
1703+
Log.d(TAG, "saveStreamProgressState() called with: progressMillis=" + progressMillis
1704+
+ ", currentMetadata=[" + info.getName() + "]");
1705+
}
17071706

1708-
databaseUpdateDisposable
1709-
.add(recordManager.saveStreamState(getCurrentStreamInfo().get(), progressMillis)
1710-
.observeOn(AndroidSchedulers.mainThread())
1711-
.doOnError(e -> {
1712-
if (DEBUG) {
1713-
e.printStackTrace();
1714-
}
1715-
})
1716-
.onErrorComplete()
1717-
.subscribe());
1707+
databaseUpdateDisposable.add(recordManager.saveStreamState(info, progressMillis)
1708+
.observeOn(AndroidSchedulers.mainThread())
1709+
.doOnError(e -> {
1710+
if (DEBUG) {
1711+
e.printStackTrace();
1712+
}
1713+
})
1714+
.onErrorComplete()
1715+
.subscribe());
1716+
});
17181717
}
17191718

17201719
public void saveStreamProgressState() {
@@ -1876,23 +1875,16 @@ public void disablePreloadingOfCurrentTrack() {
18761875
loadController.disablePreloadingOfCurrentTrack();
18771876
}
18781877

1879-
@Nullable
1880-
public VideoStream getSelectedVideoStream() {
1881-
@Nullable final MediaItemTag.Quality quality = Optional.ofNullable(currentMetadata)
1878+
public Optional<VideoStream> getSelectedVideoStream() {
1879+
return Optional.ofNullable(currentMetadata)
18821880
.flatMap(MediaItemTag::getMaybeQuality)
1883-
.orElse(null);
1884-
if (quality == null) {
1885-
return null;
1886-
}
1887-
1888-
final List<VideoStream> availableStreams = quality.getSortedVideoStreams();
1889-
final int selectedStreamIndex = quality.getSelectedVideoStreamIndex();
1890-
1891-
if (selectedStreamIndex >= 0 && availableStreams.size() > selectedStreamIndex) {
1892-
return availableStreams.get(selectedStreamIndex);
1893-
} else {
1894-
return null;
1895-
}
1881+
.filter(quality -> {
1882+
final int selectedStreamIndex = quality.getSelectedVideoStreamIndex();
1883+
return selectedStreamIndex >= 0
1884+
&& selectedStreamIndex < quality.getSortedVideoStreams().size();
1885+
})
1886+
.map(quality -> quality.getSortedVideoStreams()
1887+
.get(quality.getSelectedVideoStreamIndex()));
18961888
}
18971889
//endregion
18981890

@@ -2036,40 +2028,36 @@ public void useVideoSource(final boolean videoEnabled) {
20362028
// in livestreams) so we will be not able to execute the block below.
20372029
// Reload the play queue manager in this case, which is the behavior when we don't know the
20382030
// index of the video renderer or playQueueManagerReloadingNeeded returns true.
2039-
final Optional<StreamInfo> optCurrentStreamInfo = getCurrentStreamInfo();
2040-
if (!optCurrentStreamInfo.isPresent()) {
2041-
reloadPlayQueueManager();
2042-
setRecovery();
2043-
return;
2044-
}
2045-
2046-
final StreamInfo info = optCurrentStreamInfo.get();
2047-
2048-
// In the case we don't know the source type, fallback to the one with video with audio or
2049-
// audio-only source.
2050-
final SourceType sourceType = videoResolver.getStreamSourceType().orElse(
2051-
SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY);
2031+
getCurrentStreamInfo().ifPresentOrElse(info -> {
2032+
// In the case we don't know the source type, fallback to the one with video with audio
2033+
// or audio-only source.
2034+
final SourceType sourceType = videoResolver.getStreamSourceType()
2035+
.orElse(SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY);
20522036

2053-
if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) {
2054-
reloadPlayQueueManager();
2055-
} else {
2056-
if (StreamTypeUtil.isAudio(info.getStreamType())) {
2057-
// Nothing to do more than setting the recovery position
2058-
setRecovery();
2059-
return;
2060-
}
2037+
if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) {
2038+
reloadPlayQueueManager();
2039+
} else {
2040+
if (StreamTypeUtil.isAudio(info.getStreamType())) {
2041+
// Nothing to do more than setting the recovery position
2042+
setRecovery();
2043+
return;
2044+
}
20612045

2062-
final DefaultTrackSelector.Parameters.Builder parametersBuilder =
2063-
trackSelector.buildUponParameters();
2046+
final var parametersBuilder = trackSelector.buildUponParameters();
20642047

2065-
// Enable/disable the video track and the ability to select subtitles
2066-
parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, !videoEnabled);
2067-
parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, !videoEnabled);
2048+
// Enable/disable the video track and the ability to select subtitles
2049+
parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, !videoEnabled);
2050+
parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, !videoEnabled);
20682051

2069-
trackSelector.setParameters(parametersBuilder);
2070-
}
2052+
trackSelector.setParameters(parametersBuilder);
2053+
}
20712054

2072-
setRecovery();
2055+
setRecovery();
2056+
}, () -> {
2057+
// This is executed when the current stream info is not available.
2058+
reloadPlayQueueManager();
2059+
setRecovery();
2060+
});
20732061
}
20742062

20752063
/**

app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,11 @@ default Optional<Quality> getMaybeQuality() {
6161

6262
@NonNull
6363
static Optional<MediaItemTag> from(@Nullable final MediaItem mediaItem) {
64-
if (mediaItem == null || mediaItem.localConfiguration == null
65-
|| !(mediaItem.localConfiguration.tag instanceof MediaItemTag)) {
66-
return Optional.empty();
67-
}
68-
69-
return Optional.of((MediaItemTag) mediaItem.localConfiguration.tag);
64+
return Optional.ofNullable(mediaItem)
65+
.flatMap(item -> Optional.ofNullable(item.localConfiguration))
66+
.flatMap(localConfiguration -> Optional.ofNullable(localConfiguration.tag))
67+
.filter(MediaItemTag.class::isInstance)
68+
.map(MediaItemTag.class::cast);
7069
}
7170

7271
@NonNull

app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import androidx.annotation.Nullable;
88
import androidx.collection.ArraySet;
99

10-
import com.google.android.exoplayer2.source.MediaSource;
11-
1210
import org.reactivestreams.Subscriber;
1311
import org.reactivestreams.Subscription;
1412
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
@@ -23,10 +21,10 @@
2321
import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent;
2422
import org.schabi.newpipe.player.playqueue.events.RemoveEvent;
2523
import org.schabi.newpipe.player.playqueue.events.ReorderEvent;
26-
import org.schabi.newpipe.util.ServiceHelper;
2724

2825
import java.util.Collection;
2926
import java.util.Collections;
27+
import java.util.Optional;
3028
import java.util.Set;
3129
import java.util.concurrent.TimeUnit;
3230
import java.util.concurrent.atomic.AtomicBoolean;
@@ -43,6 +41,7 @@
4341
import static org.schabi.newpipe.player.mediasource.FailedMediaSource.MediaSourceResolutionException;
4442
import static org.schabi.newpipe.player.mediasource.FailedMediaSource.StreamInfoLoadException;
4543
import static org.schabi.newpipe.player.playqueue.PlayQueue.DEBUG;
44+
import static org.schabi.newpipe.util.ServiceHelper.getCacheExpirationMillis;
4645

4746
public class MediaSourceManager {
4847
@NonNull
@@ -421,31 +420,39 @@ private void maybeLoadItem(@NonNull final PlayQueueItem item) {
421420
}
422421

423422
private Single<ManagedMediaSource> getLoadedMediaSource(@NonNull final PlayQueueItem stream) {
424-
return stream.getStream().map(streamInfo -> {
425-
final MediaSource source = playbackListener.sourceOf(stream, streamInfo);
426-
if (source == null || !MediaItemTag.from(source.getMediaItem()).isPresent()) {
427-
final String message = "Unable to resolve source from stream info. "
428-
+ "URL: " + stream.getUrl() + ", "
429-
+ "audio count: " + streamInfo.getAudioStreams().size() + ", "
430-
+ "video count: " + streamInfo.getVideoOnlyStreams().size() + ", "
431-
+ streamInfo.getVideoStreams().size();
432-
return (ManagedMediaSource)
433-
FailedMediaSource.of(stream, new MediaSourceResolutionException(message));
434-
}
435-
436-
final MediaItemTag tag = MediaItemTag.from(source.getMediaItem()).get();
437-
final long expiration = System.currentTimeMillis()
438-
+ ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId());
439-
return new LoadedMediaSource(source, tag, stream, expiration);
440-
}).onErrorReturn(throwable -> {
441-
if (throwable instanceof ExtractionException) {
442-
return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable));
443-
}
444-
// Non-source related error expected here (e.g. network),
445-
// should allow retry shortly after the error.
446-
return FailedMediaSource.of(stream, new Exception(throwable),
447-
/*allowRetryIn=*/TimeUnit.MILLISECONDS.convert(3, TimeUnit.SECONDS));
448-
});
423+
return stream.getStream()
424+
.map(streamInfo -> Optional
425+
.ofNullable(playbackListener.sourceOf(stream, streamInfo))
426+
.<ManagedMediaSource>flatMap(source ->
427+
MediaItemTag.from(source.getMediaItem())
428+
.map(tag -> {
429+
final int serviceId = streamInfo.getServiceId();
430+
final long expiration = System.currentTimeMillis()
431+
+ getCacheExpirationMillis(serviceId);
432+
return new LoadedMediaSource(source, tag, stream,
433+
expiration);
434+
})
435+
)
436+
.orElseGet(() -> {
437+
final String message = "Unable to resolve source from stream info. "
438+
+ "URL: " + stream.getUrl()
439+
+ ", audio count: " + streamInfo.getAudioStreams().size()
440+
+ ", video count: " + streamInfo.getVideoOnlyStreams().size()
441+
+ ", " + streamInfo.getVideoStreams().size();
442+
return FailedMediaSource.of(stream,
443+
new MediaSourceResolutionException(message));
444+
})
445+
)
446+
.onErrorReturn(throwable -> {
447+
if (throwable instanceof ExtractionException) {
448+
return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable));
449+
}
450+
// Non-source related error expected here (e.g. network),
451+
// should allow retry shortly after the error.
452+
final long allowRetryIn = TimeUnit.MILLISECONDS.convert(3,
453+
TimeUnit.SECONDS);
454+
return FailedMediaSource.of(stream, new Exception(throwable), allowRetryIn);
455+
});
449456
}
450457

451458
private void onMediaSourceReceived(@NonNull final PlayQueueItem item,

app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import androidx.annotation.IntDef;
1010
import androidx.annotation.NonNull;
11+
import androidx.annotation.Nullable;
1112
import androidx.core.graphics.BitmapCompat;
1213
import androidx.core.math.MathUtils;
1314
import androidx.preference.PreferenceManager;
@@ -16,7 +17,6 @@
1617
import org.schabi.newpipe.util.DeviceUtils;
1718

1819
import java.lang.annotation.Retention;
19-
import java.util.Optional;
2020
import java.util.function.IntSupplier;
2121

2222
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -66,21 +66,19 @@ public static int getSeekbarPreviewThumbnailType(@NonNull final Context context)
6666

6767
public static void tryResizeAndSetSeekbarPreviewThumbnail(
6868
@NonNull final Context context,
69-
@NonNull final Optional<Bitmap> optPreviewThumbnail,
69+
@Nullable final Bitmap previewThumbnail,
7070
@NonNull final ImageView currentSeekbarPreviewThumbnail,
7171
@NonNull final IntSupplier baseViewWidthSupplier) {
72-
73-
if (!optPreviewThumbnail.isPresent()) {
72+
if (previewThumbnail == null) {
7473
currentSeekbarPreviewThumbnail.setVisibility(View.GONE);
7574
return;
7675
}
7776

7877
currentSeekbarPreviewThumbnail.setVisibility(View.VISIBLE);
79-
final Bitmap srcBitmap = optPreviewThumbnail.get();
8078

8179
// Resize original bitmap
8280
try {
83-
final int srcWidth = srcBitmap.getWidth() > 0 ? srcBitmap.getWidth() : 1;
81+
final int srcWidth = previewThumbnail.getWidth() > 0 ? previewThumbnail.getWidth() : 1;
8482
final int newWidth = MathUtils.clamp(
8583
// Use 1/4 of the width for the preview
8684
Math.round(baseViewWidthSupplier.getAsInt() / 4f),
@@ -90,15 +88,15 @@ public static void tryResizeAndSetSeekbarPreviewThumbnail(
9088
Math.round(srcWidth * 2.5f));
9189

9290
final float scaleFactor = (float) newWidth / srcWidth;
93-
final int newHeight = (int) (srcBitmap.getHeight() * scaleFactor);
91+
final int newHeight = (int) (previewThumbnail.getHeight() * scaleFactor);
9492

95-
currentSeekbarPreviewThumbnail.setImageBitmap(BitmapCompat.createScaledBitmap(srcBitmap,
96-
newWidth, newHeight, null, true));
93+
currentSeekbarPreviewThumbnail.setImageBitmap(BitmapCompat
94+
.createScaledBitmap(previewThumbnail, newWidth, newHeight, null, true));
9795
} catch (final Exception ex) {
9896
Log.e(TAG, "Failed to resize and set seekbar preview thumbnail", ex);
9997
currentSeekbarPreviewThumbnail.setVisibility(View.GONE);
10098
} finally {
101-
srcBitmap.recycle();
99+
previewThumbnail.recycle();
102100
}
103101
}
104102
}

0 commit comments

Comments
 (0)