1 package com.android.tv.samples.sampletunertvinput; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.media.tv.TvInputInfo; 6 import android.media.tv.TvInputService; 7 import android.media.tv.tuner.Tuner; 8 import android.media.tv.tuner.dvr.DvrPlayback; 9 import android.media.tv.tuner.dvr.DvrSettings; 10 import android.media.tv.tuner.filter.Filter; 11 import android.media.tv.tuner.filter.FilterCallback; 12 import android.media.tv.tuner.filter.FilterEvent; 13 import android.media.tv.tuner.filter.SectionEvent; 14 import android.os.Bundle; 15 import android.os.Handler; 16 import android.os.Looper; 17 import android.util.Log; 18 19 import com.android.tv.common.util.Clock; 20 import com.android.tv.testing.data.ChannelInfo; 21 import com.android.tv.testing.data.ChannelUtils; 22 import com.android.tv.testing.data.ProgramInfo; 23 import com.android.tv.testing.data.ProgramUtils; 24 25 import java.util.Collections; 26 import java.util.Locale; 27 import java.util.concurrent.TimeUnit; 28 29 /** Setup activity for SampleTunerTvInput */ 30 public class SampleTunerTvInputSetupActivity extends Activity { 31 private static final String TAG = "SampleTunerTvInput"; 32 private static final boolean DEBUG = true; 33 34 private static final boolean USE_DVR = true; 35 private static final String SETUP_INPUT_FILE_NAME = "setup.ts"; 36 37 private Tuner mTuner; 38 private DvrPlayback mDvr; 39 private Filter mSectionFilter; 40 41 @Override onCreate(Bundle savedInstanceState)42 public void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 initTuner(); 45 } 46 47 @Override onDestroy()48 public void onDestroy() { 49 super.onDestroy(); 50 if (mTuner != null) { 51 mTuner.close(); 52 mTuner = null; 53 } 54 if (mDvr != null) { 55 mDvr.close(); 56 mDvr = null; 57 } 58 if (mSectionFilter != null) { 59 mSectionFilter.close(); 60 mSectionFilter = null; 61 } 62 } 63 setChannel(byte[] sectionData)64 private void setChannel(byte[] sectionData) { 65 SampleTunerTvInputSectionParser.TvctChannelInfo channelInfo = 66 SampleTunerTvInputSectionParser.parseTvctSection(sectionData); 67 68 String channelNumber = ""; 69 String channelName = ""; 70 71 if(channelInfo == null) { 72 Log.e(TAG, "Did not receive channel description from parser"); 73 } else { 74 channelNumber = String.format(Locale.US, "%d-%d", channelInfo.getMajorChannelNumber(), 75 channelInfo.getMinorChannelNumber()); 76 channelName = channelInfo.getChannelName(); 77 } 78 79 ChannelInfo channel = 80 new ChannelInfo.Builder() 81 .setNumber(channelNumber) 82 .setName(channelName) 83 .setLogoUrl( 84 ChannelInfo.getUriStringForChannelLogo(this, 100)) 85 .setOriginalNetworkId(1) 86 .setVideoWidth(640) 87 .setVideoHeight(480) 88 .setAudioChannel(2) 89 .setAudioLanguageCount(1) 90 .setHasClosedCaption(false) 91 .build(); 92 93 Intent intent = getIntent(); 94 String inputId = intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID); 95 ChannelUtils.updateChannels(this, inputId, Collections.singletonList(channel)); 96 ProgramUtils.updateProgramForAllChannelsOf(this, inputId, Clock.SYSTEM, 97 TimeUnit.DAYS.toMillis(1)); 98 99 setResult(Activity.RESULT_OK); 100 finish(); 101 } 102 sectionFilterCallback()103 private FilterCallback sectionFilterCallback() { 104 return new FilterCallback() { 105 @Override 106 public void onFilterEvent(Filter filter, FilterEvent[] events) { 107 if (DEBUG) { 108 Log.d(TAG, "onFilterEvent setup section, size=" + events.length); 109 } 110 for (int i = 0; i < events.length; i++) { 111 if (DEBUG) { 112 Log.d(TAG, "events[" + i + "] is " 113 + events[i].getClass().getSimpleName()); 114 } 115 if (events[i] instanceof SectionEvent) { 116 SectionEvent sectionEvent = (SectionEvent) events[i]; 117 int dataSize = (int)sectionEvent.getDataLengthLong(); 118 if (DEBUG) { 119 Log.d(TAG, "section dataSize:" + dataSize); 120 } 121 122 byte[] data = new byte[dataSize]; 123 filter.read(data, 0, dataSize); 124 125 setChannel(data); 126 } 127 } 128 } 129 130 @Override 131 public void onFilterStatusChanged(Filter filter, int status) { 132 if (DEBUG) { 133 Log.d(TAG, "onFilterStatusChanged setup section, status=" + status); 134 } 135 } 136 }; 137 } 138 139 private void initTuner() { 140 mTuner = new Tuner(getApplicationContext(), null, 141 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE); 142 Handler handler = new Handler(Looper.myLooper()); 143 144 mSectionFilter = SampleTunerTvInputUtils.createSectionFilter(mTuner, handler, 145 sectionFilterCallback()); 146 mSectionFilter.start(); 147 148 // Dvr Playback can be used to read a file instead of relying on physical tuner 149 if (USE_DVR) { 150 mDvr = SampleTunerTvInputUtils.configureDvrPlayback(mTuner, handler, 151 DvrSettings.DATA_FORMAT_TS); 152 SampleTunerTvInputUtils.readFilePlaybackInput(getApplicationContext(), mDvr, 153 SETUP_INPUT_FILE_NAME); 154 mDvr.start(); 155 } else { 156 SampleTunerTvInputUtils.tune(mTuner, handler); 157 } 158 } 159 160 } 161