TunableTvView.java revision 561696c364ee330f4316544f1f85498393883526
1d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leepackage com.android.tv.ui; 2900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 3900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.content.Context; 49035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvInputInfo; 59035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvInputManager; 69035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvInputManager.Session; 79035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvView; 8900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.os.Handler; 9900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.os.Message; 10900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.util.AttributeSet; 11900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.util.Log; 12900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport android.view.SurfaceHolder; 13900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 14900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Choimport com.android.internal.util.Preconditions; 15d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.data.Channel; 1621abb13274f379e69c3c86d51e493122cccca345Dongwon Kangimport com.android.tv.data.StreamInfo; 1721abb13274f379e69c3c86d51e493122cccca345Dongwon Kangimport com.android.tv.ui.TunableTvView.OnTuneListener; 18d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.util.TvInputManagerHelper; 19d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.util.Utils; 20900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 2121abb13274f379e69c3c86d51e493122cccca345Dongwon Kangpublic class TunableTvView extends TvView implements StreamInfo { 22900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private static final boolean DEBUG = true; 23900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private static final String TAG = "TunableTvView"; 24900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 25900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private static final int DELAY_FOR_SURFACE_RELEASE = 300; 26900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private static final int MSG_TUNE = 0; 27900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 28900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private float mVolume; 29900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private long mChannelId = Channel.INVALID_ID; 30900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private TvInputManagerHelper mInputManagerHelper; 31900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private boolean mStarted; 32900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private TvInputInfo mInputInfo; 33900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private TvInputManager.Session mSession; 34900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private OnTuneListener mOnTuneListener; 3521abb13274f379e69c3c86d51e493122cccca345Dongwon Kang private int mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN; 36e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang private int mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN; 37e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang private boolean mHasClosedCaption = false; 38900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private final Handler mHandler = new Handler() { 39900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 40900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void handleMessage(Message msg) { 41900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho switch (msg.what) { 42900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho case MSG_TUNE: 43900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Preconditions.checkState(mChannelId != Channel.INVALID_ID); 44900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Preconditions.checkNotNull(mSession); 45900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 46900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession.tune(Utils.getChannelUri(mChannelId)); 47900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (mOnTuneListener != null) { 48900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener.onTuned(true, mChannelId); 49900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 50900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho break; 51900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 52900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 53900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho }; 54900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 55900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { 56900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 57900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } 58900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 59900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 60900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void surfaceCreated(SurfaceHolder holder) { } 61900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 62900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 63900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void surfaceDestroyed(SurfaceHolder holder) { 64900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho // TODO: It is a hack to wait to release a surface at TIS. If there is a way to 65900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho // know when the surface is released at TIS, we don't need this hack. 66900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho try { 67900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (DEBUG) Log.d(TAG, "Sleep to wait destroying a surface"); 68900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Thread.sleep(DELAY_FOR_SURFACE_RELEASE); 69900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (DEBUG) Log.d(TAG, "Wake up from sleeping"); 70900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } catch (InterruptedException e) { 71900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho e.printStackTrace(); 72900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 73900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 74900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho }; 75900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 76900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho private final TvInputManager.SessionCallback mSessionCallback = 77900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho new TvInputManager.SessionCallback() { 78900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 79900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void onSessionCreated(TvInputManager.Session session) { 80900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (session != null) { 81900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession = session; 82561696c364ee330f4316544f1f85498393883526Jae Seo setStreamVolume(mVolume); 83900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mHandler.sendEmptyMessage(MSG_TUNE); 84900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } else { 85900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Log.w(TAG, "Failed to create a session"); 86900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho long channelId = mChannelId; 87900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mChannelId = Channel.INVALID_ID; 88900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = null; 89900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession = null; 90900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (mOnTuneListener != null) { 91900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener.onTuned(false, channelId); 92900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = null; 93900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 94900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 95900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 96900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 97900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho @Override 98900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void onSessionReleased(TvInputManager.Session session) { 99900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Log.w(TAG, "Session is released by crash"); 100900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho long channelId = mChannelId; 101900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mChannelId = Channel.INVALID_ID; 102900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = null; 103900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession = null; 104900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (mOnTuneListener != null) { 105900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener.onUnexpectedStop(channelId); 106900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = null; 107900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 108900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 10921abb13274f379e69c3c86d51e493122cccca345Dongwon Kang 11021abb13274f379e69c3c86d51e493122cccca345Dongwon Kang @Override 111fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang public void onVideoStreamChanged(Session session, int width, int height, 112fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang boolean interlaced) { 11321abb13274f379e69c3c86d51e493122cccca345Dongwon Kang mVideoFormat = Utils.getVideoDefinitionLevelFromSize(width, height); 11421abb13274f379e69c3c86d51e493122cccca345Dongwon Kang if (mOnTuneListener != null) { 11521abb13274f379e69c3c86d51e493122cccca345Dongwon Kang mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 11621abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 11721abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 118fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang 119fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang @Override 120fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang public void onAudioStreamChanged(Session session, int channelCount) { 121fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang mAudioChannelCount = channelCount; 122fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang if (mOnTuneListener != null) { 123fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 124fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 125fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 126fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang 127fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang @Override 128fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang public void onClosedCaptionStreamChanged(Session session, 129fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang boolean hasClosedCaption) { 130fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang mHasClosedCaption = hasClosedCaption; 131fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang if (mOnTuneListener != null) { 132fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang mOnTuneListener.onStreamInfoChanged(TunableTvView.this); 133fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 134fc4ae3d84120d40af0d1ce5da7b0b1e40003e9aaDongwon Kang } 135900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho }; 136900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 137900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context) { 138900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho this(context, null, 0); 139900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 140900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 141900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context, AttributeSet attrs) { 142900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho this(context, attrs, 0); 143900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 144900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 145900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr) { 146900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho super(context, attrs, defStyleAttr); 147900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho getHolder().addCallback(mSurfaceHolderCallback); 148900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 149900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 150900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void start(TvInputManagerHelper tvInputManagerHelper) { 151900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputManagerHelper = tvInputManagerHelper; 152900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (mStarted) { 153900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return; 154900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 155900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mStarted = true; 156900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 157900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 158900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public void stop() { 159900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 160900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return; 161900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 162900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mHandler.removeMessages(MSG_TUNE); 163900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mStarted = false; 164900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession = null; 165900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho unbindTvInput(); 166900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mChannelId = Channel.INVALID_ID; 167900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = null; 168900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = null; 169900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 170900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 171900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public boolean isPlaying() { 172900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return mStarted; 173900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 174900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 175900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public boolean tuneTo(long channelId, OnTuneListener listener) { 176900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 177900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho throw new IllegalStateException("TvView isn't started"); 178900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 179900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (DEBUG) Log.d(TAG, "tuneTo " + channelId); 180900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mHandler.removeMessages(MSG_TUNE); 18121abb13274f379e69c3c86d51e493122cccca345Dongwon Kang mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN; 182e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN; 183e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang mHasClosedCaption = false; 184900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho String inputId = Utils.getInputIdForChannel(getContext(), channelId); 185900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho TvInputInfo inputInfo = mInputManagerHelper.getTvInputInfo(inputId); 186900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (inputInfo == null || !mInputManagerHelper.isAvailable(inputInfo)) { 187900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return false; 188900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 189900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mOnTuneListener = listener; 190900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mChannelId = channelId; 191900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!inputInfo.equals(mInputInfo)) { 192900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mSession = null; 193900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho unbindTvInput(); 194900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 195900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho // TODO: It is a hack to wait to release a surface at TIS. If there is a way to 196900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho // know when the surface is released at TIS, we don't need this hack. 197900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho try { 198900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho Thread.sleep(DELAY_FOR_SURFACE_RELEASE); 199900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } catch (InterruptedException e) { 200900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho e.printStackTrace(); 201900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 202900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 203900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mInputInfo = inputInfo; 204900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho bindTvInput(mInputInfo.getId(), mSessionCallback); 205900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho // mChannelId will be tuned after onSessionCreated. 206900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } else { 20756008ca02c3d40e73fe6229b9eb95277d5c57129Youngsang Cho if (mSession == null) { 20856008ca02c3d40e73fe6229b9eb95277d5c57129Youngsang Cho // onSessionCreated is not called yet. MSG_TUNE will be sent in onSessionCreated. 20956008ca02c3d40e73fe6229b9eb95277d5c57129Youngsang Cho } else { 21056008ca02c3d40e73fe6229b9eb95277d5c57129Youngsang Cho mHandler.sendEmptyMessage(MSG_TUNE); 21156008ca02c3d40e73fe6229b9eb95277d5c57129Youngsang Cho } 212900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 213900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return true; 214900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 215900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 216900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public TvInputInfo getCurrentTvInputInfo() { 217900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return mInputInfo; 218900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 219900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 220900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public long getCurrentChannelId() { 221900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho return mChannelId; 222900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 223900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 224561696c364ee330f4316544f1f85498393883526Jae Seo @Override 225561696c364ee330f4316544f1f85498393883526Jae Seo public void setStreamVolume(float volume) { 226900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho if (!mStarted) { 227900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho throw new IllegalStateException("TvView isn't started"); 228900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 229561696c364ee330f4316544f1f85498393883526Jae Seo if (DEBUG) 230561696c364ee330f4316544f1f85498393883526Jae Seo Log.d(TAG, "setStreamVolume " + volume); 231900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho mVolume = volume; 232561696c364ee330f4316544f1f85498393883526Jae Seo super.setStreamVolume(volume); 233900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 234900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho 235900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho public interface OnTuneListener { 236900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho void onTuned(boolean success, long channelId); 237900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho void onUnexpectedStop(long channelId); 23821abb13274f379e69c3c86d51e493122cccca345Dongwon Kang void onStreamInfoChanged(StreamInfo info); 23921abb13274f379e69c3c86d51e493122cccca345Dongwon Kang } 24021abb13274f379e69c3c86d51e493122cccca345Dongwon Kang 24121abb13274f379e69c3c86d51e493122cccca345Dongwon Kang @Override 24221abb13274f379e69c3c86d51e493122cccca345Dongwon Kang public int getVideoDefinitionLevel() { 24321abb13274f379e69c3c86d51e493122cccca345Dongwon Kang return mVideoFormat; 244900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho } 245e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang 246e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang @Override 247e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang public int getAudioChannelCount() { 248e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang return mAudioChannelCount; 249e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang } 250e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang 251e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang @Override 252e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang public boolean hasClosedCaption() { 253e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang return mHasClosedCaption; 254e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang } 255900cc7509f1edf86db9ba1e4b71b7d1096769a0aYoungsang Cho} 256