/*
 * 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.ProgramDataManager;
import com.android.tv.data.ProgramImpl;
import com.android.tv.data.api.Channel;
import com.android.tv.data.api.Program;
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 TV app. 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 TV app. 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 ProgramImpl.Builder()
                                .setStartTimeUtcMillis(start)
                                .setEndTimeUtcMillis(end)
                                .build());
                start = end;
                end += MAX_DUMMY_PROGRAM_DURATION;
            }
            programs.add(
                    new ProgramImpl.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;
            }
        }
    }
}
