11abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/*
21abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Copyright (C) 2015 The Android Open Source Project
31abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
41abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
51abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * you may not use this file except in compliance with the License.
61abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * You may obtain a copy of the License at
71abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
81abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
91abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Unless required by applicable law or agreed to in writing, software
111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * See the License for the specific language governing permissions and
141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * limitations under the License.
151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */
161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.tuner.tvinput;
181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
192e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.annotation.TargetApi;
201abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.content.Context;
211abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.media.PlaybackParams;
221abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.media.tv.TvContentRating;
231abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.media.tv.TvInputManager;
242e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.media.tv.TvInputService;
251abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.net.Uri;
262e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.os.Build;
271abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.os.Handler;
281abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.os.Message;
291abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.os.SystemClock;
301abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.text.Html;
311abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.util.Log;
321abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.LayoutInflater;
331abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.Surface;
341abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.View;
351abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.ViewGroup;
361abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.widget.TextView;
371abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.widget.Toast;
38944779887775bd950cf1abf348d2df461593f6abLive Channels Teamimport com.android.tv.common.CommonPreferences.CommonPreferencesChangedListener;
39944779887775bd950cf1abf348d2df461593f6abLive Channels Teamimport com.android.tv.common.util.SystemPropertiesProxy;
4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.tuner.R;
41633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.tuner.TunerPreferences;
4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.tuner.cc.CaptionLayout;
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.tuner.cc.CaptionTrackRenderer;
4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.tuner.data.Cea708Data.CaptionEvent;
45721bd0da688cd552737fbb753a00597f95103b95Adrian Roosimport com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
46d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.tuner.util.GlobalSettingsUtils;
4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.tuner.util.StatusTextUtils;
48a1589bd48e05abbee991e0cdd27fa402a5dc5001Live Channels Teamimport com.google.android.exoplayer.audio.AudioCapabilities;
491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/**
5195961816a768da387f0b5523cf4363ace2044089Nick Chalko * Provides a tuner TV input session. It handles Overlay UI works. Main tuner input functions are
5295961816a768da387f0b5523cf4363ace2044089Nick Chalko * implemented in {@link TunerSessionWorker}.
531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */
5495961816a768da387f0b5523cf4363ace2044089Nick Chalkopublic class TunerSession extends TvInputService.Session
55944779887775bd950cf1abf348d2df461593f6abLive Channels Team        implements Handler.Callback, CommonPreferencesChangedListener {
562e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static final String TAG = "TunerSession";
571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private static final boolean DEBUG = false;
5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final String USBTUNER_SHOW_DEBUG = "persist.tv.tuner.show_debug";
591abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
601abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_SHOW_MESSAGE = 1;
611abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_HIDE_MESSAGE = 2;
621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_SHOW_AUDIO_UNPLAYABLE = 3;
631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_HIDE_AUDIO_UNPLAYABLE = 4;
641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_PROCESS_CAPTION_TRACK = 5;
651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_START_CAPTION_TRACK = 6;
661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_STOP_CAPTION_TRACK = 7;
671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static final int MSG_UI_RESET_CAPTION_TRACK = 8;
68633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    public static final int MSG_UI_CLEAR_CAPTION_RENDERER = 9;
69633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    public static final int MSG_UI_SET_STATUS_TEXT = 10;
70633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    public static final int MSG_UI_TOAST_RESCAN_NEEDED = 11;
711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final Context mContext;
731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final Handler mUiHandler;
741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final View mOverlayView;
751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final TextView mMessageView;
761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final TextView mStatusView;
771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final TextView mAudioStatusView;
781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final ViewGroup mMessageLayout;
791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final CaptionTrackRenderer mCaptionTrackRenderer;
802e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private final TunerSessionWorker mSessionWorker;
811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private boolean mReleased = false;
821abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private boolean mPlayPaused;
831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private long mTuneStartTimestamp;
841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
85633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    public TunerSession(Context context, ChannelDataManager channelDataManager) {
861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        super(context);
871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mContext = context;
881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mUiHandler = new Handler(this);
8995961816a768da387f0b5523cf4363ace2044089Nick Chalko        LayoutInflater inflater =
9095961816a768da387f0b5523cf4363ace2044089Nick Chalko                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
911abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mOverlayView = inflater.inflate(R.layout.ut_overlay_view, null);
921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mMessageLayout = (ViewGroup) mOverlayView.findViewById(R.id.message_layout);
931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mMessageLayout.setVisibility(View.INVISIBLE);
941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mMessageView = (TextView) mOverlayView.findViewById(R.id.message);
951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mStatusView = (TextView) mOverlayView.findViewById(R.id.tuner_status);
961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        boolean showDebug = SystemPropertiesProxy.getBoolean(USBTUNER_SHOW_DEBUG, false);
971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mStatusView.setVisibility(showDebug ? View.VISIBLE : View.INVISIBLE);
981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mAudioStatusView = (TextView) mOverlayView.findViewById(R.id.audio_status);
991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mAudioStatusView.setVisibility(View.INVISIBLE);
1001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        CaptionLayout captionLayout = (CaptionLayout) mOverlayView.findViewById(R.id.caption);
1011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mCaptionTrackRenderer = new CaptionTrackRenderer(captionLayout);
102633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko        mSessionWorker = new TunerSessionWorker(context, channelDataManager, this);
103944779887775bd950cf1abf348d2df461593f6abLive Channels Team        TunerPreferences.setCommonPreferencesChangedListener(this);
1041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean isReleased() {
1071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return mReleased;
1081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public View onCreateOverlayView() {
1121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return mOverlayView;
1131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean onSelectTrack(int type, String trackId) {
11765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_SELECT_TRACK, type, 0, trackId);
1181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return false;
1191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onSetCaptionEnabled(boolean enabled) {
12365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mSessionWorker.setCaptionEnabled(enabled);
1241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onSetStreamVolume(float volume) {
12865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mSessionWorker.setStreamVolume(volume);
1291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean onSetSurface(Surface surface) {
13365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mSessionWorker.setSurface(surface);
1341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return true;
1351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onTimeShiftPause() {
1392e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_PAUSE);
1401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mPlayPaused = true;
1411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1441abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onTimeShiftResume() {
1452e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_RESUME);
1461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mPlayPaused = false;
1471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onTimeShiftSeekTo(long timeMs) {
1512e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        if (DEBUG) Log.d(TAG, "Timeshift seekTo requested position: " + timeMs / 1000);
15295961816a768da387f0b5523cf4363ace2044089Nick Chalko        mSessionWorker.sendMessage(
15395961816a768da387f0b5523cf4363ace2044089Nick Chalko                TunerSessionWorker.MSG_TIMESHIFT_SEEK_TO, mPlayPaused ? 1 : 0, 0, timeMs);
1541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
15895961816a768da387f0b5523cf4363ace2044089Nick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_SET_PLAYBACKPARAMS, params);
1591abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1601abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1611abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public long onTimeShiftGetStartPosition() {
1632e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        return mSessionWorker.getStartPosition();
1641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public long onTimeShiftGetCurrentPosition() {
1682e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        return mSessionWorker.getCurrentPosition();
1691abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean onTune(Uri channelUri) {
1731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        if (DEBUG) {
1741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            Log.d(TAG, "onTune to " + channelUri != null ? channelUri.toString() : "");
1751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
1761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        if (channelUri == null) {
1771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            Log.w(TAG, "onTune() is failed due to null channelUri.");
1782e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mSessionWorker.stopTune();
1791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            return false;
1801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
1811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mTuneStartTimestamp = SystemClock.elapsedRealtime();
1822e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSessionWorker.tune(channelUri);
1831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mPlayPaused = false;
1841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return true;
1851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1872e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    @TargetApi(Build.VERSION_CODES.N)
1881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1892e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public void onTimeShiftPlay(Uri recordUri) {
190ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        if (recordUri == null) {
1912e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            Log.w(TAG, "onTimeShiftPlay() is failed due to null channelUri.");
1922e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mSessionWorker.stopTune();
193ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            return;
194ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        }
195ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        mTuneStartTimestamp = SystemClock.elapsedRealtime();
1962e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSessionWorker.tune(recordUri);
197ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        mPlayPaused = false;
198ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    }
199ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
200ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    @Override
2011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onUnblockContent(TvContentRating unblockedRating) {
20295961816a768da387f0b5523cf4363ace2044089Nick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_UNBLOCKED_RATING, unblockedRating);
2031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
2061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void onRelease() {
2071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        if (DEBUG) {
2081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            Log.d(TAG, "onRelease");
2091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
2101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mReleased = true;
2112e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSessionWorker.release();
2121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mUiHandler.removeCallbacksAndMessages(null);
213944779887775bd950cf1abf348d2df461593f6abLive Channels Team        TunerPreferences.setCommonPreferencesChangedListener(null);
2141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
21695961816a768da387f0b5523cf4363ace2044089Nick Chalko    /** Sets {@link AudioCapabilities}. */
2172e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public void setAudioCapabilities(AudioCapabilities audioCapabilities) {
21895961816a768da387f0b5523cf4363ace2044089Nick Chalko        mSessionWorker.sendMessage(
21995961816a768da387f0b5523cf4363ace2044089Nick Chalko                TunerSessionWorker.MSG_AUDIO_CAPABILITIES_CHANGED, audioCapabilities);
2201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
2231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void notifyVideoAvailable() {
2241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        super.notifyVideoAvailable();
2251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        if (mTuneStartTimestamp != 0) {
22695961816a768da387f0b5523cf4363ace2044089Nick Chalko            Log.i(
22795961816a768da387f0b5523cf4363ace2044089Nick Chalko                    TAG,
22895961816a768da387f0b5523cf4363ace2044089Nick Chalko                    "[Profiler] Video available in "
22995961816a768da387f0b5523cf4363ace2044089Nick Chalko                            + (SystemClock.elapsedRealtime() - mTuneStartTimestamp)
23095961816a768da387f0b5523cf4363ace2044089Nick Chalko                            + " ms");
2311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            mTuneStartTimestamp = 0;
2321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
2331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
2361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void notifyVideoUnavailable(int reason) {
23765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        super.notifyVideoUnavailable(reason);
2381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING
2391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko                && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL) {
2401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE);
2411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
2421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2441abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void sendUiMessage(int message) {
2451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mUiHandler.sendEmptyMessage(message);
2461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void sendUiMessage(int message, Object object) {
2491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mUiHandler.obtainMessage(message, object).sendToTarget();
2501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2511abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void sendUiMessage(int message, int arg1, int arg2, Object object) {
2531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        mUiHandler.obtainMessage(message, arg1, arg2, object).sendToTarget();
2541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
2551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
2561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
2571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean handleMessage(Message msg) {
2581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        switch (msg.what) {
25995961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_SHOW_MESSAGE:
26095961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
26195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mMessageView.setText((String) msg.obj);
26295961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mMessageLayout.setVisibility(View.VISIBLE);
26395961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
26495961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
26595961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_HIDE_MESSAGE:
26695961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
26795961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mMessageLayout.setVisibility(View.INVISIBLE);
26895961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
26995961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
27095961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_SHOW_AUDIO_UNPLAYABLE:
27195961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
27295961816a768da387f0b5523cf4363ace2044089Nick Chalko                    // Showing message of enabling surround sound only when global surround sound
27395961816a768da387f0b5523cf4363ace2044089Nick Chalko                    // setting is "never".
27495961816a768da387f0b5523cf4363ace2044089Nick Chalko                    final int value =
27595961816a768da387f0b5523cf4363ace2044089Nick Chalko                            GlobalSettingsUtils.getEncodedSurroundOutputSettings(mContext);
27695961816a768da387f0b5523cf4363ace2044089Nick Chalko                    if (value == GlobalSettingsUtils.ENCODED_SURROUND_OUTPUT_NEVER) {
27795961816a768da387f0b5523cf4363ace2044089Nick Chalko                        mAudioStatusView.setText(
27895961816a768da387f0b5523cf4363ace2044089Nick Chalko                                Html.fromHtml(
27995961816a768da387f0b5523cf4363ace2044089Nick Chalko                                        StatusTextUtils.getAudioWarningInHTML(
28095961816a768da387f0b5523cf4363ace2044089Nick Chalko                                                mContext.getString(
28195961816a768da387f0b5523cf4363ace2044089Nick Chalko                                                        R.string.ut_surround_sound_disabled))));
28295961816a768da387f0b5523cf4363ace2044089Nick Chalko                    } else {
28395961816a768da387f0b5523cf4363ace2044089Nick Chalko                        mAudioStatusView.setText(
28495961816a768da387f0b5523cf4363ace2044089Nick Chalko                                Html.fromHtml(
28595961816a768da387f0b5523cf4363ace2044089Nick Chalko                                        StatusTextUtils.getAudioWarningInHTML(
28695961816a768da387f0b5523cf4363ace2044089Nick Chalko                                                mContext.getString(
28795961816a768da387f0b5523cf4363ace2044089Nick Chalko                                                        R.string
28895961816a768da387f0b5523cf4363ace2044089Nick Chalko                                                                .audio_passthrough_not_supported))));
28995961816a768da387f0b5523cf4363ace2044089Nick Chalko                    }
29095961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mAudioStatusView.setVisibility(View.VISIBLE);
29195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
29295961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
29395961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_HIDE_AUDIO_UNPLAYABLE:
29495961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
29595961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mAudioStatusView.setVisibility(View.INVISIBLE);
29695961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
29795961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
29895961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_PROCESS_CAPTION_TRACK:
29995961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
30095961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mCaptionTrackRenderer.processCaptionEvent((CaptionEvent) msg.obj);
30195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
30295961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
30395961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_START_CAPTION_TRACK:
30495961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
30595961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mCaptionTrackRenderer.start((AtscCaptionTrack) msg.obj);
30695961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
30795961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
30895961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_STOP_CAPTION_TRACK:
30995961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
31095961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mCaptionTrackRenderer.stop();
31195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
31295961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
31395961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_RESET_CAPTION_TRACK:
31495961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
31595961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mCaptionTrackRenderer.reset();
31695961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
31795961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
31895961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_CLEAR_CAPTION_RENDERER:
31995961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
32095961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mCaptionTrackRenderer.clear();
32195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
32295961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
32395961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_SET_STATUS_TEXT:
32495961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
32595961816a768da387f0b5523cf4363ace2044089Nick Chalko                    mStatusView.setText((CharSequence) msg.obj);
32695961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
32795961816a768da387f0b5523cf4363ace2044089Nick Chalko                }
32895961816a768da387f0b5523cf4363ace2044089Nick Chalko            case MSG_UI_TOAST_RESCAN_NEEDED:
32995961816a768da387f0b5523cf4363ace2044089Nick Chalko                {
33095961816a768da387f0b5523cf4363ace2044089Nick Chalko                    Toast.makeText(mContext, R.string.ut_rescan_needed, Toast.LENGTH_LONG).show();
33195961816a768da387f0b5523cf4363ace2044089Nick Chalko                    return true;
332d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
3331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
3341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return false;
3351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
336633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko
337633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    @Override
338944779887775bd950cf1abf348d2df461593f6abLive Channels Team    public void onCommonPreferencesChanged() {
339633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TUNER_PREFERENCES_CHANGED);
340633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko    }
3411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko}
342