summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java')
-rw-r--r--mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java
new file mode 100644
index 0000000000..c06361e69b
--- /dev/null
+++ b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/BasePlayer.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mozilla.thirdparty.com.google.android.exoplayer2;
+
+import androidx.annotation.Nullable;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.util.Util;
+
+/** Abstract base {@link Player} which implements common implementation independent methods. */
+public abstract class BasePlayer implements Player {
+
+ protected final Timeline.Window window;
+
+ public BasePlayer() {
+ window = new Timeline.Window();
+ }
+
+ @Override
+ public final boolean isPlaying() {
+ return getPlaybackState() == Player.STATE_READY
+ && getPlayWhenReady()
+ && getPlaybackSuppressionReason() == PLAYBACK_SUPPRESSION_REASON_NONE;
+ }
+
+ @Override
+ public final void seekToDefaultPosition() {
+ seekToDefaultPosition(getCurrentWindowIndex());
+ }
+
+ @Override
+ public final void seekToDefaultPosition(int windowIndex) {
+ seekTo(windowIndex, /* positionMs= */ C.TIME_UNSET);
+ }
+
+ @Override
+ public final void seekTo(long positionMs) {
+ seekTo(getCurrentWindowIndex(), positionMs);
+ }
+
+ @Override
+ public final boolean hasPrevious() {
+ return getPreviousWindowIndex() != C.INDEX_UNSET;
+ }
+
+ @Override
+ public final void previous() {
+ int previousWindowIndex = getPreviousWindowIndex();
+ if (previousWindowIndex != C.INDEX_UNSET) {
+ seekToDefaultPosition(previousWindowIndex);
+ }
+ }
+
+ @Override
+ public final boolean hasNext() {
+ return getNextWindowIndex() != C.INDEX_UNSET;
+ }
+
+ @Override
+ public final void next() {
+ int nextWindowIndex = getNextWindowIndex();
+ if (nextWindowIndex != C.INDEX_UNSET) {
+ seekToDefaultPosition(nextWindowIndex);
+ }
+ }
+
+ @Override
+ public final void stop() {
+ stop(/* reset= */ false);
+ }
+
+ @Override
+ public final int getNextWindowIndex() {
+ Timeline timeline = getCurrentTimeline();
+ return timeline.isEmpty()
+ ? C.INDEX_UNSET
+ : timeline.getNextWindowIndex(
+ getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
+ }
+
+ @Override
+ public final int getPreviousWindowIndex() {
+ Timeline timeline = getCurrentTimeline();
+ return timeline.isEmpty()
+ ? C.INDEX_UNSET
+ : timeline.getPreviousWindowIndex(
+ getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
+ }
+
+ @Override
+ @Nullable
+ public final Object getCurrentTag() {
+ Timeline timeline = getCurrentTimeline();
+ return timeline.isEmpty() ? null : timeline.getWindow(getCurrentWindowIndex(), window).tag;
+ }
+
+ @Override
+ @Nullable
+ public final Object getCurrentManifest() {
+ Timeline timeline = getCurrentTimeline();
+ return timeline.isEmpty() ? null : timeline.getWindow(getCurrentWindowIndex(), window).manifest;
+ }
+
+ @Override
+ public final int getBufferedPercentage() {
+ long position = getBufferedPosition();
+ long duration = getDuration();
+ return position == C.TIME_UNSET || duration == C.TIME_UNSET
+ ? 0
+ : duration == 0 ? 100 : Util.constrainValue((int) ((position * 100) / duration), 0, 100);
+ }
+
+ @Override
+ public final boolean isCurrentWindowDynamic() {
+ Timeline timeline = getCurrentTimeline();
+ return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isDynamic;
+ }
+
+ @Override
+ public final boolean isCurrentWindowLive() {
+ Timeline timeline = getCurrentTimeline();
+ return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isLive;
+ }
+
+ @Override
+ public final boolean isCurrentWindowSeekable() {
+ Timeline timeline = getCurrentTimeline();
+ return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isSeekable;
+ }
+
+ @Override
+ public final long getContentDuration() {
+ Timeline timeline = getCurrentTimeline();
+ return timeline.isEmpty()
+ ? C.TIME_UNSET
+ : timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
+ }
+
+ @RepeatMode
+ private int getRepeatModeForNavigation() {
+ @RepeatMode int repeatMode = getRepeatMode();
+ return repeatMode == REPEAT_MODE_ONE ? REPEAT_MODE_OFF : repeatMode;
+ }
+
+ /** Holds a listener reference. */
+ protected static final class ListenerHolder {
+
+ /**
+ * The listener on which {link #invoke} will execute {@link ListenerInvocation listener
+ * invocations}.
+ */
+ public final Player.EventListener listener;
+
+ private boolean released;
+
+ public ListenerHolder(Player.EventListener listener) {
+ this.listener = listener;
+ }
+
+ /** Prevents any further {@link ListenerInvocation} to be executed on {@link #listener}. */
+ public void release() {
+ released = true;
+ }
+
+ /**
+ * Executes the given {@link ListenerInvocation} on {@link #listener}. Does nothing if {@link
+ * #release} has been called on this instance.
+ */
+ public void invoke(ListenerInvocation listenerInvocation) {
+ if (!released) {
+ listenerInvocation.invokeListener(listener);
+ }
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+ return listener.equals(((ListenerHolder) other).listener);
+ }
+
+ @Override
+ public int hashCode() {
+ return listener.hashCode();
+ }
+ }
+
+ /** Parameterized invocation of a {@link Player.EventListener} method. */
+ protected interface ListenerInvocation {
+
+ /** Executes the invocation on the given {@link Player.EventListener}. */
+ void invokeListener(Player.EventListener listener);
+ }
+}