/*
 * 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.ContentResolver;
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.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(mContext.getContentResolver(), 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(ContentResolver contentResolver, Range<Long> period) {
                super(
                        TvSingletons.getSingletons(mContext).getDbExecutor(),
                        contentResolver,
                        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(
                        new Runnable() {
                            @Override
                            public void run() {
                                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;
            }
        }
    }
}
