/*
 * 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.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
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.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
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.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.compat.TvInputConstantCompat;
import com.android.tv.common.compat.TvViewCompat.TvInputCallbackCompat;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
import com.android.tv.common.util.DurationTimer;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
import com.android.tv.data.api.Program;
import com.android.tv.features.TvFeatures;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.ui.api.TunableTvViewPlayingApi;
import com.android.tv.util.NetworkUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;

import com.android.tv.common.flags.LegacyFlags;

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

/** Includes the real {@link AppLayerTvView} handling tuning, block and other display events. */
public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvViewPlayingApi {
    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;
    public static final int VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED = -3;
    public static final int VIDEO_UNAVAILABLE_REASON_NONE = -100;
    private final AccessibilityManager mAccessibilityManager;

    @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 =
            CommonConstants.BASE_PACKAGE + ".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;
    @Nullable private Channel mCurrentChannel;
    private TvInputManagerHelper mInputManagerHelper;
    private ContentRatingsManager mContentRatingsManager;
    private ParentalControlSettings mParentalControlSettings;
    private ProgramDataManager mProgramDataManager;
    @Nullable private WatchedHistoryManager mWatchedHistoryManager;
    private boolean mStarted;
    private String mTagetInputId;
    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 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 to hide the real TV view underlying. It may be used to enforce parental
    // control, or hide screen when there's no video available and show appropriate information.
    private final BlockScreenView mBlockScreenView;
    private final int mTuningImageColorFilter;

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

    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 int mChannelSignalStrength;

    private final TvInputCallbackCompat mCallback =
            new TvInputCallbackCompat() {
                @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, true);
                    }
                }

                @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 = (float) mVideoWidth
                                                    / mVideoHeight;
                                            mVideoDisplayAspectRatio *= videoPixelAspectRatio > 0 ?
                                                    videoPixelAspectRatio : 1;
                                        }
                                    } else if (type == TvTrackInfo.TYPE_AUDIO) {
                                        mAudioChannelCount = track.getAudioChannelCount();
                                    }
                                    trackFound = true;
                                    break;
                                }
                            }
                        }
                        if (!trackFound) {
                            Log.w(TAG, "Invalid track ID: " + trackId);
                        }
                    }
                    if (mOnTuneListener != null) {
                        // should not change audio track automatically when an audio track or a
                        // subtitle track is selected
                        mOnTuneListener.onStreamInfoChanged(
                                TunableTvView.this, type == TvTrackInfo.TYPE_VIDEO);
                    }
                }

                @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 TV app ends,"
                                            + " TunableTvView.onVideoAvailable resets timer");
                    Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
                    Debug.removeTimer(Debug.TAG_START_UP_TIMER);
                    mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NONE;
                    updateBlockScreenAndMuting();
                    if (mOnTuneListener != null) {
                        mOnTuneListener.onStreamInfoChanged(TunableTvView.this, true);
                    }
                }

                @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 + ")");
                    }
                    mVideoUnavailableReason = reason;
                    if (closePipIfNeeded()) {
                        return;
                    }
                    updateBlockScreenAndMuting();
                    if (mOnTuneListener != null) {
                        mOnTuneListener.onStreamInfoChanged(TunableTvView.this, true);
                    }
                    switch (reason) {
                        case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
                        case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
                        case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
                        case CommonConstants.VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED:
                            mTracker.sendChannelVideoUnavailable(mCurrentChannel, reason);
                            break;
                        default:
                            // do nothing
                    }
                }

                @Override
                public void onContentAllowed(String inputId) {
                    mBlockedContentRating = null;
                    updateBlockScreenAndMuting();
                    if (mOnTuneListener != null) {
                        mOnTuneListener.onContentAllowed();
                    }
                }

                @Override
                public void onContentBlocked(String inputId, TvContentRating rating) {
                    if (rating != null && rating.equals(mBlockedContentRating)) {
                        return;
                    }
                    mBlockedContentRating = rating;
                    if (closePipIfNeeded()) {
                        return;
                    }
                    updateBlockScreenAndMuting();
                    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);
                }

                @Override
                public void onSignalStrength(String inputId, int value) {
                    mChannelSignalStrength = value;
                    if (mOnTuneListener != null) {
                        mOnTuneListener.onChannelSignalStrength();
                    }
                }
            };

    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);

        TvSingletons tvSingletons = TvSingletons.getSingletons(context);
        if (CommonFeatures.DVR.isEnabled(context)) {
            mInputSessionManager = tvSingletons.getInputSessionManager();
        } else {
            mInputSessionManager = null;
        }
        mInputManager = tvSingletons.getTvInputManagerHelper();
        mConnectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mCanModifyParentalControls = PermissionUtils.hasModifyParentalControls(context);
        mTracker = tvSingletons.getTracker();
        mBlockScreenType = BLOCK_SCREEN_TYPE_NORMAL;
        mBlockScreenView = (BlockScreenView) findViewById(R.id.block_screen);
        mBlockScreenView.addInfoFadeInAnimationListener(
                new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        adjustBlockScreenSpacingAndText();
                    }
                });

        mBufferingSpinnerView = findViewById(R.id.buffering_spinner);
        mTuningImageColorFilter =
                getResources().getColor(R.color.tvview_block_image_color_filter, null);
        mDimScreenView = findViewById(R.id.dim_screen);
        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();
                                }
                            }
                        });
        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
    }

    public void initialize(
            ProgramDataManager programDataManager,
            TvInputManagerHelper tvInputManagerHelper,
            LegacyFlags mLegacyFlags) {
        mTvView = findViewById(R.id.tv_view);
        mTvView.setUseSecureSurface(!BuildConfig.ENG && !mLegacyFlags.enableDeveloperFeatures());

        mProgramDataManager = programDataManager;
        mInputManagerHelper = tvInputManagerHelper;
        mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
        mParentalControlSettings = tvInputManagerHelper.getParentalControlSettings();
        if (mInputSessionManager != null) {
            mTvViewSession = mInputSessionManager.createTvViewSession(mTvView, this, mCallback);
        } else {
            mTvView.setCallback(mCallback);
        }
    }

    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);
            }
            mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
            updateBlockScreenAndMuting();
        }
    }

    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;
        }
    }

    /** Resets TV view. */
    public void reset() {
        resetInternal();
        mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NOT_TUNED;
        updateBlockScreenAndMuting();
    }

    /** Resets 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() {
        if (PermissionUtils.hasChangeHdmiCecActiveSource(getContext())) {
            mTvView.setMain();
        }
    }

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

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

    public int getChannelSignalStrength() {
        return mChannelSignalStrength;
    }

    public void resetChannelSignalStrength() {
        mChannelSignalStrength = TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED;
    }

    @Override
    public boolean isPlaying() {
        return mStarted;
    }

    /** Called when parental control is changed. */
    public void onParentalControlChanged(boolean enabled) {
        mParentControlEnabled = enabled;
        if (!enabled) {
            // Unblock screen immediately if parental control is turned off
            updateBlockScreenAndMuting();
        }
    }

    /**
     * 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)) {
            mTagetInputId = inputInfo.getId();
            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);
        mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
        if (mTvViewSession != null) {
            mTvViewSession.tune(channel, params, listener);
        } else {
            mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params);
        }
        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.
            SurfaceView surfaceView = getSurfaceView();
            if (surfaceView != null) {
                surfaceView.getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
            } else {
                Log.w(TAG, "Failed to set fixed size for surface view: Null surface view");
            }
        }
        updateBlockScreenAndMuting();
        if (mOnTuneListener != null) {
            mOnTuneListener.onStreamInfoChanged(this, true);
        }
        return true;
    }

    @Override
    @Nullable
    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;
    }

    @Override
    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.
     *
     * <p>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, boolean allowAutoSelectionOfTrack);

        void onChannelRetuned(Uri channel);

        void onContentBlocked();

        void onContentAllowed();

        void onChannelSignalStrength();
    }

    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 mVideoUnavailableReason == VIDEO_UNAVAILABLE_REASON_NONE;
    }

    @Override
    public boolean isVideoOrAudioAvailable() {
        return mVideoUnavailableReason == VIDEO_UNAVAILABLE_REASON_NONE
                || mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY;
    }

    @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);
    }

    @VisibleForTesting
    public void setOnTuneListener(OnTuneListener listener) {
        mOnTuneListener = listener;
    }

    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);
    }

    /**
     * Gets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying {@link TvView},
     * which is the actual view to play live TV videos.
     */
    public MarginLayoutParams getTvViewLayoutParams() {
        return (MarginLayoutParams) mTvView.getLayoutParams();
    }

    /**
     * Sets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying {@link TvView},
     * which is the actual view to play live TV videos.
     */
    public void setTvViewLayoutParams(MarginLayoutParams layoutParams) {
        mTvView.setLayoutParams(layoutParams);
    }

    /**
     * Gets the underlying {@link AppLayerTvView}, which is the actual view to play live TV videos.
     */
    public TvView getTvView() {
        return mTvView;
    }

    /**
     * Returns if the screen is blocked, either by {@link #blockOrUnblockScreen(boolean)} or because
     * the content is blocked.
     */
    public boolean isBlocked() {
        return isScreenBlocked() || isContentBlocked();
    }

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

    /** Returns {@code true} if the content is blocked, otherwise {@code false}. */
    public boolean isContentBlocked() {
        return mBlockedContentRating != null;
    }

    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.
     *
     * @param blockOrUnblock {@code true} to block the screen, or {@code false} to unblock.
     */
    public void blockOrUnblockScreen(boolean blockOrUnblock) {
        if (mScreenBlocked == blockOrUnblock) {
            return;
        }
        mScreenBlocked = blockOrUnblock;
        if (closePipIfNeeded()) {
            return;
        }
        updateBlockScreenAndMuting();
        if (mOnScreenBlockedListener != null) {
            mOnScreenBlockedListener.onScreenBlockingChanged(blockOrUnblock);
        }
    }

    @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) {
        if (mBlockScreenType != type) {
            mBlockScreenType = type;
            updateBlockScreen(true);
        }
    }

    private void updateBlockScreen(boolean animation) {
        mBlockScreenView.endAnimations();
        int blockReason =
                (mScreenBlocked || mBlockedContentRating != null) && mParentControlEnabled
                        ? VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED
                        : mVideoUnavailableReason;
        if (blockReason != VIDEO_UNAVAILABLE_REASON_NONE) {
            mBufferingSpinnerView.setVisibility(
                    blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING
                                    || blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
                            ? VISIBLE
                            : GONE);
            if (!animation) {
                adjustBlockScreenSpacingAndText();
            }
            if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
                return;
            }
            mBlockScreenView.setVisibility(VISIBLE);
            mBlockScreenView.setBackgroundImage(null);
            if (blockReason == VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED) {
                mBlockScreenView.setIconVisibility(true);
                if (!mCanModifyParentalControls) {
                    mBlockScreenView.setIconImage(R.drawable.ic_message_lock_no_permission);
                    mBlockScreenView.setIconScaleType(ImageView.ScaleType.CENTER);
                } else {
                    mBlockScreenView.setIconImage(R.drawable.ic_message_lock);
                    mBlockScreenView.setIconScaleType(ImageView.ScaleType.FIT_CENTER);
                }
            } else {
                if (mInternetCheckTask != null) {
                    mInternetCheckTask.cancel(true);
                    mInternetCheckTask = null;
                }
                mBlockScreenView.setIconVisibility(false);
                if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING) {
                    showImageForTuningIfNeeded();
                } else if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN
                        && mCurrentChannel != null
                        && !mCurrentChannel.isPhysicalTunerChannel()) {
                    mInternetCheckTask = new InternetCheckTask();
                    mInternetCheckTask.execute();
                }
            }
            mBlockScreenView.onBlockStatusChanged(mBlockScreenType, animation);
        } else {
            mBufferingSpinnerView.setVisibility(GONE);
            if (mBlockScreenView.getVisibility() == VISIBLE) {
                mBlockScreenView.fadeOut();
            }
        }
    }

    private void adjustBlockScreenSpacingAndText() {
        mBlockScreenView.setSpacing(mBlockScreenType);
        String text = getBlockScreenText();
        if (text != null) {
            mBlockScreenView.setInfoText(text);
        }
        mBlockScreenView.setInfoTextClickable(mScreenBlocked && mParentControlEnabled);
    }

    /**
     * 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() {
        // TODO: add a test for this method
        Resources res = getResources();
        boolean isA11y = mAccessibilityManager.isEnabled();

        if (mScreenBlocked && mParentControlEnabled) {
            switch (mBlockScreenType) {
                case BLOCK_SCREEN_TYPE_NO_UI:
                case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
                    return "";
                case BLOCK_SCREEN_TYPE_NORMAL:
                    if (mCanModifyParentalControls) {
                        return res.getString(
                                isA11y
                                        ? R.string.tvview_channel_locked_talkback
                                        : R.string.tvview_channel_locked);
                    } else {
                        return res.getString(R.string.tvview_channel_locked_no_permission);
                    }
            }
        } else if (mBlockedContentRating != null && mParentControlEnabled) {
            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 res.getString(R.string.shrunken_tvview_content_locked);
                    } else if (name.equals(res.getString(R.string.unrated_rating_name))) {
                        return res.getString(R.string.shrunken_tvview_content_locked_unrated);
                    } else {
                        return res.getString(R.string.shrunken_tvview_content_locked_format, name);
                    }
                case BLOCK_SCREEN_TYPE_NORMAL:
                    if (TextUtils.isEmpty(name)) {
                        if (mCanModifyParentalControls) {
                            return res.getString(
                                    isA11y
                                            ? R.string.tvview_content_locked_talkback
                                            : R.string.tvview_content_locked);
                        } else {
                            return res.getString(R.string.tvview_content_locked_no_permission);
                        }
                    } else {
                        if (mCanModifyParentalControls) {
                            return name.equals(res.getString(R.string.unrated_rating_name))
                                    ? res.getString(
                                            isA11y
                                                    ? R.string
                                                            .tvview_content_locked_unrated_talkback
                                                    : R.string.tvview_content_locked_unrated)
                                    : res.getString(
                                            isA11y
                                                    ? R.string.tvview_content_locked_format_talkback
                                                    : R.string.tvview_content_locked_format,
                                            name);
                        } else {
                            return name.equals(res.getString(R.string.unrated_rating_name))
                                    ? res.getString(
                                            R.string.tvview_content_locked_unrated_no_permission)
                                    : res.getString(
                                            R.string.tvview_content_locked_format_no_permission,
                                            name);
                        }
                    }
            }
        } else if (mVideoUnavailableReason != VIDEO_UNAVAILABLE_REASON_NONE) {
            switch (mVideoUnavailableReason) {
                case TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY:
                    return res.getString(R.string.tvview_msg_audio_only);
                case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
                    return res.getString(R.string.tvview_msg_weak_signal);
                case CommonConstants.VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED:
                    return res.getString(R.string.msg_channel_unavailable_not_connected);
                case VIDEO_UNAVAILABLE_REASON_NO_RESOURCE:
                    return getTuneConflictMessage();
                default:
                    return "";
            }
        }
        return null;
    }

    private boolean closePipIfNeeded() {
        if (TvFeatures.PICTURE_IN_PICTURE.isEnabled(getContext())
                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
                && ((Activity) getContext()).isInPictureInPictureMode()
                && (mScreenBlocked
                        || mBlockedContentRating != null
                        || mVideoUnavailableReason
                                == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN
                        || mVideoUnavailableReason
                                == CommonConstants.VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED)) {
            ((Activity) getContext()).finish();
            return true;
        }
        return false;
    }

    private void updateBlockScreenAndMuting() {
        updateBlockScreen(false);
        updateMuteStatus();
    }

    private boolean shouldShowImageForTuning() {
        if (mVideoUnavailableReason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
                || mScreenBlocked
                || mBlockedContentRating != null
                || mCurrentChannel == null
                || mIsUnderShrunken
                || getWidth() == 0
                || getWidth() == 0
                || !isBundledInput()) {
            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 showImageForTuningIfNeeded() {
        if (shouldShowImageForTuning()) {
            if (mCurrentChannel == null) {
                return;
            }
            Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
            if (currentProgram != null) {
                currentProgram.loadPosterArt(
                        getContext(),
                        getWidth(),
                        getHeight(),
                        createProgramPosterArtCallback(mCurrentChannel.getId()));
            }
        }
    }

    private String getTuneConflictMessage() {
        if (mTagetInputId != null) {
            TvInputInfo input = mInputManager.getTvInputInfo(mTagetInputId);
            Long timeMs = mInputSessionManager.getEarliestRecordingSessionEndTimeMs(mTagetInputId);
            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 updateMuteStatus() {
        // Workaround: BaseTunerTvInputService 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 || isVideoOrAudioAvailable())
                && !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
                && CommonUtils.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(
                        () -> {
                            mFadeState = FADING_OUT;
                            mActionAfterFade = actionAfterFade;
                        })
                .withEndAction(() -> 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(
                        () -> {
                            mFadeState = FADING_IN;
                            mActionAfterFade = actionAfterFade;
                        })
                .withEndAction(
                        () -> {
                            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}.
     */
    @Override
    public void setTimeShiftListener(TimeShiftListener listener) {
        mTimeShiftListener = listener;
    }

    public void setBlockedInfoOnClickListener(@Nullable OnClickListener onClickListener) {
        mBlockScreenView.setInfoTextOnClickListener(onClickListener);
    }

    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. */
    @Override
    public boolean isTimeShiftAvailable() {
        return mTimeShiftAvailable;
    }

    /** Plays the media, if the current input supports time-shifting. */
    @Override
    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. */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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. */
    @Override
    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<BlockScreenView> createProgramPosterArtCallback(
            final long channelId) {
        return new ImageLoader.ImageLoaderCallback<BlockScreenView>(mBlockScreenView) {
            @Override
            public void onBitmapLoaded(BlockScreenView view, @Nullable Bitmap posterArt) {
                if (posterArt == null
                        || getCurrentChannel() == null
                        || channelId != getCurrentChannel().getId()
                        || !shouldShowImageForTuning()) {
                    return;
                }
                Drawable drawablePosterArt = new BitmapDrawable(view.getResources(), posterArt);
                drawablePosterArt
                        .mutate()
                        .setColorFilter(mTuningImageColorFilter, PorterDuff.Mode.SRC_OVER);
                view.setBackgroundImage(drawablePosterArt);
            }
        };
    }

    /** A listener which receives the notification when the screen is blocked/unblocked. */
    public abstract static 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 (!networkAvailable
                    && isAttachedToWindow()
                    && !mScreenBlocked
                    && mBlockedContentRating == null
                    && mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) {
                mBlockScreenView.setIconVisibility(true);
                mBlockScreenView.setIconImage(R.drawable.ic_sad_cloud);
                mBlockScreenView.setInfoText(R.string.tvview_msg_no_internet_connection);
            }
        }
    }
}
