Make Timeline always non-null from ExoPlayer

Note that we still have null timelines in ExoPlayerImplInternal.
This is deliberate; and is likely necessary to distinguish between
the no-timeline-yet and timeline-is-empty cases (we want to try
and process a pending seek for the latter, but not the former).

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=140200980
This commit is contained in:
olly 2016-11-25 07:21:51 -08:00 committed by Oliver Woodman
parent 97a23ce572
commit ce9ec79e59
5 changed files with 57 additions and 16 deletions

View File

@ -360,7 +360,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
playerWindow = player.getCurrentWindowIndex();
playerPosition = C.TIME_UNSET;
Timeline timeline = player.getCurrentTimeline();
if (timeline != null && timeline.getWindow(playerWindow, window).isSeekable) {
if (!timeline.isEmpty() && timeline.getWindow(playerWindow, window).isSeekable) {
playerPosition = player.getCurrentPosition();
}
player.release();
@ -417,7 +417,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
isTimelineStatic = timeline != null && timeline.getWindowCount() > 0
isTimelineStatic = !timeline.isEmpty()
&& !timeline.getWindow(timeline.getWindowCount() - 1, window).isDynamic;
}

View File

@ -403,12 +403,12 @@ public interface ExoPlayer {
/**
* Returns the current manifest. The type depends on the {@link MediaSource} passed to
* {@link #prepare}.
* {@link #prepare}. May be null.
*/
Object getCurrentManifest();
/**
* Returns the current {@link Timeline}, or {@code null} if there is no timeline.
* Returns the current {@link Timeline}. Never null, but may be empty.
*/
Timeline getCurrentTimeline();

View File

@ -82,6 +82,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
this.playbackState = STATE_IDLE;
this.listeners = new CopyOnWriteArraySet<>();
emptyTrackSelections = new TrackSelectionArray(new TrackSelection[renderers.length]);
timeline = Timeline.EMPTY;
window = new Timeline.Window();
period = new Timeline.Period();
trackGroups = TrackGroupArray.EMPTY;
@ -120,8 +121,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
if (resetState) {
if (timeline != null || manifest != null) {
timeline = null;
if (!timeline.isEmpty() || manifest != null) {
timeline = Timeline.EMPTY;
manifest = null;
for (EventListener listener : listeners) {
listener.onTimelineChanged(null, null);
@ -178,7 +179,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public void seekTo(int windowIndex, long positionMs) {
if (windowIndex < 0 || (timeline != null && windowIndex >= timeline.getWindowCount())) {
if (windowIndex < 0 || (!timeline.isEmpty() && windowIndex >= timeline.getWindowCount())) {
throw new IndexOutOfBoundsException();
}
pendingSeekAcks++;
@ -223,7 +224,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public int getCurrentWindowIndex() {
if (timeline == null || pendingSeekAcks > 0) {
if (timeline.isEmpty() || pendingSeekAcks > 0) {
return maskingWindowIndex;
} else {
return timeline.getPeriod(playbackInfo.periodIndex, period).windowIndex;
@ -232,7 +233,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public long getDuration() {
if (timeline == null) {
if (timeline.isEmpty()) {
return C.TIME_UNSET;
}
return timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
@ -240,7 +241,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public long getCurrentPosition() {
if (timeline == null || pendingSeekAcks > 0) {
if (timeline.isEmpty() || pendingSeekAcks > 0) {
return maskingWindowPositionMs;
} else {
timeline.getPeriod(playbackInfo.periodIndex, period);
@ -251,7 +252,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public long getBufferedPosition() {
// TODO - Implement this properly.
if (timeline == null || pendingSeekAcks > 0) {
if (timeline.isEmpty() || pendingSeekAcks > 0) {
return maskingWindowPositionMs;
} else {
timeline.getPeriod(playbackInfo.periodIndex, period);
@ -261,7 +262,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public int getBufferedPercentage() {
if (timeline == null) {
if (timeline.isEmpty()) {
return 0;
}
long bufferedPosition = getBufferedPosition();

View File

@ -91,6 +91,46 @@ package com.google.android.exoplayer2;
*/
public abstract class Timeline {
/**
* An empty timeline.
*/
public static final Timeline EMPTY = new Timeline() {
@Override
public int getWindowCount() {
return 0;
}
@Override
public Window getWindow(int windowIndex, Window window, boolean setIds,
long defaultPositionProjectionUs) {
throw new IndexOutOfBoundsException();
}
@Override
public int getPeriodCount() {
return 0;
}
@Override
public Period getPeriod(int periodIndex, Period period, boolean setIds) {
throw new IndexOutOfBoundsException();
}
@Override
public int getIndexOfPeriod(Object uid) {
return C.INDEX_UNSET;
}
};
/**
* Returns whether the timeline is empty.
*/
public final boolean isEmpty() {
return getWindowCount() == 0;
}
/**
* Returns the number of windows in the timeline.
*/

View File

@ -422,11 +422,11 @@ public class PlaybackControlView extends FrameLayout {
return;
}
Timeline currentTimeline = player != null ? player.getCurrentTimeline() : null;
boolean haveTimeline = currentTimeline != null;
boolean haveNonEmptyTimeline = currentTimeline != null && !currentTimeline.isEmpty();
boolean isSeekable = false;
boolean enablePrevious = false;
boolean enableNext = false;
if (haveTimeline) {
if (haveNonEmptyTimeline) {
int currentWindowIndex = player.getCurrentWindowIndex();
currentTimeline.getWindow(currentWindowIndex, currentWindow);
isSeekable = currentWindow.isSeekable;
@ -525,7 +525,7 @@ public class PlaybackControlView extends FrameLayout {
private void previous() {
Timeline currentTimeline = player.getCurrentTimeline();
if (currentTimeline == null) {
if (currentTimeline.isEmpty()) {
return;
}
int currentWindowIndex = player.getCurrentWindowIndex();
@ -540,7 +540,7 @@ public class PlaybackControlView extends FrameLayout {
private void next() {
Timeline currentTimeline = player.getCurrentTimeline();
if (currentTimeline == null) {
if (currentTimeline.isEmpty()) {
return;
}
int currentWindowIndex = player.getCurrentWindowIndex();