TunableTvView.java revision 816a4be1a0f34f6a48877c8afd3dbbca19eac435
1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/* 2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project 3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License. 6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at 7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software 11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and 14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License. 15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 17d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leepackage com.android.tv.ui; 18900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.Animator; 20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.AnimatorInflater; 21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.AnimatorListenerAdapter; 22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.TimeInterpolator; 23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.annotation.SuppressLint; 24900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.content.Context; 25829ca34b57d208a84430b2ccecd8975598d086daYoungsang Choimport android.content.pm.PackageManager; 26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.PlaybackParams; 27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContentRating; 289035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvInputInfo; 294e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kimimport android.media.tv.TvInputManager; 305459428da9aca1b91e3a976a80e1db783caac674Dongwon Kangimport android.media.tv.TvTrackInfo; 319035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvView; 32d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkerstenimport android.media.tv.TvView.OnUnhandledInputEventListener; 33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvView.TvInputCallback; 34cdde1b3be4391c4b0d3b57cce3c63eee8c81819aDongwon Kangimport android.net.Uri; 352c62d08f28cddda68005660c5cf62c5874b7f587Sungsoo Limimport android.os.Bundle; 36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.support.annotation.IntDef; 37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.TextUtils; 38900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.util.AttributeSet; 39900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.util.Log; 40829ca34b57d208a84430b2ccecd8975598d086daYoungsang Choimport android.view.KeyEvent; 41829ca34b57d208a84430b2ccecd8975598d086daYoungsang Choimport android.view.MotionEvent; 42816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.SurfaceView; 43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.View; 44d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkerstenimport android.view.ViewGroup; 45d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkerstenimport android.widget.FrameLayout; 46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.widget.TextView; 47900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 484e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kimimport com.android.tv.R; 49816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.TvApplication; 50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.analytics.DurationTimer; 51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.analytics.Tracker; 52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.common.TvCommonConstants; 53d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.data.Channel; 5421abb13274f379e69c3c86d51e493122cccca345Dongwon Kangimport com.android.tv.data.StreamInfo; 55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.parental.ContentRatingsManager; 56d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.util.TvInputManagerHelper; 57d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.util.Utils; 58900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.lang.annotation.Retention; 60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.lang.annotation.RetentionPolicy; 615459428da9aca1b91e3a976a80e1db783caac674Dongwon Kangimport java.util.List; 625459428da9aca1b91e3a976a80e1db783caac674Dongwon Kang 63d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkerstenpublic class TunableTvView extends FrameLayout implements StreamInfo { 64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final boolean DEBUG = false; 65900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private static final String TAG = "TunableTvView"; 66900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 67829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho public static final String PERMISSION_RECEIVE_INPUT_EVENT = 68816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko "com.android.tv.permission.RECEIVE_INPUT_EVENT"; 69816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 70816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int VIDEO_UNAVAILABLE_REASON_NOT_TUNED = -1; 71816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 72816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int BLOCK_SCREEN_TYPE_NO_UI = 0; 73816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW = 1; 74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int BLOCK_SCREEN_TYPE_NORMAL = 2; 75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Retention(RetentionPolicy.SOURCE) 77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @IntDef({ TIME_SHIFT_STATE_NONE, TIME_SHIFT_STATE_PLAY, TIME_SHIFT_STATE_PAUSE, 78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko TIME_SHIFT_STATE_REWIND, TIME_SHIFT_STATE_FAST_FORWARD }) 79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public @interface TimeShiftState {} 80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int TIME_SHIFT_STATE_NONE = 0; 81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int TIME_SHIFT_STATE_PLAY = 1; 82816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int TIME_SHIFT_STATE_PAUSE = 2; 83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int TIME_SHIFT_STATE_REWIND = 3; 84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static final int TIME_SHIFT_STATE_FAST_FORWARD = 4; 85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 86816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int FADED_IN = 0; 87816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int FADED_OUT = 1; 88816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int FADING_IN = 2; 89816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int FADING_OUT = 3; 90816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 91816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final long INVALID_TIME = -1; 92816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 93816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // It is too small to see the description text without PIP_BLOCK_SCREEN_SCALE_FACTOR. 94816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final float PIP_BLOCK_SCREEN_SCALE_FACTOR = 1.2f; 95900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 96816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private AppLayerTvView mTvView; 97816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private Channel mCurrentChannel; 98900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private TvInputManagerHelper mInputManagerHelper; 99816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private ContentRatingsManager mContentRatingsManager; 100900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private boolean mStarted; 101900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private TvInputInfo mInputInfo; 102900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private OnTuneListener mOnTuneListener; 103e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim private int mVideoWidth; 104e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim private int mVideoHeight; 10521abb13274f379e69c3c86d51e493122cccca345Dongwon Kang private int mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN; 106816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private float mVideoFrameRate; 107e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang private int mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN; 108e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang private boolean mHasClosedCaption = false; 109816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private boolean mVideoAvailable; 110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private boolean mScreenBlocked; 111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private OnScreenBlockingChangedListener mOnScreenBlockedListener; 112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private TvContentRating mBlockedContentRating; 113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NOT_TUNED; 114829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho private boolean mCanReceiveInputEvent; 115d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten private boolean mIsMuted; 116d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten private float mVolume; 117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private boolean mParentControlEnabled; 118816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mFixedSurfaceWidth; 119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mFixedSurfaceHeight; 120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private boolean mIsPip; 121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mScreenHeight; 122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mShrunkenTvViewHeight; 123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 124816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @TimeShiftState private int mTimeShiftState = TIME_SHIFT_STATE_NONE; 125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private TimeShiftListener mTimeShiftListener; 126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private boolean mTimeShiftAvailable; 127816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private long mTimeShiftCurrentPositionMs = INVALID_TIME; 128816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 129816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final Tracker mTracker; 130816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final DurationTimer mChannelViewTimer = new DurationTimer(); 131816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 132816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // A block screen view which has lock icon with black background. 133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // This indicates that user's action is needed to play video. 134816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBlockScreenView; 135816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 136816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBlockScreenDescriptionView; 137816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBlockScreenIconView; 138816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBlockScreenShrunkenIconView; 139816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final TextView mBlockScreenTextView; 140816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 141816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // Animators used for fade in/out of block screen icon. 142816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final Animator mBlockScreenDescriptionFadeIn; 143816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final Animator mBlockScreenDescriptionFadeOut; 144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 145816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // A View to hide screen when there's problem in video playback. 146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mHideScreenView; 147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 148816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // A View to block screen until onContentAllowed is received if parental control is on. 149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBlockScreenForTuneView; 150900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // A spinner view to show buffering status. 152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mBufferingSpinnerView; 153816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 154816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // A View for fade-in/out animation 155816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final View mDimScreenView; 156816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mFadeState = FADED_IN; 157816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private Runnable mActionAfterFade; 158816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 159816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private int mBlockScreenType; 160816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 161816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private final TvInputCallback mCallback = 162816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko new TvInputCallback() { 163900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 164816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onConnectionFailed(String inputId) { 165816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Failed to bind an input"); 166816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Channel channel = mCurrentChannel; 167816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCurrentChannel = null; 168816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mInputInfo = null; 169816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCanReceiveInputEvent = false; 170816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnTuneListener != null) { 171816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // If tune is called inside onTuneFailed, mOnTuneListener will be set to 172816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // a new instance. In order to avoid to clear the new mOnTuneListener, 173816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // we copy mOnTuneListener to l and clear mOnTuneListener before 174816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // calling onTuneFailed. 175816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko OnTuneListener listener = mOnTuneListener; 176816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener = null; 177816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko listener.onTuneFailed(channel); 178816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 179816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 180816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 181816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 182816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onDisconnected(String inputId) { 183816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Session is released by crash"); 184816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Channel channel = mCurrentChannel; 185816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCurrentChannel = null; 186816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mInputInfo = null; 187816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCanReceiveInputEvent = false; 188816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnTuneListener != null) { 189816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko OnTuneListener listener = mOnTuneListener; 190816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener = null; 191816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko listener.onUnexpectedStop(channel); 192900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 193900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 194900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 195900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 1965459428da9aca1b91e3a976a80e1db783caac674Dongwon Kang public void onChannelRetuned(String inputId, Uri channelUri) { 1978f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo if (DEBUG) { 1985459428da9aca1b91e3a976a80e1db783caac674Dongwon Kang Log.d(TAG, "onChannelRetuned(inputId=" + inputId + ", channelUri=" 1995459428da9aca1b91e3a976a80e1db783caac674Dongwon Kang + channelUri + ")"); 2008f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo } 20121abb13274f379e69c3c86d51e493122cccca345Dongwon Kang if (mOnTuneListener != null) { 202816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener.onChannelRetuned(channelUri); 20321abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 20421abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 205fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang 206fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang @Override 207ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) { 208ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mHasClosedCaption = false; 209ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang for (TvTrackInfo track : tracks) { 210ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { 211ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mHasClosedCaption = true; 212ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang break; 213ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 214ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 215512017945a2cd192797d7ca404cba08d792877ddDongwon Kang if (mOnTuneListener != null) { 216512017945a2cd192797d7ca404cba08d792877ddDongwon Kang mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 217512017945a2cd192797d7ca404cba08d792877ddDongwon Kang } 218512017945a2cd192797d7ca404cba08d792877ddDongwon Kang } 219512017945a2cd192797d7ca404cba08d792877ddDongwon Kang 220512017945a2cd192797d7ca404cba08d792877ddDongwon Kang @Override 221ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang public void onTrackSelected(String inputId, int type, String trackId) { 222ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (trackId == null) { 223ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang // A track is unselected. 224512017945a2cd192797d7ca404cba08d792877ddDongwon Kang if (type == TvTrackInfo.TYPE_VIDEO) { 225ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoWidth = 0; 226ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoHeight = 0; 227ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN; 228816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoFrameRate = 0f; 229512017945a2cd192797d7ca404cba08d792877ddDongwon Kang } else if (type == TvTrackInfo.TYPE_AUDIO) { 230ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN; 231ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 232ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } else { 233ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang List<TvTrackInfo> tracks = getTracks(type); 234ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang boolean trackFound = false; 235ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (tracks != null) { 236ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang for (TvTrackInfo track : getTracks(type)) { 237ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (track.getId().equals(trackId)) { 238ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (type == TvTrackInfo.TYPE_VIDEO) { 239ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoWidth = track.getVideoWidth(); 240ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoHeight = track.getVideoHeight(); 241ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoFormat = Utils.getVideoDefinitionLevelFromSize( 242ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mVideoWidth, mVideoHeight); 243816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoFrameRate = track.getVideoFrameRate(); 244ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } else if (type == TvTrackInfo.TYPE_AUDIO) { 245ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mAudioChannelCount = track.getAudioChannelCount(); 246ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 247ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang trackFound = true; 248ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang break; 249ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 250ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 251ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang } 252ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang if (!trackFound) { 253ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang Log.w(TAG, "Invalid track ID: " + trackId); 2545459428da9aca1b91e3a976a80e1db783caac674Dongwon Kang } 255fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 256fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang if (mOnTuneListener != null) { 257fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 258fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 259fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 2604e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim 2614e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim @Override 2624e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim public void onVideoAvailable(String inputId) { 263816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unhideScreenByVideoAvailability(); 2644e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim if (mOnTuneListener != null) { 2654e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 2664e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 2674e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 2684e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim 2694e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim @Override 2704e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim public void onVideoUnavailable(String inputId, int reason) { 271816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko hideScreenByVideoAvailability(reason); 2724e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim if (mOnTuneListener != null) { 2734e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 2744e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 2754e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 276816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 277816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 278816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onContentAllowed(String inputId) { 279816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenForTuneView.setVisibility(View.GONE); 280816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unblockScreenByContentRating(); 281816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnTuneListener != null) { 282816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener.onContentAllowed(); 283816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 284816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 285816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 287816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onContentBlocked(String inputId, TvContentRating rating) { 288816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko blockScreenByContentRating(rating); 289816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnTuneListener != null) { 290816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener.onContentBlocked(); 291816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 292816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 293816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 294816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 295816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onTimeShiftStatusChanged(String inputId, int status) { 296816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setTimeShiftAvailable(status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE); 297816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 298900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho }; 299900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 300900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context) { 301d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten this(context, null); 302900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 303900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 304900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context, AttributeSet attrs) { 305900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho this(context, attrs, 0); 306900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 307900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 308900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr) { 309d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten this(context, attrs, defStyleAttr, 0); 310d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 311d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 312d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 313d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten super(context, attrs, defStyleAttr, defStyleRes); 314d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten inflate(getContext(), R.layout.tunable_tv_view, this); 315d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 316816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTracker = ((TvApplication) context.getApplicationContext()).getTracker(); 317816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenType = BLOCK_SCREEN_TYPE_NORMAL; 318816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenView = findViewById(R.id.block_screen); 319816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView = findViewById(R.id.block_screen_description); 320816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 321816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView = mBlockScreenView.findViewById(R.id.block_screen_icon); 322816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView = mBlockScreenView.findViewById( 323816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko R.id.block_screen_shrunken_icon); 324816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView = (TextView) mBlockScreenView.findViewById(R.id.block_screen_text); 325816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 326816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeIn = AnimatorInflater.loadAnimator(context, 327816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko R.animator.tvview_block_screen_fade_in); 328816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeIn.setTarget(mBlockScreenDescriptionView); 329816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeIn.addListener(new AnimatorListenerAdapter() { 330816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 331816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onAnimationStart(Animator animation) { 332816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko switch (mBlockScreenType) { 333816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NORMAL: 334816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView.setVisibility(VISIBLE); 335816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView.setVisibility(GONE); 336816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 337816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 338816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView.setVisibility(GONE); 339816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView.setVisibility(VISIBLE); 340816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 341816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 342816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setVisibility(VISIBLE); 343816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 344816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 345816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeOut = AnimatorInflater.loadAnimator(context, 346816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko R.animator.tvview_block_screen_fade_out); 347816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeOut.setTarget(mBlockScreenDescriptionView); 348816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeOut.addListener(new AnimatorListenerAdapter() { 349816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 350816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onAnimationEnd(Animator animation) { 351816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setVisibility(GONE); 352816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setAlpha(1f); 353816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko updateBlockScreenTextView(); 354816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 355816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 356816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 357816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mHideScreenView = findViewById(R.id.hide_screen); 358816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBufferingSpinnerView = findViewById(R.id.buffering_spinner); 359816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenForTuneView = findViewById(R.id.block_screen_for_tune); 360816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView = findViewById(R.id.dim); 361816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.animate().setListener(new AnimatorListenerAdapter() { 362816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 363816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onAnimationEnd(Animator animation) { 364816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mActionAfterFade != null) { 365816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mActionAfterFade.run(); 366816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 367816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 368816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 369816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 370816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onAnimationCancel(Animator animation) { 371816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mActionAfterFade != null) { 372816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mActionAfterFade.run(); 373816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 374816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 375816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 376816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 377816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 378816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void initialize(AppLayerTvView tvView, boolean isPip, int screenHeight, 379816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko int shrunkenTvViewHeight) { 380816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView = tvView; 381816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mIsPip = isPip; 382816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mScreenHeight = screenHeight; 383816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mShrunkenTvViewHeight = shrunkenTvViewHeight; 384816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setZOrderOnTop(isPip); 385816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko copyLayoutParamsToTvView(); 386900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 387900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 388900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void start(TvInputManagerHelper tvInputManagerHelper) { 389900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputManagerHelper = tvInputManagerHelper; 390816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager(); 391900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (mStarted) { 392900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return; 393900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 394900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mStarted = true; 395900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 396900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 397900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void stop() { 398900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 399900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return; 400900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 401900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mStarted = false; 402816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mCurrentChannel != null) { 403816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTracker.sendChannelViewStop(mCurrentChannel, mChannelViewTimer.reset()); 404816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 405816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko reset(); 406816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 407816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 408816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void reset() { 409d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mTvView.reset(); 410816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCurrentChannel = null; 411900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = null; 412829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho mCanReceiveInputEvent = false; 413900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = null; 414816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setTimeShiftAvailable(false); 415816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko hideScreenByVideoAvailability(VIDEO_UNAVAILABLE_REASON_NOT_TUNED); 416816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 417816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 418816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setMain() { 419816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setMain(); 420900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 421900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 422900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public boolean isPlaying() { 423900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return mStarted; 424900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 425900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 426816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 427816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Called when parental control is changed. 428816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 429816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onParentalControlChanged(boolean enabled) { 430816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mParentControlEnabled = enabled; 431816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!mParentControlEnabled) { 432816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenForTuneView.setVisibility(View.GONE); 433816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 434816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 435816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 436816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 437816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Tunes to a channel with the {@code channelId}. 438816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 439816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param params extra data to send it to TIS and store the data in TIMS. 440816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @return false, if the TV input is not a proper state to tune to a channel. For example, 441816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * if the state is disconnected or channelId doesn't exist, it returns false. 442816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 443816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public boolean tuneTo(Channel channel, Bundle params, OnTuneListener listener) { 444900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 445900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho throw new IllegalStateException("TvView isn't started"); 446900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 447816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (DEBUG) Log.d(TAG, "tuneTo " + channel); 448816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko TvInputInfo inputInfo = mInputManagerHelper.getTvInputInfo(channel.getInputId()); 449816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (inputInfo == null) { 450900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return false; 451900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 452816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mCurrentChannel != null) { 453816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTracker.sendChannelViewStop(mCurrentChannel, mChannelViewTimer.reset()); 454816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 455900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = listener; 456816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCurrentChannel = channel; 457816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTracker.sendChannelViewStart(mCurrentChannel); 458816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mChannelViewTimer.start(); 459816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko boolean needSurfaceSizeUpdate = false; 460900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!inputInfo.equals(mInputInfo)) { 461900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = inputInfo; 462d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mCanReceiveInputEvent = getContext().getPackageManager().checkPermission( 463816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getServiceInfo().packageName) 464829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho == PackageManager.PERMISSION_GRANTED; 465816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (DEBUG) { 466816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.d(TAG, "Input \'" + mInputInfo.getId() + "\' can receive input event: " 467816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko + mCanReceiveInputEvent); 468816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 469816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko needSurfaceSizeUpdate = true; 470816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 471816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoWidth = 0; 472816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoHeight = 0; 473816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN; 474816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoFrameRate = 0f; 475816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN; 476816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mHasClosedCaption = false; 477816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setCallback(mCallback); 478816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftCurrentPositionMs = INVALID_TIME; 479816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (TvCommonConstants.HAS_TIME_SHIFT_API) { 480816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // To reduce the IPCs, unregister the callback here and register it when necessary. 481816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setTimeShiftPositionCallback(null); 482816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 483816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setTimeShiftAvailable(false); 484816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params); 485816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) { 486816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // When the input is changed, TvView recreates its SurfaceView internally. 487816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView. 488816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko getSurfaceView().getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight); 489816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 490816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko hideScreenByVideoAvailability(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING); 491816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unblockScreenByContentRating(); 492816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (channel.isPassthrough()) { 493816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenForTuneView.setVisibility(View.GONE); 494816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else if (mParentControlEnabled) { 495816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenForTuneView.setVisibility(View.VISIBLE); 4969bb548ba08d7e222f276287fead545c6a11704d8Jae Seo } 4979bb548ba08d7e222f276287fead545c6a11704d8Jae Seo if (mOnTuneListener != null) { 498816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnTuneListener.onStreamInfoChanged(this); 499900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 500900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return true; 501900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 502900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 50387c1cbb508c96538d1e69ba1fdf3d9f4d52710d6Jaewan Kim @Override 504816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public Channel getCurrentChannel() { 505816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mCurrentChannel; 506900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 507900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 508816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 509816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Sets the current channel. Call this method only when setting the current channel without 510816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * actually tuning to it. 511816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 512816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param currentChannel The new current channel to set to. 513816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 514816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setCurrentChannel(Channel currentChannel) { 515816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mCurrentChannel = currentChannel; 516b47a0ad3227b940175fa4ecfe5c4113da72c8237Dongwon Kang } 517b47a0ad3227b940175fa4ecfe5c4113da72c8237Dongwon Kang 518561696c364ee330f4316544f1f85498393883526Jae Seo public void setStreamVolume(float volume) { 519900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 520900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho throw new IllegalStateException("TvView isn't started"); 521900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 522d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten if (DEBUG) Log.d(TAG, "setStreamVolume " + volume); 523d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mVolume = volume; 524d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten if (!mIsMuted) { 525d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mTvView.setStreamVolume(volume); 526d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 527900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 528900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 529816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 530816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Sets fixed size for the internal {@link android.view.Surface} of 531816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * {@link android.media.tv.TvView}. If either {@code width} or {@code height} is non positive, 532816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * the {@link android.view.Surface}'s size will be matched to the layout. 533816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 534816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Note: Once {@link android.view.SurfaceHolder#setFixedSize} is called, 535816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * {@link android.view.SurfaceView} and its underlying window can be misaligned, when the size 536816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * of {@link android.view.SurfaceView} is changed without changing either left position or top 537816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * position. For detail, please refer the codes of {@link android.view.SurfaceView#updateWindow} 538816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * . 539816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 540816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setFixedSurfaceSize(int width, int height) { 541816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFixedSurfaceWidth = width; 542816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFixedSurfaceHeight = height; 543816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) { 544816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // When the input is changed, TvView recreates its SurfaceView internally. 545816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView. 546816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko SurfaceView surfaceView = (SurfaceView) mTvView.getChildAt(0); 547816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko surfaceView.getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight); 548816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 549816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko SurfaceView surfaceView = (SurfaceView) mTvView.getChildAt(0); 550816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko surfaceView.getHolder().setSizeFromLayout(); 551816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 552816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 553816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 554829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho @Override 555829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho public boolean dispatchKeyEvent(KeyEvent event) { 556d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten return mCanReceiveInputEvent && mTvView.dispatchKeyEvent(event); 557829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho } 558829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho 559829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho @Override 560829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho public boolean dispatchTouchEvent(MotionEvent event) { 561d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten return mCanReceiveInputEvent && mTvView.dispatchTouchEvent(event); 562829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho } 563829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho 564829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho @Override 565829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho public boolean dispatchTrackballEvent(MotionEvent event) { 566d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten return mCanReceiveInputEvent && mTvView.dispatchTrackballEvent(event); 567829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho } 568829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho 569829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho @Override 570829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho public boolean dispatchGenericMotionEvent(MotionEvent event) { 571d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten return mCanReceiveInputEvent && mTvView.dispatchGenericMotionEvent(event); 572829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho } 573829ca34b57d208a84430b2ccecd8975598d086daYoungsang Cho 574900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public interface OnTuneListener { 575816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko void onTuneFailed(Channel channel); 576816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko void onUnexpectedStop(Channel channel); 57721abb13274f379e69c3c86d51e493122cccca345Dongwon Kang void onStreamInfoChanged(StreamInfo info); 578816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko void onChannelRetuned(Uri channel); 579816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko void onContentBlocked(); 580816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko void onContentAllowed(); 581816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 582816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 583816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void requestUnblockContent(TvContentRating rating) { 584816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.requestUnblockContent(rating); 58521abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 58621abb13274f379e69c3c86d51e493122cccca345Dongwon Kang 58721abb13274f379e69c3c86d51e493122cccca345Dongwon Kang @Override 588e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim public int getVideoWidth() { 589e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim return mVideoWidth; 590e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim } 591e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim 592e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim @Override 593e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim public int getVideoHeight() { 594e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim return mVideoHeight; 595e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim } 596e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim 597e06ded45d6e3b83e1a325e97ccd168c6d1c0d2deJaewan Kim @Override 59821abb13274f379e69c3c86d51e493122cccca345Dongwon Kang public int getVideoDefinitionLevel() { 59921abb13274f379e69c3c86d51e493122cccca345Dongwon Kang return mVideoFormat; 600900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 601e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang 602e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang @Override 603816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public float getVideoFrameRate() { 604816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mVideoFrameRate; 605816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 606816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 607816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 608e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang public int getAudioChannelCount() { 609e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang return mAudioChannelCount; 610e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang } 611e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang 612e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang @Override 613e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang public boolean hasClosedCaption() { 614e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang return mHasClosedCaption; 615e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang } 6164e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim 6174e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim @Override 6184e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim public boolean isVideoAvailable() { 619816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mVideoAvailable; 6204e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 6214e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim 6224e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim @Override 6234e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim public int getVideoUnavailableReason() { 6244e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim return mVideoUnavailableReason; 6254e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim } 626d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 627816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 628816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns the {@link android.view.SurfaceView} of the {@link android.media.tv.TvView}. 629816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 630816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public SurfaceView getSurfaceView() { 631816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return (SurfaceView) mTvView.getChildAt(0); 632816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 633816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 634d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) { 635d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mTvView.setOnUnhandledInputEventListener(listener); 636d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 637d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 638816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setClosedCaptionEnabled(boolean enabled) { 639816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setCaptionEnabled(enabled); 640816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 641816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 642ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang public List<TvTrackInfo> getTracks(int type) { 643ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang return mTvView.getTracks(type); 644d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 645d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 646816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public String getSelectedTrack(int type) { 647816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mTvView.getSelectedTrack(type); 648816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 649816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 650ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang public void selectTrack(int type, String trackId) { 651ec9bd88036279df7421321b2e9945adf8f89db4bDongwon Kang mTvView.selectTrack(type, trackId); 652d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 653d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 654816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 655816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns if the screen is blocked by {@link #blockScreen()}. 656816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 657816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public boolean isScreenBlocked() { 658816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mScreenBlocked; 659816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 660816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 661816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setOnScreenBlockedListener(OnScreenBlockingChangedListener listener) { 662816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnScreenBlockedListener = listener; 663816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 664816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 665816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 666816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns currently blocked content rating. {@code null} if it's not blocked. 667816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 668816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public TvContentRating getBlockedContentRating() { 669816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mBlockedContentRating; 670816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 671816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 672816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 673816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Locks current TV screen and mutes. 674816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * There would be black screen with lock icon in order to show that 675816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * screen block is intended and not an error. 676816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * TODO: Accept parameter to show lock icon or not. 677816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 678816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void blockScreen() { 679816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mScreenBlocked = true; 680816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko checkBlockScreenAndMuteNeeded(); 681816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnScreenBlockedListener != null) { 682816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnScreenBlockedListener.onScreenBlockingChanged(true); 683816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 684816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 685816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 686816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void blockScreenByContentRating(TvContentRating rating) { 687816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockedContentRating = rating; 688816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko checkBlockScreenAndMuteNeeded(); 689816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 690816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 691816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 692816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @SuppressLint("RtlHardcoded") 693816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 694816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko super.onLayout(changed, left, top, right, bottom); 695816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mIsPip) { 696816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko int height = bottom - top; 697816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko float scale; 698816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenType == BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW) { 699816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko scale = height * PIP_BLOCK_SCREEN_SCALE_FACTOR / mShrunkenTvViewHeight; 700816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 701816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko scale = height * PIP_BLOCK_SCREEN_SCALE_FACTOR / mScreenHeight; 702816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 703816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // TODO: need to get UX confirmation. 704816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setScaleX(scale); 705816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setScaleY(scale); 706816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 707816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 708816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 709816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 710816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setLayoutParams(ViewGroup.LayoutParams params) { 711816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko super.setLayoutParams(params); 712816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTvView != null) { 713816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko copyLayoutParamsToTvView(); 714816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 715816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 716816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 717816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void copyLayoutParamsToTvView() { 718816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); 719816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko FrameLayout.LayoutParams tvViewLp = (FrameLayout.LayoutParams) mTvView.getLayoutParams(); 720816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (tvViewLp.bottomMargin != lp.bottomMargin 721816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.topMargin != lp.topMargin 722816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.leftMargin != lp.leftMargin 723816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.rightMargin != lp.rightMargin 724816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.gravity != lp.gravity 725816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.height != lp.height 726816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || tvViewLp.width != lp.width) { 727816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (lp.topMargin == tvViewLp.topMargin && lp.leftMargin == tvViewLp.leftMargin) { 728816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // HACK: If top and left position aren't changed and SurfaceHolder.setFixedSize is 729816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // used, SurfaceView doesn't catch the width and height change. It causes a bug that 730816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // PIP size change isn't shown when PIP is located TOP|LEFT. So we adjust 1 px for 731816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // small size PIP as a workaround. 732816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.leftMargin = lp.leftMargin + 1; 733816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 734816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.leftMargin = lp.leftMargin; 735816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 736816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.topMargin = lp.topMargin; 737816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.bottomMargin = lp.bottomMargin; 738816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.rightMargin = lp.rightMargin; 739816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.gravity = lp.gravity; 740816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.height = lp.height; 741816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko tvViewLp.width = lp.width; 742816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setLayoutParams(tvViewLp); 743816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 744816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 745816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 746816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 747816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko protected void onVisibilityChanged(View changedView, int visibility) { 748816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko super.onVisibilityChanged(changedView, visibility); 749816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTvView != null) { 750816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setVisibility(visibility); 751816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 752816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 753816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 754816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 755816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Set the type of block screen. If {@code type} is set to {@code BLOCK_SCREEN_TYPE_NO_UI}, the 756816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * block screen will not show any description such as a lock icon and a text for the blocked 757816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * reason, if {@code type} is set to {@code BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW}, the block screen 758816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * will show the description for shrunken tv view (Small icon and short text), and if 759816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * {@code type} is set to {@code BLOCK_SCREEN_TYPE_NORMAL}, the block screen will show the 760816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * description for normal tv view (Big icon and long text). 761816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 762816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param type The type of block screen to set. 763816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 764816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setBlockScreenType(int type) { 765816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // TODO: need to support the transition from NORMAL to SHRUNKEN and vice verse. 766816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenType != type) { 767816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenType = type; 768816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko updateBlockScreenUI(true); 769816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 770816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 771816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 772816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void updateBlockScreenUI(boolean animation) { 773816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenDescriptionFadeIn.isRunning()) { 774816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeIn.end(); 775816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 776816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenDescriptionFadeOut.isRunning()) { 777816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeOut.end(); 778816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 779816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 780816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!mScreenBlocked && mBlockedContentRating == null) { 781816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenView.setVisibility(GONE); 782816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 783816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 784816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 785816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenView.setVisibility(VISIBLE); 786816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!animation) { 787816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko updateBlockScreenTextView(); 788816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko switch (mBlockScreenType) { 789816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NO_UI: 790816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView.setVisibility(GONE); 791816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView.setVisibility(GONE); 792816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setVisibility(GONE); 793816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 794816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 795816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView.setVisibility(GONE); 796816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView.setVisibility(VISIBLE); 797816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setVisibility(VISIBLE); 798816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 799816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NORMAL: 800816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenIconView.setVisibility(VISIBLE); 801816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenShrunkenIconView.setVisibility(GONE); 802816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionView.setVisibility(VISIBLE); 803816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 804816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 805816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 806816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko switch (mBlockScreenType) { 807816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NO_UI: 808816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenDescriptionView.getVisibility() == VISIBLE) { 809816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeOut.start(); 810816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 811816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 812816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 813816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NORMAL: 814816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko updateBlockScreenTextView(); 815816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mBlockScreenDescriptionView.getVisibility() == GONE) { 816816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenDescriptionFadeIn.start(); 817816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 818816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 819816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 820816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 821816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 822816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 823816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void updateBlockScreenTextView() { 824816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // TODO: need to add animation for padding change when the block screen type is changed 825816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // NORMAL to SHRUNKEN and vice verse. 826816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setPadding(0, 827816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko getResources().getDimensionPixelOffset( 828816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenType == BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW 829816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko ? R.dimen.shrunken_tvview_block_text_padding_top 830816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko : R.dimen.tvview_block_text_padding_top), 831816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 0, 0); 832816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 833816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mScreenBlocked) { 834816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko switch (mBlockScreenType) { 835816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NO_UI: 836816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 837816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(""); 838816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 839816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NORMAL: 840816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(R.string.tvview_channel_locked); 841816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 842816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 843816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else if (mBlockedContentRating != null) { 844816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko String name = mContentRatingsManager.getDisplayNameForRating(mBlockedContentRating); 845816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko switch (mBlockScreenType) { 846816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NO_UI: 847816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(""); 848816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 849816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 850816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (TextUtils.isEmpty(name)) { 851816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(R.string.shrunken_tvview_content_locked); 852816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 853816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(getContext().getString( 854816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko R.string.shrunken_tvview_content_locked_format, name)); 855816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 856816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 857816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case BLOCK_SCREEN_TYPE_NORMAL: 858816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (TextUtils.isEmpty(name)) { 859816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(R.string.tvview_content_locked); 860816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 861816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockScreenTextView.setText(getContext().getString( 862816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko R.string.tvview_content_locked_format, name)); 863816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 864816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko break; 865816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 866816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 867816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 868816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 869816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void checkBlockScreenAndMuteNeeded() { 870816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko updateBlockScreenUI(false); 871816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mScreenBlocked || mBlockedContentRating != null) { 872816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mute(); 873816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mIsPip) { 874816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // If we don't make mTvView invisible, some frames are leaked when a user changes 875816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // PIP layout in options. 876816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // Note: When video is unavailable, we keep the mTvView's visibility, because 877816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // TIS implementation may not send video available with no surface. 878816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setVisibility(View.INVISIBLE); 879816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 880816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 881816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unmuteIfPossible(); 882816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mIsPip) { 883816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setVisibility(View.VISIBLE); 884816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 885816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 886816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 887816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 888816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void unblockScreen() { 889816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mScreenBlocked = false; 890816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko checkBlockScreenAndMuteNeeded(); 891816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mOnScreenBlockedListener != null) { 892816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mOnScreenBlockedListener.onScreenBlockingChanged(false); 893816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 894816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 895816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 896816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void unblockScreenByContentRating() { 897816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBlockedContentRating = null; 898816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko checkBlockScreenAndMuteNeeded(); 899816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 900816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 901816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void hideScreenByVideoAvailability(int reason) { 902d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten switch (reason) { 903816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING: 904816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBufferingSpinnerView.setVisibility(VISIBLE); 905d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten break; 906816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN: 907c91a6ff8aca631d682764bc7a771cc79fbd41c75Jae Seo case TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING: 908d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL: 909816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko case VIDEO_UNAVAILABLE_REASON_NOT_TUNED: 910816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko default: 911816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mHideScreenView.setVisibility(VISIBLE); 912816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBufferingSpinnerView.setVisibility(GONE); 913d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten break; 914d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 915816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoAvailable = false; 916816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoUnavailableReason = reason; 917d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mute(); 918d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 919d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 920816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void unhideScreenByVideoAvailability() { 921816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mVideoAvailable = true; 922816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mHideScreenView.setVisibility(GONE); 923816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mBufferingSpinnerView.setVisibility(GONE); 924816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unmuteIfPossible(); 925816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 926816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 927816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void unmuteIfPossible() { 928816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mVideoAvailable && !mScreenBlocked && mBlockedContentRating == null) { 929816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko unmute(); 930816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 931d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 932d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 933d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten private void mute() { 934d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mIsMuted = true; 935d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mTvView.setStreamVolume(0); 936d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 937d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 938d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten private void unmute() { 939d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mIsMuted = false; 940d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten mTvView.setStreamVolume(mVolume); 941d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 942d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten 943816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** Returns true if this view is faded out. */ 944816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public boolean isFadedOut() { 945816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mFadeState == FADED_OUT; 946816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 947816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 948816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** Fade out this TunableTvView. Fade out by increasing the dimming. */ 949816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void fadeOut(int durationMillis, TimeInterpolator interpolator, 950816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko final Runnable actionAfterFade) { 951816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setAlpha(0f); 952816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setVisibility(View.VISIBLE); 953816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.animate() 954816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .alpha(1f) 955816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .setDuration(durationMillis) 956816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .setInterpolator(interpolator) 957816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .withStartAction(new Runnable() { 958816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 959816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void run() { 960816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFadeState = FADING_OUT; 961816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mActionAfterFade = actionAfterFade; 962816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 963816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }) 964816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .withEndAction(new Runnable() { 965816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 966816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void run() { 967816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFadeState = FADED_OUT; 968816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 969816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 970816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 971816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 972816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** Fade in this TunableTvView. Fade in by decreasing the dimming. */ 973816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void fadeIn(int durationMillis, TimeInterpolator interpolator, 974816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko final Runnable actionAfterFade) { 975816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setAlpha(1f); 976816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setVisibility(View.VISIBLE); 977816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.animate() 978816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .alpha(0f) 979816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .setDuration(durationMillis) 980816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .setInterpolator(interpolator) 981816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .withStartAction(new Runnable() { 982816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 983816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void run() { 984816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFadeState = FADING_IN; 985816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mActionAfterFade = actionAfterFade; 986816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 987816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }) 988816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko .withEndAction(new Runnable() { 989816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 990816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void run() { 991816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFadeState = FADED_IN; 992816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setVisibility(View.GONE); 993816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 994816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 995816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 996816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 997816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** Remove the fade effect. */ 998816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void removeFadeEffect() { 999816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.animate().cancel(); 1000816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mDimScreenView.setVisibility(View.GONE); 1001816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mFadeState = FADED_IN; 1002816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1003816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1004816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1005816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Sets the TimeShiftListener 1006816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 1007816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param listener The instance of {@link TimeShiftListener}. 1008816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1009816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void setTimeShiftListener(TimeShiftListener listener) { 1010816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftListener = listener; 1011816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1012816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1013816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private void setTimeShiftAvailable(boolean isTimeShiftAvailable) { 1014816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API || mTimeShiftAvailable == isTimeShiftAvailable) { 1015816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1016816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1017816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftAvailable = isTimeShiftAvailable; 1018816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (isTimeShiftAvailable) { 1019816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() { 1020816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 1021816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onTimeShiftStartPositionChanged(String inputId, long timeMs) { 1022816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTimeShiftListener != null && mCurrentChannel != null 1023816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko && mCurrentChannel.getInputId().equals(inputId)) { 1024816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftListener.onRecordStartTimeChanged(timeMs); 1025816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1026816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1027816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1028816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 1029816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) { 1030816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftCurrentPositionMs = timeMs; 1031816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1032816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko }); 1033816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 1034816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.setTimeShiftPositionCallback(null); 1035816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1036816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTimeShiftListener != null) { 1037816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftListener.onAvailabilityChanged(); 1038816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1039816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1040816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1041816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1042816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns if the time shift is available for the current channel. 1043816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1044816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public boolean isTimeShiftAvailable() { 1045816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mTimeShiftAvailable; 1046816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1047816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1048816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1049816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns the current time-shift state. It returns one of {@link #TIME_SHIFT_STATE_NONE}, 1050816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * {@link #TIME_SHIFT_STATE_PLAY}, {@link #TIME_SHIFT_STATE_PAUSE}, 1051816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * {@link #TIME_SHIFT_STATE_REWIND}, {@link #TIME_SHIFT_STATE_FAST_FORWARD} 1052816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * or {@link #TIME_SHIFT_STATE_PAUSE}. 1053816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1054816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @TimeShiftState public int getTimeShiftState() { 1055816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mTimeShiftState; 1056816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1057816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1058816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1059816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Plays the media, if the current input supports time-shifting. 1060816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1061816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void timeshiftPlay() { 1062816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1063816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1064816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1065816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1066816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1067816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1068816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1069816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTimeShiftState == TIME_SHIFT_STATE_PLAY) { 1070816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1071816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1072816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.timeShiftResume(); 1073816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1074816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1075816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1076816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Pauses the media, if the current input supports time-shifting. 1077816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1078816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void timeshiftPause() { 1079816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1080816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1081816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1082816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1083816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1084816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1085816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1086816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (mTimeShiftState == TIME_SHIFT_STATE_PAUSE) { 1087816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1088816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1089816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.timeShiftPause(); 1090816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1091816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1092816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1093816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Rewinds the media with the given speed, if the current input supports time-shifting. 1094816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 1095816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param speed The speed to rewind the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x. 1096816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1097816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void timeshiftRewind(int speed) { 1098816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1099816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1100816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1101816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1102816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1103816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1104816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1105816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (speed <= 0) { 1106816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalArgumentException("The speed should be a positive integer."); 1107816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1108816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftState = TIME_SHIFT_STATE_REWIND; 1109816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko PlaybackParams params = new PlaybackParams(); 1110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko params.setSpeed(speed * -1); 1111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.timeShiftSetPlaybackParams(params); 1112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1114816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1115816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Fast-forwards the media with the given speed, if the current input supports time-shifting. 1116816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 1117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param speed The speed to forward the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x. 1118816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void timeshiftFastForward(int speed) { 1120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1124816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1127816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (speed <= 0) { 1128816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalArgumentException("The speed should be a positive integer."); 1129816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1130816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTimeShiftState = TIME_SHIFT_STATE_FAST_FORWARD; 1131816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko PlaybackParams params = new PlaybackParams(); 1132816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko params.setSpeed(speed); 1133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.timeShiftSetPlaybackParams(params); 1134816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1135816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1136816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1137816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Seek to the given time position. 1138816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 1139816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * @param timeMs The time in milliseconds to seek to. 1140816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1141816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void timeshiftSeekTo(long timeMs) { 1142816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1143816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return; 1145816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1148816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mTvView.timeShiftSeekTo(timeMs); 1150816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1153816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Returns the current playback position in milliseconds. 1154816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1155816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public long timeshiftGetCurrentPositionMs() { 1156816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!TvCommonConstants.HAS_TIME_SHIFT_API) { 1157816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Time shifting is not supported in this platform."); 1158816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return INVALID_TIME; 1159816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1160816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (!isTimeShiftAvailable()) { 1161816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko throw new IllegalStateException("Time-shift is not supported for the current channel"); 1162816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1163816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (DEBUG) { 1164816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.d(TAG, "timeshiftGetCurrentPositionMs: current position =" 1165816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko + Utils.toTimeString(mTimeShiftCurrentPositionMs)); 1166816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1167816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return mTimeShiftCurrentPositionMs; 1168816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1169816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1170816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1171816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Used to receive the time-shift events. 1172816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1173816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static abstract class TimeShiftListener { 1174816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1175816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Called when the availability of the time-shift for the current channel has been changed. 1176816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * It should be guaranteed that this is called only when the availability is really changed. 1177816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1178816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public abstract void onAvailabilityChanged(); 1179816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1180816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1181816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Called when the record start time has been changed.. 1182816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1183816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public abstract void onRecordStartTimeChanged(long recordStartTimeMs); 1184816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 1185816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 1186816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1187816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * A listener which receives the notification when the screen is blocked/unblocked. 1188816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1189816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static abstract class OnScreenBlockingChangedListener { 1190816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 1191816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Called when the screen is blocked/unblocked. 1192816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 1193816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public abstract void onScreenBlockingChanged(boolean blocked); 1194d82ca62a0fefaed41493540df7d622cfcfb2cb6cChristofer Åkersten } 1195900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho} 1196