/*
 * 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.ui;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.app.AlertDialog;
import android.app.ApplicationErrorReport;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
import android.media.tv.TvView.OnUnhandledInputEventListener;
import android.media.tv.TvView.TvInputCallback;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.android.tv.ApplicationSingletons;
import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.DurationTimer;
import com.android.tv.util.Debug;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.util.ImageLoader;
import com.android.tv.util.NetworkUtils;
import com.android.tv.util.PermissionUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

public class TunableTvView extends FrameLayout implements StreamInfo {
    private static final boolean DEBUG = false;
    private static final String TAG = "TunableTvView";

    public static final int VIDEO_UNAVAILABLE_REASON_NOT_TUNED = -1;
    public static final int VIDEO_UNAVAILABLE_REASON_NO_RESOURCE = -2;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({BLOCK_SCREEN_TYPE_NO_UI, BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW, BLOCK_SCREEN_TYPE_NORMAL})
    public @interface BlockScreenType {}
    public static final int BLOCK_SCREEN_TYPE_NO_UI = 0;
    public static final int BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW = 1;
    public static final int BLOCK_SCREEN_TYPE_NORMAL = 2;

    private static final String PERMISSION_RECEIVE_INPUT_EVENT =
            "com.android.tv.permission.RECEIVE_INPUT_EVENT";

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({ TIME_SHIFT_STATE_NONE, TIME_SHIFT_STATE_PLAY, TIME_SHIFT_STATE_PAUSE,
            TIME_SHIFT_STATE_REWIND, TIME_SHIFT_STATE_FAST_FORWARD })
    private @interface TimeShiftState {}
    private static final int TIME_SHIFT_STATE_NONE = 0;
    private static final int TIME_SHIFT_STATE_PLAY = 1;
    private static final int TIME_SHIFT_STATE_PAUSE = 2;
    private static final int TIME_SHIFT_STATE_REWIND = 3;
    private static final int TIME_SHIFT_STATE_FAST_FORWARD = 4;

    private static final int FADED_IN = 0;
    private static final int FADED_OUT = 1;
    private static final int FADING_IN = 2;
    private static final int FADING_OUT = 3;

    private AppLayerTvView mTvView;
    private TvViewSession mTvViewSession;
    private Channel mCurrentChannel;
    private TvInputManagerHelper mInputManagerHelper;
    private ContentRatingsManager mContentRatingsManager;
    private ParentalControlSettings mParentalControlSettings;
    private ProgramDataManager mProgramDataManager;
    @Nullable
    private WatchedHistoryManager mWatchedHistoryManager;
    private boolean mStarted;
    private TvInputInfo mInputInfo;
    private OnTuneListener mOnTuneListener;
    private int mVideoWidth;
    private int mVideoHeight;
    private int mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
    private float mVideoFrameRate;
    private float mVideoDisplayAspectRatio;
    private int mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
    private boolean mHasClosedCaption = false;
    private boolean mVideoAvailable;
    private boolean mAudioAvailable;
    private boolean mScreenBlocked;
    private OnScreenBlockingChangedListener mOnScreenBlockedListener;
    private TvContentRating mBlockedContentRating;
    private int mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NOT_TUNED;
    private boolean mCanReceiveInputEvent;
    private boolean mIsMuted;
    private float mVolume;
    private boolean mParentControlEnabled;
    private int mFixedSurfaceWidth;
    private int mFixedSurfaceHeight;
    private final boolean mCanModifyParentalControls;
    private boolean mIsUnderShrunken;

    @TimeShiftState private int mTimeShiftState = TIME_SHIFT_STATE_NONE;
    private TimeShiftListener mTimeShiftListener;
    private boolean mTimeShiftAvailable;
    private long mTimeShiftCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;

    private final Tracker mTracker;
    private final DurationTimer mChannelViewTimer = new DurationTimer();
    private InternetCheckTask mInternetCheckTask;

    // A block screen view which has lock icon with black background.
    // This indicates that user's action is needed to play video.
    private final BlockScreenView mBlockScreenView;

    // A View to hide screen when there's problem in video playback.
    private final BlockScreenView mHideScreenView;
    private final int mHideScreenImageColorFilter;

    // A spinner view to show buffering status.
    private final View mBufferingSpinnerView;
    private TuningBlockView mTuningBlockView;

    // A View to block screen until onContentAllowed is received if parental control is on.
    private final View mBlockScreenForTuneView;

    // A View for fade-in/out animation
    private final View mDimScreenView;
    private int mFadeState = FADED_IN;
    private Runnable mActionAfterFade;

    @BlockScreenType private int mBlockScreenType;

    private final TvInputManagerHelper mInputManager;
    private final ConnectivityManager mConnectivityManager;
    private final InputSessionManager mInputSessionManager;

    private final TvInputCallback mCallback = new TvInputCallback() {
        @Override
        public void onConnectionFailed(String inputId) {
            Log.w(TAG, "Failed to bind an input");
            mTracker.sendInputConnectionFailure(inputId);
            Channel channel = mCurrentChannel;
            mCurrentChannel = null;
            mInputInfo = null;
            mCanReceiveInputEvent = false;
            if (mOnTuneListener != null) {
                // If tune is called inside onTuneFailed, mOnTuneListener will be set to
                // a new instance. In order to avoid to clear the new mOnTuneListener,
                // we copy mOnTuneListener to l and clear mOnTuneListener before
                // calling onTuneFailed.
                OnTuneListener listener = mOnTuneListener;
                mOnTuneListener = null;
                listener.onTuneFailed(channel);
            }
        }

        @Override
        public void onDisconnected(String inputId) {
            Log.w(TAG, "Session is released by crash");
            mTracker.sendInputDisconnected(inputId);
            Channel channel = mCurrentChannel;
            mCurrentChannel = null;
            mInputInfo = null;
            mCanReceiveInputEvent = false;
            if (mOnTuneListener != null) {
                OnTuneListener listener = mOnTuneListener;
                mOnTuneListener = null;
                listener.onUnexpectedStop(channel);
            }
        }

        @Override
        public void onChannelRetuned(String inputId, Uri channelUri) {
            if (DEBUG) {
                Log.d(TAG, "onChannelRetuned(inputId=" + inputId + ", channelUri="
                        + channelUri + ")");
            }
            if (mOnTuneListener != null) {
                mOnTuneListener.onChannelRetuned(channelUri);
            }
        }

        @Override
        public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
            mHasClosedCaption = false;
            for (TvTrackInfo track : tracks) {
                if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
                    mHasClosedCaption = true;
                    break;
                }
            }
            if (mOnTuneListener != null) {
                mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
            }
        }

        @Override
        public void onTrackSelected(String inputId, int type, String trackId) {
            if (trackId == null) {
                // A track is unselected.
                if (type == TvTrackInfo.TYPE_VIDEO) {
                    mVideoWidth = 0;
                    mVideoHeight = 0;
                    mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
                    mVideoFrameRate = 0f;
                    mVideoDisplayAspectRatio = 0f;
                } else if (type == TvTrackInfo.TYPE_AUDIO) {
                    mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
                }
            } else {
                List<TvTrackInfo> tracks = getTracks(type);
                boolean trackFound = false;
                if (tracks != null) {
                    for (TvTrackInfo track : tracks) {
                        if (track.getId().equals(trackId)) {
                            if (type == TvTrackInfo.TYPE_VIDEO) {
                                mVideoWidth = track.getVideoWidth();
                                mVideoHeight = track.getVideoHeight();
                                mVideoFormat = Utils.getVideoDefinitionLevelFromSize(
                                        mVideoWidth, mVideoHeight);
                                mVideoFrameRate = track.getVideoFrameRate();
                                if (mVideoWidth <= 0 || mVideoHeight <= 0) {
                                    mVideoDisplayAspectRatio = 0.0f;
                                } else {
                                    float VideoPixelAspectRatio =
                                            track.getVideoPixelAspectRatio();
                                    mVideoDisplayAspectRatio = VideoPixelAspectRatio
                                            * mVideoWidth / mVideoHeight;
                                }
                            } else if (type == TvTrackInfo.TYPE_AUDIO) {
                                mAudioChannelCount = track.getAudioChannelCount();
                            }
                            trackFound = true;
                            break;
                        }
                    }
                }
                if (!trackFound) {
                    Log.w(TAG, "Invalid track ID: " + trackId);
                }
            }
            if (mOnTuneListener != null) {
                mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
            }
        }

        @Override
        public void onVideoAvailable(String inputId) {
            if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
            Debug.getTimer(Debug.TAG_START_UP_TIMER).log("Start up of Live TV ends," +
                    " TunableTvView.onVideoAvailable resets timer");
            long startUpDurationTime = Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
            Debug.removeTimer(Debug.TAG_START_UP_TIMER);
            if (BuildConfig.ENG
                    && startUpDurationTime > Debug.TIME_START_UP_DURATION_THRESHOLD) {
                showAlertDialogForLongStartUp();
            }
            unhideScreenByVideoAvailability();
            if (mOnTuneListener != null) {
                mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
            }
        }

        private void showAlertDialogForLongStartUp() {
            new AlertDialog.Builder(getContext()).setTitle(
                    getContext().getString(R.string.settings_send_feedback))
                    .setMessage("Because the start up time of Live channels is too long," +
                            " please send feedback")
                    .setPositiveButton(android.R.string.ok,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    Intent intent = new Intent(Intent.ACTION_APP_ERROR);
                                    ApplicationErrorReport report = new ApplicationErrorReport();
                                    report.packageName = report.processName = getContext()
                                            .getApplicationContext().getPackageName();
                                    report.time = System.currentTimeMillis();
                                    report.type = ApplicationErrorReport.TYPE_CRASH;

                                    // Add the crash info to add title of feedback automatically.
                                    ApplicationErrorReport.CrashInfo crash = new
                                            ApplicationErrorReport.CrashInfo();
                                    crash.exceptionClassName =
                                            "Live TV start up takes long time";
                                    crash.exceptionMessage =
                                            "The start up time of Live TV is too long";
                                    report.crashInfo = crash;

                                    intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
                                    getContext().startActivity(intent);
                                }
                            })
                    .setNegativeButton(android.R.string.no, null)
                    .show();
        }

        @Override
        public void onVideoUnavailable(String inputId, int reason) {
            if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
                    && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
                Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
                        "TunableTvView.onVideoUnAvailable reason = (" + reason
                                + ") and removes timer");
                Debug.removeTimer(Debug.TAG_START_UP_TIMER);
            } else {
                Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
                        "TunableTvView.onVideoUnAvailable reason = (" + reason + ")");
            }
            hideScreenByVideoAvailability(inputId, reason);
            if (mOnTuneListener != null) {
                mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
            }
            switch (reason) {
                case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
                case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
                case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
                    mTracker.sendChannelVideoUnavailable(mCurrentChannel, reason);
                default:
                    // do nothing
            }
        }

        @Override
        public void onContentAllowed(String inputId) {
            mBlockScreenForTuneView.setVisibility(View.GONE);
            mBlockedContentRating = null;
            checkBlockScreenAndMuteNeeded();
            if (mOnTuneListener != null) {
                mOnTuneListener.onContentAllowed();
            }
        }

        @Override
        public void onContentBlocked(String inputId, TvContentRating rating) {
            mBlockedContentRating = rating;
            checkBlockScreenAndMuteNeeded();
            if (mOnTuneListener != null) {
                mOnTuneListener.onContentBlocked();
            }
        }

        @Override
        public void onTimeShiftStatusChanged(String inputId, int status) {
            if (DEBUG) {
                Log.d(TAG, "onTimeShiftStatusChanged: {inputId=" + inputId + ", status=" + status +
                        "}");
            }
            boolean available = status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;
            setTimeShiftAvailable(available);
        }
    };

    public TunableTvView(Context context) {
        this(context, null);
    }

    public TunableTvView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        inflate(getContext(), R.layout.tunable_tv_view, this);

        ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
        if (CommonFeatures.DVR.isEnabled(context)) {
            mInputSessionManager = appSingletons.getInputSessionManager();
        } else {
            mInputSessionManager = null;
        }
        mInputManager = appSingletons.getTvInputManagerHelper();
        mConnectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        mCanModifyParentalControls = PermissionUtils.hasModifyParentalControls(context);
        mTracker = appSingletons.getTracker();
        mBlockScreenType = BLOCK_SCREEN_TYPE_NORMAL;
        mBlockScreenView = (BlockScreenView) findViewById(R.id.block_screen);
        if (!mCanModifyParentalControls) {
            mBlockScreenView.setImage(R.drawable.ic_message_lock_no_permission);
            mBlockScreenView.setScaleType(ImageView.ScaleType.CENTER);
        } else {
            mBlockScreenView.setImage(R.drawable.ic_message_lock);
        }
        mBlockScreenView.setShrunkenImage(R.drawable.ic_message_lock_preview);
        mBlockScreenView.addFadeOutAnimationListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                adjustBlockScreenSpacingAndText();
            }
        });

        mHideScreenView = (BlockScreenView) findViewById(R.id.hide_screen);
        mHideScreenView.setImageVisibility(false);
        mBufferingSpinnerView = findViewById(R.id.buffering_spinner);
        mHideScreenImageColorFilter = getResources().getColor(
                R.color.tvview_block_image_color_filter, null);
        mBlockScreenForTuneView = findViewById(R.id.block_screen_for_tune);
        mDimScreenView = findViewById(R.id.dim);
        mDimScreenView.animate().setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (mActionAfterFade != null) {
                    mActionAfterFade.run();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                if (mActionAfterFade != null) {
                    mActionAfterFade.run();
                }
            }
        });
    }

    public void initialize(AppLayerTvView tvView, TuningBlockView tuningBlockView,
            ProgramDataManager programDataManager, TvInputManagerHelper tvInputManagerHelper) {
        mTvView = tvView;
        mTuningBlockView = tuningBlockView;
        mProgramDataManager = programDataManager;
        mInputManagerHelper = tvInputManagerHelper;
        mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
        mParentalControlSettings = tvInputManagerHelper.getParentalControlSettings();
        if (mInputSessionManager != null) {
            mTvViewSession = mInputSessionManager.createTvViewSession(tvView, this, mCallback);
        } else {
            mTvView.setCallback(mCallback);
        }
        copyLayoutParamsToTvView();
    }

    public void start() {
        mStarted = true;
    }

    /**
     * Warms up the input to reduce the start time.
     */
    public void warmUpInput(String inputId, Uri channelUri) {
        if (!mStarted && inputId != null && channelUri != null) {
            if (mTvViewSession != null) {
                mTvViewSession.tune(inputId, channelUri);
            } else {
                mTvView.tune(inputId, channelUri);
            }
            hideScreenByVideoAvailability(inputId, TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
        }
    }

    public void stop() {
        if (!mStarted) {
            return;
        }
        mStarted = false;
        if (mCurrentChannel != null) {
            long duration = mChannelViewTimer.reset();
            mTracker.sendChannelViewStop(mCurrentChannel, duration);
            if (mWatchedHistoryManager != null && !mCurrentChannel.isPassthrough()) {
                mWatchedHistoryManager.logChannelViewStop(mCurrentChannel,
                        System.currentTimeMillis(), duration);
            }
        }
        reset();
    }

    /**
     * Releases the resources.
     */
    public void release() {
        if (mInputSessionManager != null) {
            mInputSessionManager.releaseTvViewSession(mTvViewSession);
            mTvViewSession = null;
        }
    }

    /**
     * Reset TV view.
     */
    public void reset() {
        resetInternal();
        hideScreenByVideoAvailability(null, VIDEO_UNAVAILABLE_REASON_NOT_TUNED);
    }

    /**
     * Reset TV view to acquire the recording session.
     */
    public void resetByRecording() {
        resetInternal();
    }

    private void resetInternal() {
        if (mTvViewSession != null) {
            mTvViewSession.reset();
        } else {
            mTvView.reset();
        }
        mCurrentChannel = null;
        mInputInfo = null;
        mCanReceiveInputEvent = false;
        mOnTuneListener = null;
        setTimeShiftAvailable(false);
    }

    public void setMain() {
        mTvView.setMain();
    }

    public void setWatchedHistoryManager(WatchedHistoryManager watchedHistoryManager) {
        mWatchedHistoryManager = watchedHistoryManager;
    }

    /**
     * Sets if the TunableTvView is under shrunken.
     */
    public void setIsUnderShrunken(boolean isUnderShrunken) {
        mIsUnderShrunken = isUnderShrunken;
    }

    public boolean isPlaying() {
        return mStarted;
    }

    /**
     * Called when parental control is changed.
     */
    public void onParentalControlChanged(boolean enabled) {
        mParentControlEnabled = enabled;
        if (!mParentControlEnabled) {
            mBlockScreenForTuneView.setVisibility(View.GONE);
        }
    }

    /**
     * Tunes to a channel with the {@code channelId}.
     *
     * @param params extra data to send it to TIS and store the data in TIMS.
     * @return false, if the TV input is not a proper state to tune to a channel. For example,
     *         if the state is disconnected or channelId doesn't exist, it returns false.
     */
    public boolean tuneTo(Channel channel, Bundle params, OnTuneListener listener) {
        Debug.getTimer(Debug.TAG_START_UP_TIMER).log("TunableTvView.tuneTo");
        if (!mStarted) {
            throw new IllegalStateException("TvView isn't started");
        }
        if (DEBUG) Log.d(TAG, "tuneTo " + channel);
        TvInputInfo inputInfo = mInputManagerHelper.getTvInputInfo(channel.getInputId());
        if (inputInfo == null) {
            return false;
        }
        if (mCurrentChannel != null) {
            long duration = mChannelViewTimer.reset();
            mTracker.sendChannelViewStop(mCurrentChannel, duration);
            if (mWatchedHistoryManager != null && !mCurrentChannel.isPassthrough()) {
                mWatchedHistoryManager.logChannelViewStop(mCurrentChannel,
                        System.currentTimeMillis(), duration);
            }
        }
        mOnTuneListener = listener;
        mCurrentChannel = channel;
        boolean tunedByRecommendation = params != null
                && params.getString(NotificationService.TUNE_PARAMS_RECOMMENDATION_TYPE) != null;
        boolean needSurfaceSizeUpdate = false;
        if (!inputInfo.equals(mInputInfo)) {
            mInputInfo = inputInfo;
            mCanReceiveInputEvent = getContext().getPackageManager().checkPermission(
                    PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getServiceInfo().packageName)
                            == PackageManager.PERMISSION_GRANTED;
            if (DEBUG) {
                Log.d(TAG, "Input \'" + mInputInfo.getId() + "\' can receive input event: "
                        + mCanReceiveInputEvent);
            }
            needSurfaceSizeUpdate = true;
        }
        mTracker.sendChannelViewStart(mCurrentChannel, tunedByRecommendation);
        mChannelViewTimer.start();
        mVideoWidth = 0;
        mVideoHeight = 0;
        mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
        mVideoFrameRate = 0f;
        mVideoDisplayAspectRatio = 0f;
        mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
        mHasClosedCaption = false;
        mBlockedContentRating = null;
        mTimeShiftCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
        // To reduce the IPCs, unregister the callback here and register it when necessary.
        mTvView.setTimeShiftPositionCallback(null);
        setTimeShiftAvailable(false);
        if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
            // When the input is changed, TvView recreates its SurfaceView internally.
            // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
            getSurfaceView().getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
        }
        hideScreenByVideoAvailability(mInputInfo.getId(),
                TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
        updateBlockScreenUI(false);
        if (mTvViewSession != null) {
            mTvViewSession.tune(channel, params, listener);
        } else {
            mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params);
        }
        if (channel.isPassthrough()) {
            mBlockScreenForTuneView.setVisibility(View.GONE);
        } else if (mParentControlEnabled) {
            mBlockScreenForTuneView.setVisibility(View.VISIBLE);
        }
        if (mOnTuneListener != null) {
            mOnTuneListener.onStreamInfoChanged(this);
        }
        return true;
    }

    @Override
    public Channel getCurrentChannel() {
        return mCurrentChannel;
    }

    /**
     * Sets the current channel. Call this method only when setting the current channel without
     * actually tuning to it.
     *
     * @param currentChannel The new current channel to set to.
     */
    public void setCurrentChannel(Channel currentChannel) {
        mCurrentChannel = currentChannel;
    }

    public void setStreamVolume(float volume) {
        if (!mStarted) {
            throw new IllegalStateException("TvView isn't started");
        }
        if (DEBUG) Log.d(TAG, "setStreamVolume " + volume);
        mVolume = volume;
        if (!mIsMuted) {
            mTvView.setStreamVolume(volume);
        }
    }

    /**
     * Sets fixed size for the internal {@link android.view.Surface} of
     * {@link android.media.tv.TvView}. If either {@code width} or {@code height} is non positive,
     * the {@link android.view.Surface}'s size will be matched to the layout.
     *
     * Note: Once {@link android.view.SurfaceHolder#setFixedSize} is called,
     * {@link android.view.SurfaceView} and its underlying window can be misaligned, when the size
     * of {@link android.view.SurfaceView} is changed without changing either left position or top
     * position. For detail, please refer the codes of android.view.SurfaceView.updateWindow().
     */
    public void setFixedSurfaceSize(int width, int height) {
        mFixedSurfaceWidth = width;
        mFixedSurfaceHeight = height;
        if (mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
            // When the input is changed, TvView recreates its SurfaceView internally.
            // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
            SurfaceView surfaceView = (SurfaceView) mTvView.getChildAt(0);
            surfaceView.getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
        } else {
            SurfaceView surfaceView = (SurfaceView) mTvView.getChildAt(0);
            surfaceView.getHolder().setSizeFromLayout();
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        return mCanReceiveInputEvent && mTvView.dispatchKeyEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return mCanReceiveInputEvent && mTvView.dispatchTouchEvent(event);
    }

    @Override
    public boolean dispatchTrackballEvent(MotionEvent event) {
        return mCanReceiveInputEvent && mTvView.dispatchTrackballEvent(event);
    }

    @Override
    public boolean dispatchGenericMotionEvent(MotionEvent event) {
        return mCanReceiveInputEvent && mTvView.dispatchGenericMotionEvent(event);
    }

    public interface OnTuneListener {
        void onTuneFailed(Channel channel);
        void onUnexpectedStop(Channel channel);
        void onStreamInfoChanged(StreamInfo info);
        void onChannelRetuned(Uri channel);
        void onContentBlocked();
        void onContentAllowed();
    }

    public void unblockContent(TvContentRating rating) {
        mTvView.unblockContent(rating);
    }

    @Override
    public int getVideoWidth() {
        return mVideoWidth;
    }

    @Override
    public int getVideoHeight() {
        return mVideoHeight;
    }

    @Override
    public int getVideoDefinitionLevel() {
        return mVideoFormat;
    }

    @Override
    public float getVideoFrameRate() {
        return mVideoFrameRate;
    }

    /**
     * Returns displayed aspect ratio (video width / video height * pixel ratio).
     */
    @Override
    public float getVideoDisplayAspectRatio() {
        return mVideoDisplayAspectRatio;
    }

    @Override
    public int getAudioChannelCount() {
        return mAudioChannelCount;
    }

    @Override
    public boolean hasClosedCaption() {
        return mHasClosedCaption;
    }

    @Override
    public boolean isVideoAvailable() {
        return mVideoAvailable;
    }

    @Override
    public boolean isVideoOrAudioAvailable() {
        return mVideoAvailable || mAudioAvailable;
    }

    @Override
    public int getVideoUnavailableReason() {
        return mVideoUnavailableReason;
    }

    /**
     * Returns the {@link android.view.SurfaceView} of the {@link android.media.tv.TvView}.
     */
    private SurfaceView getSurfaceView() {
        return (SurfaceView) mTvView.getChildAt(0);
    }

    public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) {
        mTvView.setOnUnhandledInputEventListener(listener);
    }

    public void setClosedCaptionEnabled(boolean enabled) {
        mTvView.setCaptionEnabled(enabled);
    }

    public List<TvTrackInfo> getTracks(int type) {
        return mTvView.getTracks(type);
    }

    public String getSelectedTrack(int type) {
        return mTvView.getSelectedTrack(type);
    }

    public void selectTrack(int type, String trackId) {
        mTvView.selectTrack(type, trackId);
    }

    /**
     * Returns if the screen is blocked by {@link #blockOrUnblockScreen(boolean)}.
     */
    public boolean isScreenBlocked() {
        return mScreenBlocked;
    }

    public void setOnScreenBlockedListener(OnScreenBlockingChangedListener listener) {
        mOnScreenBlockedListener = listener;
    }

    /**
     * Returns currently blocked content rating. {@code null} if it's not blocked.
     */
    @Override
    public TvContentRating getBlockedContentRating() {
        return mBlockedContentRating;
    }

    /**
     * Blocks/unblocks current TV screen and mutes.
     * There would be black screen with lock icon in order to show that
     * screen block is intended and not an error.
     * TODO: Accept parameter to show lock icon or not.
     *
     * @param blockOrUnblock {@code true} to block the screen, or {@code false} to unblock.
     */
    public void blockOrUnblockScreen(boolean blockOrUnblock) {
        mScreenBlocked = blockOrUnblock;
        checkBlockScreenAndMuteNeeded();
        if (mOnScreenBlockedListener != null) {
            mOnScreenBlockedListener.onScreenBlockingChanged(blockOrUnblock);
        }
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        super.setLayoutParams(params);
        if (mTvView != null) {
            copyLayoutParamsToTvView();
        }
    }

    private void copyLayoutParamsToTvView() {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        FrameLayout.LayoutParams tvViewLp = (FrameLayout.LayoutParams) mTvView.getLayoutParams();
        if (tvViewLp.bottomMargin != lp.bottomMargin
                || tvViewLp.topMargin != lp.topMargin
                || tvViewLp.leftMargin != lp.leftMargin
                || tvViewLp.rightMargin != lp.rightMargin
                || tvViewLp.gravity != lp.gravity
                || tvViewLp.height != lp.height
                || tvViewLp.width != lp.width) {
            tvViewLp.leftMargin = lp.leftMargin;
            tvViewLp.topMargin = lp.topMargin;
            tvViewLp.bottomMargin = lp.bottomMargin;
            tvViewLp.rightMargin = lp.rightMargin;
            tvViewLp.gravity = lp.gravity;
            tvViewLp.height = lp.height;
            tvViewLp.width = lp.width;
            mTvView.setLayoutParams(tvViewLp);
        }
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (mTvView != null) {
            mTvView.setVisibility(visibility);
        }
    }

    /**
     * Set the type of block screen. If {@code type} is set to {@code BLOCK_SCREEN_TYPE_NO_UI}, the
     * block screen will not show any description such as a lock icon and a text for the blocked
     * reason, if {@code type} is set to {@code BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW}, the block screen
     * will show the description for shrunken tv view (Small icon and short text), and if
     * {@code type} is set to {@code BLOCK_SCREEN_TYPE_NORMAL}, the block screen will show the
     * description for normal tv view (Big icon and long text).
     *
     * @param type The type of block screen to set.
     */
    public void setBlockScreenType(@BlockScreenType int type) {
        // TODO: need to support the transition from NORMAL to SHRUNKEN and vice verse.
        if (mBlockScreenType != type) {
            mBlockScreenType = type;
            updateBlockScreenUI(true);
        }
    }

    private void updateBlockScreenUI(boolean animation) {
        mBlockScreenView.endAnimations();

        if (!mScreenBlocked && mBlockedContentRating == null) {
            mBlockScreenView.setVisibility(GONE);
            return;
        }

        mBlockScreenView.setVisibility(VISIBLE);
        if (!animation || mBlockScreenType != TunableTvView.BLOCK_SCREEN_TYPE_NO_UI) {
            adjustBlockScreenSpacingAndText();
        }
        mBlockScreenView.onBlockStatusChanged(mBlockScreenType, animation);
    }

    private void adjustBlockScreenSpacingAndText() {
        // TODO: need to add animation for padding change when the block screen type is changed
        // NORMAL to SHRUNKEN and vice verse.
        mBlockScreenView.setSpacing(mBlockScreenType);
        String text = getBlockScreenText();
        if (text != null) {
            mBlockScreenView.setText(text);
        }
    }

    /**
     * Returns the block screen text corresponding to the current status.
     * Note that returning {@code null} value means that the current text should not be changed.
     */
    private String getBlockScreenText() {
        if (mScreenBlocked) {
            switch (mBlockScreenType) {
                case BLOCK_SCREEN_TYPE_NO_UI:
                case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
                    return "";
                case BLOCK_SCREEN_TYPE_NORMAL:
                    if (mCanModifyParentalControls) {
                        return getResources().getString(R.string.tvview_channel_locked);
                    } else {
                        return getResources().getString(
                                R.string.tvview_channel_locked_no_permission);
                    }
            }
        } else if (mBlockedContentRating != null) {
            String name = mContentRatingsManager.getDisplayNameForRating(mBlockedContentRating);
            switch (mBlockScreenType) {
                case BLOCK_SCREEN_TYPE_NO_UI:
                    return "";
                case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
                    if (TextUtils.isEmpty(name)) {
                        return getResources().getString(R.string.shrunken_tvview_content_locked);
                    } else {
                        return getContext().getString(
                                R.string.shrunken_tvview_content_locked_format, name);
                    }
                case BLOCK_SCREEN_TYPE_NORMAL:
                    if (TextUtils.isEmpty(name)) {
                        if (mCanModifyParentalControls) {
                            return getResources().getString(R.string.tvview_content_locked);
                        } else {
                            return getResources().getString(
                                    R.string.tvview_content_locked_no_permission);
                        }
                    } else {
                        if (mCanModifyParentalControls) {
                            return getContext().getString(
                                    R.string.tvview_content_locked_format, name);
                        } else {
                            return getContext().getString(
                                    R.string.tvview_content_locked_format_no_permission, name);
                        }
                    }
            }
        }
        return null;
    }

    private void checkBlockScreenAndMuteNeeded() {
        updateBlockScreenUI(false);
        updateMuteStatus();
    }

    @UiThread
    private void hideScreenByVideoAvailability(String inputId, int reason) {
        mVideoAvailable = false;
        mAudioAvailable = false;
        mVideoUnavailableReason = reason;
        if (mInternetCheckTask != null) {
            mInternetCheckTask.cancel(true);
            mInternetCheckTask = null;
        }
        if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
            // Tuning block view will apply animation when unhide screen, so let's end the
            // animation if it is running.
            mTuningBlockView.endFadeOutAnimator();
        }
        switch (reason) {
            case TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY:
                mHideScreenView.setVisibility(VISIBLE);
                mHideScreenView.setImageVisibility(false);
                mHideScreenView.setText(R.string.tvview_msg_audio_only);
                mTuningBlockView.setVisibility(GONE);
                mBufferingSpinnerView.setVisibility(GONE);
                mAudioAvailable = true;
                break;
            case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
                mBufferingSpinnerView.setVisibility(VISIBLE);
                break;
            case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
                mHideScreenView.setVisibility(VISIBLE);
                mHideScreenView.setText(R.string.tvview_msg_weak_signal);
                mTuningBlockView.setVisibility(GONE);
                mBufferingSpinnerView.setVisibility(GONE);
                break;
            case TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING:
                mBufferingSpinnerView.setVisibility(VISIBLE);
                if (shouldShowImageForTuning()) {
                    mHideScreenView.setVisibility(GONE);
                    mTuningBlockView.setVisibility(VISIBLE);
                    mTuningBlockView.setImageVisibility(false);
                    showImageForTuning();
                } else {
                    mHideScreenView.setVisibility(VISIBLE);
                    mHideScreenView.setImageVisibility(false);
                    mHideScreenView.setText(null);
                    mTuningBlockView.setVisibility(GONE);
                }
                break;
            case VIDEO_UNAVAILABLE_REASON_NOT_TUNED:
                mHideScreenView.setVisibility(VISIBLE);
                mHideScreenView.setImageVisibility(false);
                mHideScreenView.setText(null);
                mTuningBlockView.setVisibility(GONE);
                mBufferingSpinnerView.setVisibility(GONE);
                break;
            case VIDEO_UNAVAILABLE_REASON_NO_RESOURCE:
                mHideScreenView.setVisibility(VISIBLE);
                mHideScreenView.setImageVisibility(false);
                mHideScreenView.setText(getTuneConflictMessage(inputId));
                mTuningBlockView.setVisibility(GONE);
                mBufferingSpinnerView.setVisibility(GONE);
                break;
            case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
            default:
                mHideScreenView.setVisibility(VISIBLE);
                mHideScreenView.setImageVisibility(false);
                mHideScreenView.setText(null);
                mTuningBlockView.setVisibility(GONE);
                mBufferingSpinnerView.setVisibility(GONE);
                if (mCurrentChannel != null && !mCurrentChannel.isPhysicalTunerChannel()) {
                    mInternetCheckTask = new InternetCheckTask();
                    mInternetCheckTask.execute();
                }
                break;
        }
        updateMuteStatus();
    }

    private boolean shouldShowImageForTuning() {
        if (getWidth() == 0 || getWidth() == 0 || mCurrentChannel == null || !isBundledInput()
                || mIsUnderShrunken || (mParentControlEnabled && (mCurrentChannel.isLocked()))) {
            return false;
        }
        Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
        if (currentProgram == null) {
            return false;
        }
        TvContentRating rating =
                mParentalControlSettings.getBlockedRating(currentProgram.getContentRatings());
        return !(mParentControlEnabled && rating != null);
    }

    private void showImageForTuning() {
        mTuningBlockView.setImage(null);
        if (mCurrentChannel == null) {
            return;
        }
        Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
        if (currentProgram != null) {
            currentProgram.loadPosterArt(getContext(), getWidth(), getHeight(),
                    createProgramPosterArtCallback(mTuningBlockView, mCurrentChannel.getId()));
        }
    }

    private String getTuneConflictMessage(String inputId) {
        if (inputId != null) {
            TvInputInfo input = mInputManager.getTvInputInfo(inputId);
            Long timeMs = mInputSessionManager.getEarliestRecordingSessionEndTimeMs(inputId);
            if (timeMs != null) {
                return getResources().getQuantityString(R.plurals.tvview_msg_input_no_resource,
                        input.getTunerCount(),
                        DateUtils.formatDateTime(getContext(), timeMs, DateUtils.FORMAT_SHOW_TIME));
            }
        }
        return null;
    }

    private void unhideScreenByVideoAvailability() {
        mVideoAvailable = true;
        mAudioAvailable = true;
        mTuningBlockView.hideWithAnimationIfNeeded();
        mHideScreenView.setVisibility(GONE);
        mBufferingSpinnerView.setVisibility(GONE);
        updateMuteStatus();
    }

    private void updateMuteStatus() {
        // Workaround: TunerTvInputService uses AC3 pass-through implementation, which disables
        // audio tracks to enforce the mute request. We don't want to send mute request if we are
        // not going to block the screen to prevent the video jankiness resulted by disabling audio
        // track before the playback is started. In other way, we should send unmute request before
        // the playback is started, because TunerTvInput will remember the muted state and mute
        // itself right way when the playback is going to be started, which results the initial
        // jankiness, too.
        boolean isBundledInput = isBundledInput();
        if ((isBundledInput || mAudioAvailable) && !mScreenBlocked
                && mBlockedContentRating == null) {
            if (mIsMuted) {
                mIsMuted = false;
                mTvView.setStreamVolume(mVolume);
            }
        } else {
            if (!mIsMuted) {
                if ((mInputInfo == null || isBundledInput)
                        && !mScreenBlocked && mBlockedContentRating == null) {
                    return;
                }
                mIsMuted = true;
                mTvView.setStreamVolume(0);
            }
        }
    }

    private boolean isBundledInput() {
        return mInputInfo != null && mInputInfo.getType() == TvInputInfo.TYPE_TUNER
                && Utils.isBundledInput(mInputInfo.getId());
    }

    /** Returns true if this view is faded out. */
    public boolean isFadedOut() {
        return mFadeState == FADED_OUT;
    }

    /** Fade out this TunableTvView. Fade out by increasing the dimming. */
    public void fadeOut(int durationMillis, TimeInterpolator interpolator,
            final Runnable actionAfterFade) {
        mDimScreenView.setAlpha(0f);
        mDimScreenView.setVisibility(View.VISIBLE);
        mDimScreenView.animate()
                .alpha(1f)
                .setDuration(durationMillis)
                .setInterpolator(interpolator)
                .withStartAction(new Runnable() {
                    @Override
                    public void run() {
                        mFadeState = FADING_OUT;
                        mActionAfterFade = actionAfterFade;
                    }
                })
                .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        mFadeState = FADED_OUT;
                    }
                });
    }

    /** Fade in this TunableTvView. Fade in by decreasing the dimming. */
    public void fadeIn(int durationMillis, TimeInterpolator interpolator,
            final Runnable actionAfterFade) {
        mDimScreenView.setAlpha(1f);
        mDimScreenView.setVisibility(View.VISIBLE);
        mDimScreenView.animate()
                .alpha(0f)
                .setDuration(durationMillis)
                .setInterpolator(interpolator)
                .withStartAction(new Runnable() {
                    @Override
                    public void run() {
                        mFadeState = FADING_IN;
                        mActionAfterFade = actionAfterFade;
                    }
                })
                .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        mFadeState = FADED_IN;
                        mDimScreenView.setVisibility(View.GONE);
                    }
                });
    }

    /** Remove the fade effect. */
    public void removeFadeEffect() {
        mDimScreenView.animate().cancel();
        mDimScreenView.setVisibility(View.GONE);
        mFadeState = FADED_IN;
    }

    /**
     * Sets the TimeShiftListener
     *
     * @param listener The instance of {@link TimeShiftListener}.
     */
    public void setTimeShiftListener(TimeShiftListener listener) {
        mTimeShiftListener = listener;
    }

    private void setTimeShiftAvailable(boolean isTimeShiftAvailable) {
        if (mTimeShiftAvailable == isTimeShiftAvailable) {
            return;
        }
        mTimeShiftAvailable = isTimeShiftAvailable;
        if (isTimeShiftAvailable) {
            mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
                @Override
                public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
                    if (mTimeShiftListener != null && mCurrentChannel != null
                            && mCurrentChannel.getInputId().equals(inputId)) {
                        mTimeShiftListener.onRecordStartTimeChanged(timeMs);
                    }
                }

                @Override
                public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
                    mTimeShiftCurrentPositionMs = timeMs;
                }
            });
        } else {
            mTvView.setTimeShiftPositionCallback(null);
        }
        if (mTimeShiftListener != null) {
            mTimeShiftListener.onAvailabilityChanged();
        }
    }

    /**
     * Returns if the time shift is available for the current channel.
     */
    public boolean isTimeShiftAvailable() {
        return mTimeShiftAvailable;
    }

    /**
     * Plays the media, if the current input supports time-shifting.
     */
    public void timeshiftPlay() {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        }
        if (mTimeShiftState == TIME_SHIFT_STATE_PLAY) {
            return;
        }
        mTvView.timeShiftResume();
    }

    /**
     * Pauses the media, if the current input supports time-shifting.
     */
    public void timeshiftPause() {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        }
        if (mTimeShiftState == TIME_SHIFT_STATE_PAUSE) {
            return;
        }
        mTvView.timeShiftPause();
    }

    /**
     * Rewinds the media with the given speed, if the current input supports time-shifting.
     *
     * @param speed The speed to rewind the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
     */
    public void timeshiftRewind(int speed) {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        } else {
            if (speed <= 0) {
                throw new IllegalArgumentException("The speed should be a positive integer.");
            }
            mTimeShiftState = TIME_SHIFT_STATE_REWIND;
            PlaybackParams params = new PlaybackParams();
            params.setSpeed(speed * -1);
            mTvView.timeShiftSetPlaybackParams(params);
        }
    }

    /**
     * Fast-forwards the media with the given speed, if the current input supports time-shifting.
     *
     * @param speed The speed to forward the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
     */
    public void timeshiftFastForward(int speed) {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        } else {
            if (speed <= 0) {
                throw new IllegalArgumentException("The speed should be a positive integer.");
            }
            mTimeShiftState = TIME_SHIFT_STATE_FAST_FORWARD;
            PlaybackParams params = new PlaybackParams();
            params.setSpeed(speed);
            mTvView.timeShiftSetPlaybackParams(params);
        }
    }

    /**
     * Seek to the given time position.
     *
     * @param timeMs The time in milliseconds to seek to.
     */
    public void timeshiftSeekTo(long timeMs) {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        }
        mTvView.timeShiftSeekTo(timeMs);
    }

    /**
     * Returns the current playback position in milliseconds.
     */
    public long timeshiftGetCurrentPositionMs() {
        if (!isTimeShiftAvailable()) {
            throw new IllegalStateException("Time-shift is not supported for the current channel");
        }
        if (DEBUG) {
            Log.d(TAG, "timeshiftGetCurrentPositionMs: current position ="
                    + Utils.toTimeString(mTimeShiftCurrentPositionMs));
        }
        return mTimeShiftCurrentPositionMs;
    }

    private ImageLoader.ImageLoaderCallback<TuningBlockView> createProgramPosterArtCallback(
            TuningBlockView view, final long channelId) {
        return new ImageLoader.ImageLoaderCallback<TuningBlockView>(view) {
            @Override
            public void onBitmapLoaded(TuningBlockView view, @Nullable Bitmap posterArt) {
                if (posterArt == null || getCurrentChannel() == null
                        || channelId != getCurrentChannel().getId()
                        || !shouldShowImageForTuning()) {
                    return;
                }
                Drawable drawablePosterArt = new BitmapDrawable(view.getResources(), posterArt);
                drawablePosterArt.mutate().setColorFilter(
                        mHideScreenImageColorFilter, PorterDuff.Mode.SRC_OVER);
                view.setImage(drawablePosterArt);
                view.setImageVisibility(true);
            }
        };
    }

    /**
     * Used to receive the time-shift events.
     */
    public static abstract class TimeShiftListener {
        /**
         * Called when the availability of the time-shift for the current channel has been changed.
         * It should be guaranteed that this is called only when the availability is really changed.
         */
        public abstract void onAvailabilityChanged();

        /**
         * Called when the record start time has been changed.
         * This is not called when the recorded programs is played.
         */
        public abstract void onRecordStartTimeChanged(long recordStartTimeMs);
    }

    /**
     * A listener which receives the notification when the screen is blocked/unblocked.
     */
    public static abstract class OnScreenBlockingChangedListener {
        /**
         * Called when the screen is blocked/unblocked.
         */
        public abstract void onScreenBlockingChanged(boolean blocked);
    }

    private class InternetCheckTask extends AsyncTask<Void, Void, Boolean> {
        @Override
        protected Boolean doInBackground(Void... params) {
            return NetworkUtils.isNetworkAvailable(mConnectivityManager);
        }

        @Override
        protected void onPostExecute(Boolean networkAvailable) {
            mInternetCheckTask = null;
            if (!mVideoAvailable && !networkAvailable && isAttachedToWindow()
                    && mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) {
                mHideScreenView.setImageVisibility(true);
                mHideScreenView.setImage(R.drawable.ic_sad_cloud);
                mHideScreenView.setText(R.string.tvview_msg_no_internet_connection);
            }
        }
    }
}
