/*
 * Copyright (C) 2015 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 com.android.tv;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Range;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.api.TunableTvViewPlayingApi.TimeShiftListener;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TimeShiftUtils;
import com.android.tv.util.Utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/**
 * A class which manages the time shift feature in Live TV. It consists of two parts. {@link
 * PlayController} controls the playback such as play/pause, rewind and fast-forward using {@link
 * TunableTvView} which communicates with TvInputService through {@link
 * android.media.tv.TvInputService.Session}. {@link ProgramManager} loads programs of the current
 * channel in the background.
 */
public class TimeShiftManager {
    private static final String TAG = "TimeShiftManager";
    private static final boolean DEBUG = false;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({PLAY_STATUS_PAUSED, PLAY_STATUS_PLAYING})
    public @interface PlayStatus {}

    public static final int PLAY_STATUS_PAUSED = 0;
    public static final int PLAY_STATUS_PLAYING = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({PLAY_SPEED_1X, PLAY_SPEED_2X, PLAY_SPEED_3X, PLAY_SPEED_4X, PLAY_SPEED_5X})
    public @interface PlaySpeed {}

    public static final int PLAY_SPEED_1X = 1;
    public static final int PLAY_SPEED_2X = 2;
    public static final int PLAY_SPEED_3X = 3;
    public static final int PLAY_SPEED_4X = 4;
    public static final int PLAY_SPEED_5X = 5;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({PLAY_DIRECTION_FORWARD, PLAY_DIRECTION_BACKWARD})
    public @interface PlayDirection {}

    public static final int PLAY_DIRECTION_FORWARD = 0;
    public static final int PLAY_DIRECTION_BACKWARD = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            flag = true,
            value = {
                TIME_SHIFT_ACTION_ID_PLAY,
                TIME_SHIFT_ACTION_ID_PAUSE,
                TIME_SHIFT_ACTION_ID_REWIND,
                TIME_SHIFT_ACTION_ID_FAST_FORWARD,
                TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS,
                TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT
            })
    public @interface TimeShiftActionId {}

    public static final int TIME_SHIFT_ACTION_ID_PLAY = 1;
    public static final int TIME_SHIFT_ACTION_ID_PAUSE = 1 << 1;
    public static final int TIME_SHIFT_ACTION_ID_REWIND = 1 << 2;
    public static final int TIME_SHIFT_ACTION_ID_FAST_FORWARD = 1 << 3;
    public static final int TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS = 1 << 4;
    public static final int TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT = 1 << 5;

    private static final int MSG_GET_CURRENT_POSITION = 1000;
    private static final int MSG_PREFETCH_PROGRAM = 1001;
    private static final long REQUEST_CURRENT_POSITION_INTERVAL = TimeUnit.SECONDS.toMillis(1);
    private static final long MAX_DUMMY_PROGRAM_DURATION = TimeUnit.MINUTES.toMillis(30);
    @VisibleForTesting static final long INVALID_TIME = -1;
    static final long CURRENT_TIME = -2;
    private static final long PREFETCH_TIME_OFFSET_FROM_PROGRAM_END = TimeUnit.MINUTES.toMillis(1);
    private static final long PREFETCH_DURATION_FOR_NEXT = TimeUnit.HOURS.toMillis(2);

    private static final long ALLOWED_START_TIME_OFFSET = TimeUnit.DAYS.toMillis(14);
    private static final long TWO_WEEKS_MS = TimeUnit.DAYS.toMillis(14);

    @VisibleForTesting static final long REQUEST_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(3);

    /**
     * If the user presses the {@link android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS} button within
     * this threshold from the program start time, the play position moves to the start of the
     * previous program. Otherwise, the play position moves to the start of the current program.
     * This value is specified in the UX document.
     */
    private static final long PROGRAM_START_TIME_THRESHOLD = TimeUnit.SECONDS.toMillis(3);
    /**
     * If the current position enters within this range from the recording start time, rewind action
     * and jump to previous action is disabled. Similarly, if the current position enters within
     * this range from the current system time, fast forward action and jump to next action is
     * disabled. It must be three times longer than {@link #REQUEST_CURRENT_POSITION_INTERVAL} at
     * least.
     */
    private static final long DISABLE_ACTION_THRESHOLD = 3 * REQUEST_CURRENT_POSITION_INTERVAL;
    /**
     * If the current position goes out of this range from the recording start time, rewind action
     * and jump to previous action is enabled. Similarly, if the current position goes out of this
     * range from the current system time, fast forward action and jump to next action is enabled.
     * Enable threshold and disable threshold must be different because the current position does
     * not have the continuous value. It changes every one second.
     */
    private static final long ENABLE_ACTION_THRESHOLD =
            DISABLE_ACTION_THRESHOLD + 3 * REQUEST_CURRENT_POSITION_INTERVAL;
    /**
     * The current position sent from TIS can not be exactly the same as the current system time due
     * to the elapsed time to pass the message from TIS to Live TV. So the boundary threshold
     * is necessary. The same goes for the recording start time. It's the same {@link
     * #REQUEST_CURRENT_POSITION_INTERVAL}.
     */
    private static final long RECORDING_BOUNDARY_THRESHOLD = REQUEST_CURRENT_POSITION_INTERVAL;

    private final PlayController mPlayController;
    private final ProgramManager mProgramManager;
    private final Tracker mTracker;

    @VisibleForTesting
    final CurrentPositionMediator mCurrentPositionMediator = new CurrentPositionMediator();

    private Listener mListener;
    private final OnCurrentProgramUpdatedListener mOnCurrentProgramUpdatedListener;
    private int mEnabledActionIds =
            TIME_SHIFT_ACTION_ID_PLAY
                    | TIME_SHIFT_ACTION_ID_PAUSE
                    | TIME_SHIFT_ACTION_ID_REWIND
                    | TIME_SHIFT_ACTION_ID_FAST_FORWARD
                    | TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS
                    | TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT;
    @TimeShiftActionId private int mLastActionId = 0;

    private final Context mContext;

    private Program mCurrentProgram;
    // This variable is used to block notification while changing the availability status.
    private boolean mNotificationEnabled;

    private final Handler mHandler = new TimeShiftHandler(this);

    public TimeShiftManager(
            Context context,
            TunableTvView tvView,
            ProgramDataManager programDataManager,
            Tracker tracker,
            OnCurrentProgramUpdatedListener onCurrentProgramUpdatedListener) {
        mContext = context;
        mPlayController = new PlayController(tvView);
        mProgramManager = new ProgramManager(programDataManager);
        mTracker = tracker;
        mOnCurrentProgramUpdatedListener = onCurrentProgramUpdatedListener;
    }

    /** Sets a listener which will receive events from this class. */
    public void setListener(Listener listener) {
        mListener = listener;
    }

    /** Checks if the trick play is available for the current channel. */
    public boolean isAvailable() {
        return mPlayController.mAvailable;
    }

    /** Returns the current time position in milliseconds. */
    public long getCurrentPositionMs() {
        return mCurrentPositionMediator.mCurrentPositionMs;
    }

    void setCurrentPositionMs(long currentTimeMs) {
        mCurrentPositionMediator.onCurrentPositionChanged(currentTimeMs);
    }

    /** Returns the start time of the recording in milliseconds. */
    public long getRecordStartTimeMs() {
        long oldestProgramStartTime = mProgramManager.getOldestProgramStartTime();
        return oldestProgramStartTime == INVALID_TIME
                ? INVALID_TIME
                : mPlayController.mRecordStartTimeMs;
    }

    /** Returns the end time of the recording in milliseconds. */
    public long getRecordEndTimeMs() {
        if (mPlayController.mRecordEndTimeMs == CURRENT_TIME) {
            return System.currentTimeMillis();
        } else {
            return mPlayController.mRecordEndTimeMs;
        }
    }

    /**
     * Plays the media.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void play() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_PLAY)) {
            return;
        }
        mTracker.sendTimeShiftAction(TIME_SHIFT_ACTION_ID_PLAY);
        mLastActionId = TIME_SHIFT_ACTION_ID_PLAY;
        mPlayController.play();
        updateActions();
    }

    /**
     * Pauses the playback.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void pause() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_PAUSE)) {
            return;
        }
        mLastActionId = TIME_SHIFT_ACTION_ID_PAUSE;
        mTracker.sendTimeShiftAction(mLastActionId);
        mPlayController.pause();
        updateActions();
    }

    /**
     * Toggles the playing and paused state.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void togglePlayPause() {
        mPlayController.togglePlayPause();
    }

    /**
     * Plays the media in backward direction. The playback speed is increased by 1x each time this
     * is called. The range of the speed is from 2x to 5x. If the playing position is considered the
     * same as the record start time, it does nothing
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void rewind() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND)) {
            return;
        }
        mLastActionId = TIME_SHIFT_ACTION_ID_REWIND;
        mTracker.sendTimeShiftAction(mLastActionId);
        mPlayController.rewind();
        updateActions();
    }

    /**
     * Plays the media in forward direction. The playback speed is increased by 1x each time this is
     * called. The range of the speed is from 2x to 5x. If the playing position is the same as the
     * current time, it does nothing.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void fastForward() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD)) {
            return;
        }
        mLastActionId = TIME_SHIFT_ACTION_ID_FAST_FORWARD;
        mTracker.sendTimeShiftAction(mLastActionId);
        mPlayController.fastForward();
        updateActions();
    }

    /**
     * Jumps to the start of the current program. If the currently playing position is within 3
     * seconds (={@link #PROGRAM_START_TIME_THRESHOLD})from the start time of the program, it goes
     * to the start of the previous program if exists. If the playing position is the same as the
     * record start time, it does nothing.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void jumpToPrevious() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS)) {
            return;
        }
        Program program =
                mProgramManager.getProgramAt(
                        mCurrentPositionMediator.mCurrentPositionMs - PROGRAM_START_TIME_THRESHOLD);
        if (program == null) {
            return;
        }
        long seekPosition =
                Math.max(program.getStartTimeUtcMillis(), mPlayController.mRecordStartTimeMs);
        mLastActionId = TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS;
        mTracker.sendTimeShiftAction(mLastActionId);
        mPlayController.seekTo(seekPosition);
        mCurrentPositionMediator.onSeekRequested(seekPosition);
        updateActions();
    }

    /**
     * Jumps to the start of the next program if exists. If there's no next program, it jumps to the
     * current system time and shows the live TV. If the playing position is considered the same as
     * the current time, it does nothing.
     *
     * @throws IllegalStateException if the trick play is not available.
     */
    public void jumpToNext() {
        if (!isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT)) {
            return;
        }
        Program currentProgram =
                mProgramManager.getProgramAt(mCurrentPositionMediator.mCurrentPositionMs);
        if (currentProgram == null) {
            return;
        }
        Program nextProgram = mProgramManager.getProgramAt(currentProgram.getEndTimeUtcMillis());
        long currentTimeMs = System.currentTimeMillis();
        mLastActionId = TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT;
        mTracker.sendTimeShiftAction(mLastActionId);
        if (nextProgram == null || nextProgram.getStartTimeUtcMillis() > currentTimeMs) {
            mPlayController.seekTo(currentTimeMs);
            if (mPlayController.isForwarding()) {
                // The current position will be the current system time from now.
                mPlayController.mIsPlayOffsetChanged = false;
                mCurrentPositionMediator.initialize(currentTimeMs);
            } else {
                // The current position would not be the current system time.
                // So need to wait for the correct time from TIS.
                mCurrentPositionMediator.onSeekRequested(currentTimeMs);
            }
        } else {
            mPlayController.seekTo(nextProgram.getStartTimeUtcMillis());
            mCurrentPositionMediator.onSeekRequested(nextProgram.getStartTimeUtcMillis());
        }
        updateActions();
    }

    /** Returns the playback status. The value is PLAY_STATUS_PAUSED or PLAY_STATUS_PLAYING. */
    @PlayStatus
    public int getPlayStatus() {
        return mPlayController.mPlayStatus;
    }

    /**
     * Returns the displayed playback speed. The value is one of PLAY_SPEED_1X, PLAY_SPEED_2X,
     * PLAY_SPEED_3X, PLAY_SPEED_4X and PLAY_SPEED_5X.
     */
    @PlaySpeed
    public int getDisplayedPlaySpeed() {
        return mPlayController.mDisplayedPlaySpeed;
    }

    /**
     * Returns the playback speed. The value is PLAY_DIRECTION_FORWARD or PLAY_DIRECTION_BACKWARD.
     */
    @PlayDirection
    public int getPlayDirection() {
        return mPlayController.mPlayDirection;
    }

    /** Returns the ID of the last action.. */
    @TimeShiftActionId
    public int getLastActionId() {
        return mLastActionId;
    }

    /** Enables or disables the time-shift actions. */
    @VisibleForTesting
    void enableAction(@TimeShiftActionId int actionId, boolean enable) {
        int oldEnabledActionIds = mEnabledActionIds;
        if (enable) {
            mEnabledActionIds |= actionId;
        } else {
            mEnabledActionIds &= ~actionId;
        }
        if (mNotificationEnabled && mListener != null && oldEnabledActionIds != mEnabledActionIds) {
            mListener.onActionEnabledChanged(actionId, enable);
        }
    }

    public boolean isActionEnabled(@TimeShiftActionId int actionId) {
        return (mEnabledActionIds & actionId) == actionId;
    }

    private void updateActions() {
        if (isAvailable()) {
            enableAction(TIME_SHIFT_ACTION_ID_PLAY, true);
            enableAction(TIME_SHIFT_ACTION_ID_PAUSE, true);
            // Rewind action and jump to previous action.
            long threshold =
                    isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND)
                            ? DISABLE_ACTION_THRESHOLD
                            : ENABLE_ACTION_THRESHOLD;
            boolean enabled =
                    mCurrentPositionMediator.mCurrentPositionMs - mPlayController.mRecordStartTimeMs
                            > threshold;
            enableAction(TIME_SHIFT_ACTION_ID_REWIND, enabled);
            enableAction(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS, enabled);
            // Fast forward action and jump to next action
            threshold =
                    isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD)
                            ? DISABLE_ACTION_THRESHOLD
                            : ENABLE_ACTION_THRESHOLD;
            enabled =
                    getRecordEndTimeMs() - mCurrentPositionMediator.mCurrentPositionMs > threshold;
            enableAction(TIME_SHIFT_ACTION_ID_FAST_FORWARD, enabled);
            enableAction(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT, enabled);
        } else {
            enableAction(TIME_SHIFT_ACTION_ID_PLAY, false);
            enableAction(TIME_SHIFT_ACTION_ID_PAUSE, false);
            enableAction(TIME_SHIFT_ACTION_ID_REWIND, false);
            enableAction(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS, false);
            enableAction(TIME_SHIFT_ACTION_ID_FAST_FORWARD, false);
            enableAction(TIME_SHIFT_ACTION_ID_PLAY, false);
        }
    }

    private void updateCurrentProgram() {
        SoftPreconditions.checkState(isAvailable(), TAG, "Time shift is not available");
        SoftPreconditions.checkState(mCurrentPositionMediator.mCurrentPositionMs != INVALID_TIME);
        Program currentProgram = getProgramAt(mCurrentPositionMediator.mCurrentPositionMs);
        if (!Program.isProgramValid(currentProgram)) {
            currentProgram = null;
        }
        if (!Objects.equals(mCurrentProgram, currentProgram)) {
            if (DEBUG) Log.d(TAG, "Current program has been updated. " + currentProgram);
            mCurrentProgram = currentProgram;
            if (mNotificationEnabled && mOnCurrentProgramUpdatedListener != null) {
                Channel channel = mPlayController.getCurrentChannel();
                if (channel != null) {
                    mOnCurrentProgramUpdatedListener.onCurrentProgramUpdated(
                            channel.getId(), mCurrentProgram);
                    mPlayController.onCurrentProgramChanged();
                }
            }
        }
    }

    /**
     * Returns {@code true} if the trick play is available and it's playing to the forward direction
     * with normal speed, otherwise {@code false}.
     */
    public boolean isNormalPlaying() {
        return mPlayController.mAvailable
                && mPlayController.mPlayStatus == PLAY_STATUS_PLAYING
                && mPlayController.mPlayDirection == PLAY_DIRECTION_FORWARD
                && mPlayController.mDisplayedPlaySpeed == PLAY_SPEED_1X;
    }

    /** Checks if the trick play is available and it's playback status is paused. */
    public boolean isPaused() {
        return mPlayController.mAvailable && mPlayController.mPlayStatus == PLAY_STATUS_PAUSED;
    }

    /** Returns the program which airs at the given time. */
    @NonNull
    public Program getProgramAt(long timeMs) {
        Program program = mProgramManager.getProgramAt(timeMs);
        if (program == null) {
            // Guard just in case when the program prefetch handler doesn't work on time.
            mProgramManager.addDummyProgramsAt(timeMs);
            program = mProgramManager.getProgramAt(timeMs);
        }
        return program;
    }

    void onAvailabilityChanged() {
        mCurrentPositionMediator.initialize(mPlayController.mRecordStartTimeMs);
        mProgramManager.onAvailabilityChanged(
                mPlayController.mAvailable,
                mPlayController.getCurrentChannel(),
                mPlayController.mRecordStartTimeMs);
        updateActions();
        // Availability change notification should be always sent
        // even if mNotificationEnabled is false.
        if (mListener != null) {
            mListener.onAvailabilityChanged();
        }
    }

    void onRecordTimeRangeChanged() {
        if (mPlayController.mAvailable) {
            mProgramManager.onRecordTimeRangeChanged(
                    mPlayController.mRecordStartTimeMs, mPlayController.mRecordEndTimeMs);
        }
        updateActions();
        if (mNotificationEnabled && mListener != null) {
            mListener.onRecordTimeRangeChanged();
        }
    }

    void onCurrentPositionChanged() {
        updateActions();
        updateCurrentProgram();
        if (mNotificationEnabled && mListener != null) {
            mListener.onCurrentPositionChanged();
        }
    }

    void onPlayStatusChanged(@PlayStatus int status) {
        if (mNotificationEnabled && mListener != null) {
            mListener.onPlayStatusChanged(status);
        }
    }

    void onProgramInfoChanged() {
        updateCurrentProgram();
        if (mNotificationEnabled && mListener != null) {
            mListener.onProgramInfoChanged();
        }
    }

    /**
     * Returns the current program which airs right now.
     *
     * <p>If the program is a dummy program, which means there's no program information, returns
     * {@code null}.
     */
    @Nullable
    public Program getCurrentProgram() {
        if (isAvailable()) {
            return mCurrentProgram;
        }
        return null;
    }

    private int getPlaybackSpeed() {
        if (mPlayController.mDisplayedPlaySpeed == PLAY_SPEED_1X) {
            return 1;
        } else {
            long durationMs =
                    (getCurrentProgram() == null ? 0 : getCurrentProgram().getDurationMillis());
            if (mPlayController.mDisplayedPlaySpeed > PLAY_SPEED_5X) {
                Log.w(
                        TAG,
                        "Unknown displayed play speed is chosen : "
                                + mPlayController.mDisplayedPlaySpeed);
                return TimeShiftUtils.getMaxPlaybackSpeed(durationMs);
            } else {
                return TimeShiftUtils.getPlaybackSpeed(
                        mPlayController.mDisplayedPlaySpeed - PLAY_SPEED_2X, durationMs);
            }
        }
    }

    /** A class which controls the trick play. */
    private class PlayController {
        private final TunableTvView mTvView;

        private long mAvailablityChangedTimeMs;
        private long mRecordStartTimeMs;
        private long mRecordEndTimeMs;

        @PlayStatus private int mPlayStatus = PLAY_STATUS_PAUSED;
        @PlaySpeed private int mDisplayedPlaySpeed = PLAY_SPEED_1X;
        @PlayDirection private int mPlayDirection = PLAY_DIRECTION_FORWARD;
        private int mPlaybackSpeed;
        private boolean mAvailable;

        /**
         * Indicates that the trick play is not playing the current time position. It is set true
         * when {@link PlayController#pause}, {@link PlayController#rewind}, {@link
         * PlayController#fastForward} and {@link PlayController#seekTo} is called. If it is true,
         * the current time is equal to System.currentTimeMillis().
         */
        private boolean mIsPlayOffsetChanged;

        PlayController(TunableTvView tvView) {
            mTvView = tvView;
            mTvView.setTimeShiftListener(
                    new TimeShiftListener() {
                        @Override
                        public void onAvailabilityChanged() {
                            if (DEBUG) {
                                Log.d(
                                        TAG,
                                        "onAvailabilityChanged(available="
                                                + mTvView.isTimeShiftAvailable()
                                                + ")");
                            }
                            PlayController.this.onAvailabilityChanged();
                        }

                        @Override
                        public void onRecordStartTimeChanged(long recordStartTimeMs) {
                            if (!SoftPreconditions.checkState(
                                    mAvailable, TAG, "Trick play is not available.")) {
                                return;
                            }
                            if (recordStartTimeMs
                                    < mAvailablityChangedTimeMs - ALLOWED_START_TIME_OFFSET) {
                                Log.e(
                                        TAG,
                                        "The start time is too earlier than the time of availability: {"
                                                + "startTime: "
                                                + recordStartTimeMs
                                                + ", availability: "
                                                + mAvailablityChangedTimeMs);
                                return;
                            }
                            if (recordStartTimeMs > System.currentTimeMillis()) {
                                // The time reported by TvInputService might not consistent with
                                // system
                                // clock,, use system's current time instead.
                                Log.e(
                                        TAG,
                                        "The start time should not be earlier than the current time, "
                                                + "reset the start time to the system's current time: {"
                                                + "startTime: "
                                                + recordStartTimeMs
                                                + ", current time: "
                                                + System.currentTimeMillis());
                                recordStartTimeMs = System.currentTimeMillis();
                            }
                            if (mRecordStartTimeMs == recordStartTimeMs) {
                                return;
                            }
                            mRecordStartTimeMs = recordStartTimeMs;
                            TimeShiftManager.this.onRecordTimeRangeChanged();

                            // According to the UX guidelines, the stream should be resumed if the
                            // recording buffer fills up while paused, which means that the current
                            // time
                            // position is the same as or before the recording start time.
                            // But, for this application and the TIS, it's an erroneous and
                            // confusing
                            // situation if the current time position is before the recording start
                            // time.
                            // So, we recommend the TIS to keep the current time position greater
                            // than or
                            // equal to the recording start time.
                            // And here, we assume that the buffer is full if the current time
                            // position
                            // is nearly equal to the recording start time.
                            if (mPlayStatus == PLAY_STATUS_PAUSED
                                    && getCurrentPositionMs() - mRecordStartTimeMs
                                            < RECORDING_BOUNDARY_THRESHOLD) {
                                TimeShiftManager.this.play();
                            }
                        }
                    });
        }

        void onAvailabilityChanged() {
            boolean newAvailable = mTvView.isTimeShiftAvailable();
            if (mAvailable == newAvailable) {
                return;
            }
            mAvailable = newAvailable;
            // Do not send the notifications while the availability is changing,
            // because the variables are in the intermediate state.
            // For example, the current program can be null.
            mNotificationEnabled = false;
            mDisplayedPlaySpeed = PLAY_SPEED_1X;
            mPlaybackSpeed = 1;
            mPlayDirection = PLAY_DIRECTION_FORWARD;
            mHandler.removeMessages(MSG_GET_CURRENT_POSITION);

            if (mAvailable) {
                mAvailablityChangedTimeMs = System.currentTimeMillis();
                mIsPlayOffsetChanged = false;
                mRecordStartTimeMs = mAvailablityChangedTimeMs;
                mRecordEndTimeMs = CURRENT_TIME;
                // When the media availability message has come.
                mPlayController.setPlayStatus(PLAY_STATUS_PLAYING);
                mHandler.sendEmptyMessageDelayed(
                        MSG_GET_CURRENT_POSITION, REQUEST_CURRENT_POSITION_INTERVAL);
            } else {
                mAvailablityChangedTimeMs = INVALID_TIME;
                mIsPlayOffsetChanged = false;
                mRecordStartTimeMs = INVALID_TIME;
                mRecordEndTimeMs = INVALID_TIME;
                // When the tune command is sent.
                mPlayController.setPlayStatus(PLAY_STATUS_PAUSED);
            }
            TimeShiftManager.this.onAvailabilityChanged();
            mNotificationEnabled = true;
        }

        void handleGetCurrentPosition() {
            if (mIsPlayOffsetChanged) {
                long currentTimeMs =
                        mRecordEndTimeMs == CURRENT_TIME
                                ? System.currentTimeMillis()
                                : mRecordEndTimeMs;
                long currentPositionMs =
                        Math.max(
                                Math.min(mTvView.timeShiftGetCurrentPositionMs(), currentTimeMs),
                                mRecordStartTimeMs);
                boolean isCurrentTime =
                        currentTimeMs - currentPositionMs < RECORDING_BOUNDARY_THRESHOLD;
                long newCurrentPositionMs;
                if (isCurrentTime && isForwarding()) {
                    // It's playing forward and the current playing position reached
                    // the current system time. i.e. The live stream is played.
                    // Therefore no need to call TvView.timeShiftGetCurrentPositionMs
                    // any more.
                    newCurrentPositionMs = currentTimeMs;
                    mIsPlayOffsetChanged = false;
                    if (mDisplayedPlaySpeed > PLAY_SPEED_1X) {
                        TimeShiftManager.this.play();
                    }
                } else {
                    newCurrentPositionMs = currentPositionMs;
                    boolean isRecordStartTime =
                            currentPositionMs - mRecordStartTimeMs < RECORDING_BOUNDARY_THRESHOLD;
                    if (isRecordStartTime && isRewinding()) {
                        TimeShiftManager.this.play();
                    }
                }
                setCurrentPositionMs(newCurrentPositionMs);
            } else {
                setCurrentPositionMs(System.currentTimeMillis());
                TimeShiftManager.this.onCurrentPositionChanged();
            }
            // Need to send message here just in case there is no or invalid response
            // for the current time position request from TIS.
            mHandler.sendEmptyMessageDelayed(
                    MSG_GET_CURRENT_POSITION, REQUEST_CURRENT_POSITION_INTERVAL);
        }

        void play() {
            mDisplayedPlaySpeed = PLAY_SPEED_1X;
            mPlaybackSpeed = 1;
            mPlayDirection = PLAY_DIRECTION_FORWARD;
            mTvView.timeShiftPlay();
            setPlayStatus(PLAY_STATUS_PLAYING);
        }

        void pause() {
            mDisplayedPlaySpeed = PLAY_SPEED_1X;
            mPlaybackSpeed = 1;
            mTvView.timeShiftPause();
            setPlayStatus(PLAY_STATUS_PAUSED);
            mIsPlayOffsetChanged = true;
        }

        void togglePlayPause() {
            if (mPlayStatus == PLAY_STATUS_PAUSED) {
                play();
                mTracker.sendTimeShiftAction(TIME_SHIFT_ACTION_ID_PLAY);
            } else {
                pause();
                mTracker.sendTimeShiftAction(TIME_SHIFT_ACTION_ID_PAUSE);
            }
        }

        void rewind() {
            if (mPlayDirection == PLAY_DIRECTION_BACKWARD) {
                increaseDisplayedPlaySpeed();
            } else {
                mDisplayedPlaySpeed = PLAY_SPEED_2X;
            }
            mPlayDirection = PLAY_DIRECTION_BACKWARD;
            mPlaybackSpeed = getPlaybackSpeed();
            mTvView.timeShiftRewind(mPlaybackSpeed);
            setPlayStatus(PLAY_STATUS_PLAYING);
            mIsPlayOffsetChanged = true;
        }

        void fastForward() {
            if (mPlayDirection == PLAY_DIRECTION_FORWARD) {
                increaseDisplayedPlaySpeed();
            } else {
                mDisplayedPlaySpeed = PLAY_SPEED_2X;
            }
            mPlayDirection = PLAY_DIRECTION_FORWARD;
            mPlaybackSpeed = getPlaybackSpeed();
            mTvView.timeShiftFastForward(mPlaybackSpeed);
            setPlayStatus(PLAY_STATUS_PLAYING);
            mIsPlayOffsetChanged = true;
        }

        /** Moves to the specified time. */
        void seekTo(long timeMs) {
            mTvView.timeShiftSeekTo(
                    Math.min(
                            mRecordEndTimeMs == CURRENT_TIME
                                    ? System.currentTimeMillis()
                                    : mRecordEndTimeMs,
                            Math.max(mRecordStartTimeMs, timeMs)));
            mIsPlayOffsetChanged = true;
        }

        void onCurrentProgramChanged() {
            // Update playback speed
            if (mDisplayedPlaySpeed == PLAY_SPEED_1X) {
                return;
            }
            int playbackSpeed = getPlaybackSpeed();
            if (playbackSpeed != mPlaybackSpeed) {
                mPlaybackSpeed = playbackSpeed;
                if (mPlayDirection == PLAY_DIRECTION_FORWARD) {
                    mTvView.timeShiftFastForward(mPlaybackSpeed);
                } else {
                    mTvView.timeShiftRewind(mPlaybackSpeed);
                }
            }
        }

        @SuppressLint("SwitchIntDef")
        private void increaseDisplayedPlaySpeed() {
            switch (mDisplayedPlaySpeed) {
                case PLAY_SPEED_1X:
                    mDisplayedPlaySpeed = PLAY_SPEED_2X;
                    break;
                case PLAY_SPEED_2X:
                    mDisplayedPlaySpeed = PLAY_SPEED_3X;
                    break;
                case PLAY_SPEED_3X:
                    mDisplayedPlaySpeed = PLAY_SPEED_4X;
                    break;
                case PLAY_SPEED_4X:
                    mDisplayedPlaySpeed = PLAY_SPEED_5X;
                    break;
            }
        }

        private void setPlayStatus(@PlayStatus int status) {
            mPlayStatus = status;
            TimeShiftManager.this.onPlayStatusChanged(status);
        }

        boolean isForwarding() {
            return mPlayStatus == PLAY_STATUS_PLAYING && mPlayDirection == PLAY_DIRECTION_FORWARD;
        }

        private boolean isRewinding() {
            return mPlayStatus == PLAY_STATUS_PLAYING && mPlayDirection == PLAY_DIRECTION_BACKWARD;
        }

        Channel getCurrentChannel() {
            return mTvView.getCurrentChannel();
        }
    }

    private class ProgramManager {
        private final ProgramDataManager mProgramDataManager;
        private Channel mChannel;
        private final List<Program> mPrograms = new ArrayList<>();
        private final Queue<Range<Long>> mProgramLoadQueue = new LinkedList<>();
        private LoadProgramsForCurrentChannelTask mProgramLoadTask = null;
        private int mEmptyFetchCount = 0;

        ProgramManager(ProgramDataManager programDataManager) {
            mProgramDataManager = programDataManager;
        }

        void onAvailabilityChanged(boolean available, Channel channel, long currentPositionMs) {
            if (DEBUG) {
                Log.d(
                        TAG,
                        "onAvailabilityChanged("
                                + available
                                + "+,"
                                + channel
                                + ", "
                                + currentPositionMs
                                + ")");
            }

            mProgramLoadQueue.clear();
            if (mProgramLoadTask != null) {
                mProgramLoadTask.cancel(true);
            }
            mHandler.removeMessages(MSG_PREFETCH_PROGRAM);
            mPrograms.clear();
            mEmptyFetchCount = 0;
            mChannel = channel;
            if (channel == null || channel.isPassthrough() || currentPositionMs == INVALID_TIME) {
                return;
            }
            if (available) {
                Program program = mProgramDataManager.getCurrentProgram(channel.getId());
                long prefetchStartTimeMs;
                if (program != null) {
                    mPrograms.add(program);
                    prefetchStartTimeMs = program.getEndTimeUtcMillis();
                } else {
                    prefetchStartTimeMs =
                            Utils.floorTime(currentPositionMs, MAX_DUMMY_PROGRAM_DURATION);
                }
                // Create dummy program
                mPrograms.addAll(
                        createDummyPrograms(
                                prefetchStartTimeMs,
                                currentPositionMs + PREFETCH_DURATION_FOR_NEXT));
                schedulePrefetchPrograms();
                TimeShiftManager.this.onProgramInfoChanged();
            }
        }

        void onRecordTimeRangeChanged(long startTimeMs, long endTimeMs) {
            if (mChannel == null || mChannel.isPassthrough()) {
                return;
            }
            if (endTimeMs == CURRENT_TIME) {
                endTimeMs = System.currentTimeMillis();
            }

            long fetchStartTimeMs = Utils.floorTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
            long fetchEndTimeMs =
                    Utils.ceilTime(
                            endTimeMs + PREFETCH_DURATION_FOR_NEXT, MAX_DUMMY_PROGRAM_DURATION);
            removeOutdatedPrograms(fetchStartTimeMs);
            boolean needToLoad = addDummyPrograms(fetchStartTimeMs, fetchEndTimeMs);
            if (needToLoad) {
                Range<Long> period = Range.create(fetchStartTimeMs, fetchEndTimeMs);
                mProgramLoadQueue.add(period);
                startTaskIfNeeded();
            }
        }

        private void startTaskIfNeeded() {
            if (mProgramLoadQueue.isEmpty()) {
                return;
            }
            if (mProgramLoadTask == null || mProgramLoadTask.isCancelled()) {
                startNext();
            } else {
                // Remove pending task fully satisfied by the current
                Range<Long> current = mProgramLoadTask.getPeriod();
                Iterator<Range<Long>> i = mProgramLoadQueue.iterator();
                while (i.hasNext()) {
                    Range<Long> r = i.next();
                    if (current.contains(r)) {
                        i.remove();
                    }
                }
            }
        }

        private void startNext() {
            mProgramLoadTask = null;
            if (mProgramLoadQueue.isEmpty()) {
                return;
            }

            Range<Long> next = mProgramLoadQueue.poll();
            // Extend next to include any overlapping Ranges.
            Iterator<Range<Long>> i = mProgramLoadQueue.iterator();
            while (i.hasNext()) {
                Range<Long> r = i.next();
                if (next.contains(r.getLower()) || next.contains(r.getUpper())) {
                    i.remove();
                    next = next.extend(r);
                }
            }
            if (mChannel != null) {
                mProgramLoadTask = new LoadProgramsForCurrentChannelTask(next);
                mProgramLoadTask.executeOnDbThread();
            }
        }

        void addDummyProgramsAt(long timeMs) {
            addDummyPrograms(timeMs, timeMs + PREFETCH_DURATION_FOR_NEXT);
        }

        private boolean addDummyPrograms(Range<Long> period) {
            return addDummyPrograms(period.getLower(), period.getUpper());
        }

        private boolean addDummyPrograms(long startTimeMs, long endTimeMs) {
            boolean added = false;
            if (mPrograms.isEmpty()) {
                // Insert dummy program.
                mPrograms.addAll(createDummyPrograms(startTimeMs, endTimeMs));
                return true;
            }
            // Insert dummy program to the head of the list if needed.
            Program firstProgram = mPrograms.get(0);
            if (startTimeMs < firstProgram.getStartTimeUtcMillis()) {
                if (!firstProgram.isValid()) {
                    // Already the firstProgram is dummy.
                    mPrograms.remove(0);
                    mPrograms.addAll(
                            0,
                            createDummyPrograms(startTimeMs, firstProgram.getEndTimeUtcMillis()));
                } else {
                    mPrograms.addAll(
                            0,
                            createDummyPrograms(startTimeMs, firstProgram.getStartTimeUtcMillis()));
                }
                added = true;
            }
            // Insert dummy program to the tail of the list if needed.
            Program lastProgram = mPrograms.get(mPrograms.size() - 1);
            if (endTimeMs > lastProgram.getEndTimeUtcMillis()) {
                if (!lastProgram.isValid()) {
                    // Already the lastProgram is dummy.
                    mPrograms.remove(mPrograms.size() - 1);
                    mPrograms.addAll(
                            createDummyPrograms(lastProgram.getStartTimeUtcMillis(), endTimeMs));
                } else {
                    mPrograms.addAll(
                            createDummyPrograms(lastProgram.getEndTimeUtcMillis(), endTimeMs));
                }
                added = true;
            }
            // Insert dummy programs if the holes exist in the list.
            for (int i = 1; i < mPrograms.size(); ++i) {
                long endOfPrevious = mPrograms.get(i - 1).getEndTimeUtcMillis();
                long startOfCurrent = mPrograms.get(i).getStartTimeUtcMillis();
                if (startOfCurrent > endOfPrevious) {
                    List<Program> dummyPrograms =
                            createDummyPrograms(endOfPrevious, startOfCurrent);
                    mPrograms.addAll(i, dummyPrograms);
                    i += dummyPrograms.size();
                    added = true;
                }
            }
            return added;
        }

        private void removeOutdatedPrograms(long startTimeMs) {
            while (mPrograms.size() > 0 && mPrograms.get(0).getEndTimeUtcMillis() <= startTimeMs) {
                mPrograms.remove(0);
            }
        }

        private void removeDummyPrograms() {
            for (Iterator<Program> it = mPrograms.listIterator(); it.hasNext(); ) {
                if (!it.next().isValid()) {
                    it.remove();
                }
            }
        }

        private void removeOverlappedPrograms(List<Program> loadedPrograms) {
            if (mPrograms.size() == 0) {
                return;
            }
            Program program = mPrograms.get(0);
            for (int i = 0, j = 0; i < mPrograms.size() && j < loadedPrograms.size(); ++j) {
                Program loadedProgram = loadedPrograms.get(j);
                // Skip previous programs.
                while (program.getEndTimeUtcMillis() <= loadedProgram.getStartTimeUtcMillis()) {
                    // Reached end of mPrograms.
                    if (++i == mPrograms.size()) {
                        return;
                    }
                    program = mPrograms.get(i);
                }
                // Remove overlapped programs.
                while (program.getStartTimeUtcMillis() < loadedProgram.getEndTimeUtcMillis()
                        && program.getEndTimeUtcMillis() > loadedProgram.getStartTimeUtcMillis()) {
                    mPrograms.remove(i);
                    if (i >= mPrograms.size()) {
                        break;
                    }
                    program = mPrograms.get(i);
                }
            }
        }

        // Returns a list of dummy programs.
        // The maximum duration of a dummy program is {@link MAX_DUMMY_PROGRAM_DURATION}.
        // So if the duration ({@code endTimeMs}-{@code startTimeMs}) is greater than the duration,
        // we need to create multiple dummy programs.
        // The reason of the limitation of the duration is because we want the trick play viewer
        // to show the time-line duration of {@link MAX_DUMMY_PROGRAM_DURATION} at most
        // for a dummy program.
        private List<Program> createDummyPrograms(long startTimeMs, long endTimeMs) {
            SoftPreconditions.checkArgument(
                    endTimeMs - startTimeMs <= TWO_WEEKS_MS,
                    TAG,
                    "createDummyProgram: long duration of dummy programs are requested ( %s , %s)",
                    Utils.toTimeString(startTimeMs),
                    Utils.toTimeString(endTimeMs));
            if (startTimeMs >= endTimeMs) {
                return Collections.emptyList();
            }
            List<Program> programs = new ArrayList<>();
            long start = startTimeMs;
            long end = Utils.ceilTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
            while (end < endTimeMs) {
                programs.add(
                        new Program.Builder()
                                .setStartTimeUtcMillis(start)
                                .setEndTimeUtcMillis(end)
                                .build());
                start = end;
                end += MAX_DUMMY_PROGRAM_DURATION;
            }
            programs.add(
                    new Program.Builder()
                            .setStartTimeUtcMillis(start)
                            .setEndTimeUtcMillis(endTimeMs)
                            .build());
            return programs;
        }

        Program getProgramAt(long timeMs) {
            return getProgramAt(timeMs, 0, mPrograms.size() - 1);
        }

        private Program getProgramAt(long timeMs, int start, int end) {
            if (start > end) {
                return null;
            }
            int mid = (start + end) / 2;
            Program program = mPrograms.get(mid);
            if (program.getStartTimeUtcMillis() > timeMs) {
                return getProgramAt(timeMs, start, mid - 1);
            } else if (program.getEndTimeUtcMillis() <= timeMs) {
                return getProgramAt(timeMs, mid + 1, end);
            } else {
                return program;
            }
        }

        private long getOldestProgramStartTime() {
            if (mPrograms.isEmpty()) {
                return INVALID_TIME;
            }
            return mPrograms.get(0).getStartTimeUtcMillis();
        }

        private Program getLastValidProgram() {
            for (int i = mPrograms.size() - 1; i >= 0; --i) {
                Program program = mPrograms.get(i);
                if (program.isValid()) {
                    return program;
                }
            }
            return null;
        }

        private void schedulePrefetchPrograms() {
            if (DEBUG) Log.d(TAG, "Scheduling prefetching programs.");
            if (mHandler.hasMessages(MSG_PREFETCH_PROGRAM)) {
                return;
            }
            Program lastValidProgram = getLastValidProgram();
            if (DEBUG) Log.d(TAG, "Last valid program = " + lastValidProgram);
            final long delay;
            if (lastValidProgram != null) {
                delay =
                        lastValidProgram.getEndTimeUtcMillis()
                                - PREFETCH_TIME_OFFSET_FROM_PROGRAM_END
                                - System.currentTimeMillis();
            } else {
                // Since there might not be any program data delay the retry 5 seconds,
                // then 30 seconds then 5 minutes
                switch (mEmptyFetchCount) {
                    case 0:
                        delay = 0;
                        break;
                    case 1:
                        delay = TimeUnit.SECONDS.toMillis(5);
                        break;
                    case 2:
                        delay = TimeUnit.SECONDS.toMillis(30);
                        break;
                    default:
                        delay = TimeUnit.MINUTES.toMillis(5);
                        break;
                }
                if (DEBUG) {
                    Log.d(
                            TAG,
                            "No last valid  program. Already tried " + mEmptyFetchCount + " times");
                }
            }
            mHandler.sendEmptyMessageDelayed(MSG_PREFETCH_PROGRAM, delay);
            if (DEBUG) Log.d(TAG, "Scheduling with " + delay + "(ms) delays.");
        }

        // Prefetch programs within PREFETCH_DURATION_FOR_NEXT from now.
        private void prefetchPrograms() {
            long startTimeMs;
            Program lastValidProgram = getLastValidProgram();
            if (lastValidProgram == null) {
                startTimeMs = System.currentTimeMillis();
            } else {
                startTimeMs = lastValidProgram.getEndTimeUtcMillis();
            }
            long endTimeMs = System.currentTimeMillis() + PREFETCH_DURATION_FOR_NEXT;
            if (startTimeMs <= endTimeMs) {
                if (DEBUG) {
                    Log.d(
                            TAG,
                            "Prefetch task starts: {startTime="
                                    + Utils.toTimeString(startTimeMs)
                                    + ", endTime="
                                    + Utils.toTimeString(endTimeMs)
                                    + "}");
                }
                mProgramLoadQueue.add(Range.create(startTimeMs, endTimeMs));
            }
            startTaskIfNeeded();
        }

        private class LoadProgramsForCurrentChannelTask
                extends AsyncDbTask.LoadProgramsForChannelTask {

            LoadProgramsForCurrentChannelTask(Range<Long> period) {
                super(
                        TvSingletons.getSingletons(mContext).getDbExecutor(),
                        mContext,
                        mChannel.getId(),
                        period);
            }

            @Override
            protected void onPostExecute(List<Program> programs) {
                if (DEBUG) {
                    Log.d(
                            TAG,
                            "Programs are loaded {channelId="
                                    + mChannelId
                                    + ", from="
                                    + Utils.toTimeString(mPeriod.getLower())
                                    + ", to="
                                    + Utils.toTimeString(mPeriod.getUpper())
                                    + "}");
                }
                // remove pending tasks that are fully satisfied by this query.
                Iterator<Range<Long>> it = mProgramLoadQueue.iterator();
                while (it.hasNext()) {
                    Range<Long> r = it.next();
                    if (mPeriod.contains(r)) {
                        it.remove();
                    }
                }
                if (programs == null || programs.isEmpty()) {
                    mEmptyFetchCount++;
                    if (addDummyPrograms(mPeriod)) {
                        TimeShiftManager.this.onProgramInfoChanged();
                    }
                    schedulePrefetchPrograms();
                    startNextLoadingIfNeeded();
                    return;
                }
                mEmptyFetchCount = 0;
                if (!mPrograms.isEmpty()) {
                    removeDummyPrograms();
                    removeOverlappedPrograms(programs);
                    Program loadedProgram = programs.get(0);
                    for (int i = 0; i < mPrograms.size() && !programs.isEmpty(); ++i) {
                        Program program = mPrograms.get(i);
                        while (program.getStartTimeUtcMillis()
                                > loadedProgram.getStartTimeUtcMillis()) {
                            mPrograms.add(i++, loadedProgram);
                            programs.remove(0);
                            if (programs.isEmpty()) {
                                break;
                            }
                            loadedProgram = programs.get(0);
                        }
                    }
                }
                mPrograms.addAll(programs);
                addDummyPrograms(mPeriod);
                TimeShiftManager.this.onProgramInfoChanged();
                schedulePrefetchPrograms();
                startNextLoadingIfNeeded();
            }

            @Override
            protected void onCancelled(List<Program> programs) {
                if (DEBUG) {
                    Log.d(
                            TAG,
                            "Program loading has been canceled {channelId="
                                    + (mChannel == null ? "null" : mChannelId)
                                    + ", from="
                                    + Utils.toTimeString(mPeriod.getLower())
                                    + ", to="
                                    + Utils.toTimeString(mPeriod.getUpper())
                                    + "}");
                }
                startNextLoadingIfNeeded();
            }

            private void startNextLoadingIfNeeded() {
                if (mProgramLoadTask == this) {
                    mProgramLoadTask = null;
                }
                // Need to post to handler, because the task is still running.
                mHandler.post(ProgramManager.this::startTaskIfNeeded);
            }

            boolean overlaps(Queue<Range<Long>> programLoadQueue) {
                for (Range<Long> r : programLoadQueue) {
                    if (mPeriod.contains(r.getLower()) || mPeriod.contains(r.getUpper())) {
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @VisibleForTesting
    final class CurrentPositionMediator {
        long mCurrentPositionMs;
        long mSeekRequestTimeMs;

        void initialize(long timeMs) {
            mSeekRequestTimeMs = INVALID_TIME;
            mCurrentPositionMs = timeMs;
            if (timeMs != INVALID_TIME) {
                TimeShiftManager.this.onCurrentPositionChanged();
            }
        }

        void onSeekRequested(long seekTimeMs) {
            mSeekRequestTimeMs = System.currentTimeMillis();
            mCurrentPositionMs = seekTimeMs;
            TimeShiftManager.this.onCurrentPositionChanged();
        }

        void onCurrentPositionChanged(long currentPositionMs) {
            if (mSeekRequestTimeMs == INVALID_TIME) {
                mCurrentPositionMs = currentPositionMs;
                TimeShiftManager.this.onCurrentPositionChanged();
                return;
            }
            long currentTimeMs = System.currentTimeMillis();
            boolean isValid = Math.abs(currentPositionMs - mCurrentPositionMs) < REQUEST_TIMEOUT_MS;
            boolean isTimeout = currentTimeMs > mSeekRequestTimeMs + REQUEST_TIMEOUT_MS;
            if (isValid || isTimeout) {
                initialize(currentPositionMs);
            } else {
                if (getPlayStatus() == PLAY_STATUS_PLAYING) {
                    if (getPlayDirection() == PLAY_DIRECTION_FORWARD) {
                        mCurrentPositionMs +=
                                (currentTimeMs - mSeekRequestTimeMs) * getPlaybackSpeed();
                    } else {
                        mCurrentPositionMs -=
                                (currentTimeMs - mSeekRequestTimeMs) * getPlaybackSpeed();
                    }
                }
                TimeShiftManager.this.onCurrentPositionChanged();
            }
        }
    }

    /** The listener used to receive the events by the time-shift manager */
    public interface Listener {
        /**
         * Called when the availability of the time-shift for the current channel has been changed.
         * If the time shift is available, {@link TimeShiftManager#getRecordStartTimeMs} should
         * return the valid time.
         */
        void onAvailabilityChanged();

        /**
         * Called when the play status is changed between {@link #PLAY_STATUS_PLAYING} and {@link
         * #PLAY_STATUS_PAUSED}
         *
         * @param status The new play state.
         */
        void onPlayStatusChanged(int status);

        /** Called when the recordStartTime has been changed. */
        void onRecordTimeRangeChanged();

        /** Called when the current position is changed. */
        void onCurrentPositionChanged();

        /** Called when the program information is updated. */
        void onProgramInfoChanged();

        /** Called when an action becomes enabled or disabled. */
        void onActionEnabledChanged(@TimeShiftActionId int actionId, boolean enabled);
    }

    private static class TimeShiftHandler extends WeakHandler<TimeShiftManager> {
        TimeShiftHandler(TimeShiftManager ref) {
            super(ref);
        }

        @Override
        public void handleMessage(Message msg, @NonNull TimeShiftManager timeShiftManager) {
            switch (msg.what) {
                case MSG_GET_CURRENT_POSITION:
                    timeShiftManager.mPlayController.handleGetCurrentPosition();
                    break;
                case MSG_PREFETCH_PROGRAM:
                    timeShiftManager.mProgramManager.prefetchPrograms();
                    break;
            }
        }
    }
}
