Skip to content

Commit f8a8260

Browse files
Daniel Yuandroid-build-merger
Daniel Yu
authored and
android-build-merger
committed
docs: Updating TIF docs for new TIF Companion library.
am: e081040 Change-Id: Ic44c96963d1dd172f07f6564a084ca731bf49762
2 parents 6aee6e9 + e081040 commit f8a8260

File tree

1 file changed

+263
-49
lines changed

1 file changed

+263
-49
lines changed

docs/html/training/tv/tif/tvinput.jd

Lines changed: 263 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ trainingnavtop=true
1010
<div id="tb">
1111
<h2>This lesson teaches you to</h2>
1212
<ol>
13-
<li><a href="#manifest">Declare Your TV Input Service in the Manifest</a></li>
14-
<li><a href="#tvinput">Define Your TV Input Service</a></li>
15-
<li><a href="#setup">Define Your Setup Activity</a></li>
13+
<li><a href="#TIFCompanion">Create a TV Input Service Using the TIF Companion Library</a></li>
14+
<li><a href="#NoTIFCompanion">Create a TV Input Service Using the TIF Framework</a></li>
1615
</ol>
1716
<h2>You should also read</h2>
1817
<ul>
@@ -30,14 +29,253 @@ trainingnavtop=true
3029
</div>
3130

3231
<p>A TV input service represents a media stream source, and lets you present your media content in a
33-
linear, broadcast TV fashion as channels and programs. With the TV input service, you can provide
32+
linear, broadcast TV fashion as channels and programs. With a TV input service, you can provide
3433
parental controls, program guide information, and content ratings. The TV input service works
35-
with the Android system TV app, developed for the device and immutable by third-party apps, which
36-
ultimately controls and presents content on the TV. See
34+
with the Android system TV app. This app ultimately controls and presents channel content
35+
on the TV. The system TV app is developed specifically for the device and immutable
36+
by third-party apps. For more information about the TV Input Framework (TIF)
37+
architecture and its components, see
3738
<a class="external-link" href="http://source.android.com/devices/tv/index.html">
38-
TV Input Framework</a> for more information about the framework architecture and its components.</p>
39+
TV Input Framework</a>.</p>
3940

40-
<p>To develop a TV input service, you implement the following components:</p>
41+
<h2 id="TIFCompanion">Create a TV Input Service Using the TIF Companion Library</h2>
42+
43+
<p>
44+
The TIF Companion Library is a framework that provides extensible
45+
implementations of common TV input service features. Use the TIF Companion
46+
Library to quickly and easily create your own TV input service that follows
47+
best practices for Android TV.
48+
</p>
49+
50+
<h3 id="build">Update your build.gradle file</h3>
51+
52+
<p>
53+
To get started using the TIF Companion Library, add the following line to your
54+
app's <code>build.gradle</code> file:
55+
</p>
56+
57+
<pre>
58+
compile 'com.google.android.media.tv.companionlibrary:1.0.0'
59+
</pre>
60+
61+
<p>The TIF Companion Library is not currently part of the Android
62+
framework. It is distributed as part of the <a class="external-link"
63+
href="https://github.com/googlesamples/androidtv-sample-inputs">
64+
TV Input Service sample app</a>, and not with the Android SDK.
65+
</p>
66+
67+
<h3 id="manifest">Declare your TV input service in the manifest</h3>
68+
69+
<p>Your app must provide a {@link android.media.tv.TvInputService}-compatible
70+
service that the system uses to access your app. The TIF
71+
Companion Library provides the <code>BaseTvInputService</code> class, which
72+
provides a default implementation of {@link android.media.tv.TvInputService}
73+
that you can customize. Create a subclass of <code>BaseTvInputService</code>,
74+
and declare the subclass in your manifest as a service.</p>
75+
76+
<p>Within the manifest declaration, specify the
77+
{@link android.Manifest.permission#BIND_TV_INPUT} permission to allow the
78+
service to connect the TV input to the system. A system service
79+
performs the binding and has the
80+
{@link android.Manifest.permission#BIND_TV_INPUT} permission.
81+
The system TV app sends requests to TV input services
82+
via the {@link android.media.tv.TvInputManager} interface.</p>
83+
84+
<p>In your service declaration, include an intent filter that specifies
85+
{@link android.media.tv.TvInputService} as the action to perform with the
86+
intent. Also declare the service metadata as a separate XML resource. The
87+
service declaration, intent filter, and service metadata declaration are shown
88+
in the following example:</p>
89+
90+
<pre>
91+
&lt;service android:name=".rich.RichTvInputService"
92+
android:label="@string/rich_input_label"
93+
android:permission="android.permission.BIND_TV_INPUT"&gt;
94+
&lt;!-- Required filter used by the system to launch our account service. --&gt;
95+
&lt;intent-filter&gt;
96+
&lt;action android:name="android.media.tv.TvInputService" /&gt;
97+
&lt;/intent-filter&gt;
98+
&lt;!-- An XML file which describes this input. This provides pointers to
99+
the RichTvInputSetupActivity to the system/TV app. --&gt;
100+
&lt;meta-data
101+
android:name="android.media.tv.input"
102+
android:resource="@xml/richtvinputservice" /&gt;
103+
&lt;/service&gt;
104+
</pre>
105+
106+
<p>Define the service metadata in a separate XML file. The service
107+
metadata XML file must include a setup interface that describes the TV input's
108+
initial configuration and channel scan. The metadata file should also contain a
109+
flag stating whether or not users are able to record content. For more
110+
information on how to support recording content in your app, see
111+
<a href="{@docRoot}preview/features/tv-recording-api.html">TV Recording</a>.
112+
</p>
113+
114+
<p>The service metadata file is located in the XML resources directory
115+
for your app and must match the name of the resource you declared in the
116+
manifest. Using the manifest entries from the previous example, you would
117+
create the XML file at <code>res/xml/richtvinputservice.xml</code>, with the
118+
following contents:</p>
119+
120+
<pre>
121+
&lt;?xml version="1.0" encoding="utf-8"?&gt;
122+
&lt;tv-input xmlns:android="http://schemas.android.com/apk/res/android"
123+
android:canRecord="true"
124+
android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" /&gt;
125+
</pre>
126+
127+
<h3 id="setup">Define channels and create your setup activity</h3>
128+
129+
<p>Your TV input service must define at least one channel that users
130+
access via the system TV app. You should register your channels
131+
in the system database, and provide a setup activity that the system
132+
invokes when it cannot find a channel for your app.</p>
133+
134+
<p>First, enable your app to read from and write to the system Electronic
135+
Programming Guide (EPG), whose data includes channels and programs available
136+
to the user. To enable your app to perform these actions, and sync with the
137+
EPG after device restart, add the following elements to your app manifest:</p>
138+
139+
<pre>
140+
&lt;uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" /&gt;
141+
&lt;uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /&gt;
142+
&lt;uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/&gt;
143+
</pre>
144+
145+
<p>Add the following element to ensure that your app shows up in the
146+
Google Play Store as an app that provides content channels in Android TV:</p>
147+
148+
<pre>
149+
&lt;uses-feature
150+
android:name="android.software.live_tv"
151+
android:required="true" /&gt;
152+
</pre>
153+
154+
<p>Next, create a class which extends the <code>EpgSyncJobService</code>
155+
class. This abstract class makes it easy to create a job service that
156+
creates and updates channels in the system database.</p>
157+
158+
<p>In your subclass, create and return your full list of channels in
159+
<code>getChannels()</code>. If your channels come from an XMLTV file,
160+
use the <code>XmlTvParser</code> class. Otherwise generate
161+
channels programmatically using the <code>Channel.Builder</code> class.
162+
</p>
163+
164+
<p>For each channel, the system calls <code>getProgramsForChannel()</code>
165+
when it needs a list of programs that can be viewed within a given time window
166+
on the channel. Return a list of <code>Program</code> objects for the
167+
channel. Use the <code>XmlTvParser</code> class to obtain programs from an
168+
XMLTV file, or generate them programmatically using the
169+
<code>Program.Builder</code> class.</p>
170+
171+
<p>For each <code>Program</code> object, use an
172+
<code>InternalProviderData</code> object to set program information such as the
173+
program's video type. If you only have a limited number of programs that you
174+
want the channel to repeat in a loop, use the
175+
<code>InternalProviderData.setRepeatable()</code> method with a value of
176+
<code>true</code> when setting information about your program.</p>
177+
178+
<p>After you've implemented the job service, add it to your app manifest:</p>
179+
180+
<pre>
181+
&lt;service
182+
android:name=".sync.SampleJobService"
183+
android:permission="android.permission.BIND_JOB_SERVICE"
184+
android:exported="true" /&gt;
185+
</pre>
186+
187+
<p>Finally, create a setup activity. Your setup activity should provide a way
188+
to sync channel and program data. One way to do this is for the user to do it
189+
via the UI in the activity. You might also have the app do it automatically
190+
when the activity starts. When the setup activity needs to sync channel and
191+
program info, the app should start the job service:</p>
192+
193+
<pre>
194+
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
195+
EpgSyncJobService.cancelAllSyncRequests(getActivity());
196+
EpgSyncJobService.requestImmediateSync(getActivity(), inputId,
197+
new ComponentName(getActivity(), SampleJobService.class));
198+
</pre>
199+
200+
<p>Use the <code>requestImmediateSync()</code> method to sync
201+
the job service. The user must wait for the sync to finish, so you should
202+
keep your request period relatively short.</p>
203+
204+
<p>Use the <code>setUpPeriodicSync()</code> method to have the job service
205+
periodically sync channel and program data in the background:</p>
206+
207+
<pre>
208+
EpgSyncJobService.setUpPeriodicSync(context, inputId,
209+
new ComponentName(context, SampleJobService.class));
210+
</pre>
211+
212+
<p>The TIF Companion Library provides an additional overloaded method of
213+
<code>requestImmediateSync()</code> that lets you specify the duration of
214+
channel data to sync in milliseconds. The default method syncs one hour's
215+
worth of channel data.
216+
</p>
217+
218+
<p>The TIF Companion Library also provides an additional overloaded method of
219+
<code>setUpPeriodicSync()</code> that lets you specify the duration of
220+
channel data to sync, and how often the periodic sync should occur. The
221+
default method syncs 48 hours of channel data every 12 hours.
222+
</p>
223+
224+
<p>For more details about channel data and the EPG, see
225+
<a href="{@docRoot}training/tv/tif/channel.html"> Working with Channel Data</a>.
226+
</p>
227+
228+
<h3 id="playback">Handle tuning requests and media playback</h3>
229+
230+
<p>When a user selects a specific channel, the system TV app uses a
231+
<code>Session</code>, created by your app, to tune to the requested channel
232+
and play content. The TIF Companion Library provides several
233+
classes you can extend to handle channel and session calls from the system.</p>
234+
235+
<p>Your <code>BaseTvInputService</code> subclass creates sessions which handle
236+
tuning requests. Override the
237+
<code>onCreateSession()</code> method, create a session extended from
238+
the <code>BaseTvInputService.Session</code> class, and call
239+
<code>super.sessionCreated()</code> with your new session. In the following
240+
example, <code>onCreateSession()</code> returns a
241+
<code>RichTvInputSessionImpl</code> object that extends
242+
<code>BaseTvInputService.Session</code>:</p>
243+
244+
<pre>
245+
&#64;Override
246+
public final Session onCreateSession(String inputId) {
247+
RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId);
248+
session.setOverlayViewEnabled(true);
249+
return super.sessionCreated(session);
250+
}
251+
</pre>
252+
253+
<p>When the user uses the system TV app to start viewing one of your channels,
254+
the system calls your session's <code>onPlayChannel()</code> method. Override
255+
this method if you need to do any special channel initialization before the
256+
program starts playing.</p>
257+
258+
<p>The system then obtains the currently scheduled program and calls your
259+
session's <code>onPlayProgram()</code> method, specifying the program
260+
information and start time in milliseconds. Use the
261+
<code>TvPlayer</code> interface to start playing the program.</p>
262+
263+
<p>Your media player code should implement <code>TvPlayer</code> to handle
264+
specific playback events. The <code>TvPlayer</code> class handles features
265+
like time-shifting controls without adding complexity to your
266+
<code>BaseTvInputService</code> implementation.</p>
267+
268+
<p>In your session's <code>getTvPlayer()</code> method, return
269+
your media player that implements <code>TvPlayer</code>. The
270+
<a class="external-link"
271+
href="https://github.com/googlesamples/androidtv-sample-inputs">
272+
TV Input Service sample app</a> implements a media player that uses
273+
<a href="{@docRoot}guide/topics/media/exoplayer.html">ExoPlayer</a>.</p>
274+
275+
<h2 id="NoTIFCompanion">Create a TV Input Service Using the TIF Framework</h2>
276+
277+
<p>If your TV input service can't use the TIF Companion Library, you need
278+
to implement the following components:</p>
41279

42280
<ul>
43281
<li>{@link android.media.tv.TvInputService} provides long-running and background availability for
@@ -56,43 +294,18 @@ TV Input Framework</a> for more information about the framework architecture and
56294
the interaction with TV inputs and apps</li>
57295
</ul>
58296

59-
<h2 id="manifest">Declare Your TV Input Service in the Manifest</h2>
60-
61-
<p>Your app manifest must declare your {@link android.media.tv.TvInputService}. Within that
62-
declaration, specify the {@link android.Manifest.permission#BIND_TV_INPUT} permission to allow the
63-
service to connect the TV input to the system. A system service (<code>TvInputManagerService</code>)
64-
performs the binding and has that permission. The system TV app sends requests to TV input services
65-
via the {@link android.media.tv.TvInputManager} interface. The service declaration must also
66-
include an intent filter that specifies the {@link android.media.tv.TvInputService}
67-
as the action to perform with the intent. Also within the service declaration, declare the service
68-
meta data in a separate XML resource. The service declaration, the intent filter and the service
69-
meta data are described in the following example.</p>
70-
71-
<pre>
72-
&lt;service android:name="com.example.sampletvinput.SampleTvInput"
73-
android:label="@string/sample_tv_input_label"
74-
android:permission="android.permission.BIND_TV_INPUT"&gt;
75-
&lt;intent-filter&gt;
76-
&lt;action android:name="android.media.tv.TvInputService" /&gt;
77-
&lt;/intent-filter&gt;
78-
&lt;meta-data android:name="android.media.tv.input"
79-
android:resource="@xml/sample_tv_input" /&gt;
80-
&lt;/service&gt;
81-
</pre>
82-
83-
<p>Define the service meta data in separate XML file, as shown in the following example. The service
84-
meta data must include a setup interface that describes the TV input's initial configuration and
85-
channel scan. The service meta data file is located in the XML resources directory
86-
for your application and must match the name of the resource in the manifest. Using the example
87-
manifest entries above, you would create an XML file in the location
88-
<code>res/xml/sample_tv_input.xml</code>, with the following contents:</p>
297+
<p>You also need to do the following:</p>
89298

90-
<pre>
91-
&lt;tv-input xmlns:android="http://schemas.android.com/apk/res/android"
92-
android:setupActivity="com.example.sampletvinput.SampleTvInputSetupActivity" /&gt;
93-
</pre>
299+
<ol>
300+
<li>Declare your TV input service in the manifest, as
301+
described in <a href="#manifest">Declare your TV input service in the
302+
manifest</a>.</li>
303+
<li>Create the service metadata file.</li>
304+
<li>Create and register your channel and program information.</li>
305+
<li>Create your setup activity.</li>
306+
</ol>
94307

95-
<h2 id="tvinput">Define Your TV Input Service</h2>
308+
<h3 id="tvinput">Define your TV input service</h3>
96309

97310
<div class="figure">
98311
<img id="tvinputlife" src="{@docRoot}images/tv/tvinput-life.png" alt=""/>
@@ -102,7 +315,7 @@ manifest entries above, you would create an XML file in the location
102315
<p>For your service, you extend the {@link android.media.tv.TvInputService} class. A
103316
{@link android.media.tv.TvInputService} implementation is a
104317
<a href="{@docRoot}guide/components/bound-services.html">bound service</a> where the system service
105-
(<code>TvInputManagerService</code>) is the client that binds to it. The service life cycle methods
318+
is the client that binds to it. The service life cycle methods
106319
you need to implement are illustrated in figure 1.</p>
107320

108321
<p>The {@link android.app.Service#onCreate()} method initializes and starts the
@@ -145,24 +358,25 @@ you may want to handle in your TV input service.</p>
145358

146359
<p>The {@link android.media.tv.TvInputService} creates a
147360
{@link android.media.tv.TvInputService.Session} that implements {@link android.os.Handler.Callback}
148-
to handle player state changes. With {@link android.media.tv.TvInputService.Session#onSetSurface(android.view.Surface) onSetSurface()},
361+
to handle player state changes. With
362+
{@link android.media.tv.TvInputService.Session#onSetSurface(android.view.Surface) onSetSurface()},
149363
the {@link android.media.tv.TvInputService.Session} sets the {@link android.view.Surface} with the
150364
video content. See <a href="{@docRoot}training/tv/tif/ui.html#surface">Integrate Player with Surface</a>
151365
for more information about working with {@link android.view.Surface} to render video.</p>
152366

153367
<p>The {@link android.media.tv.TvInputService.Session} handles the
154368
{@link android.media.tv.TvInputService.Session#onTune(android.net.Uri) onTune()}
155369
event when the user selects a channel, and notifies the system TV app for changes in the content and
156-
content meta data. These <code>notify()</code> methods are described in
370+
content metadata. These <code>notify()</code> methods are described in
157371
<a href="{@docRoot}training/tv/tif/ui.html#control">
158372
Control Content</a> and <a href="{@docRoot}training/tv/tif/ui.html#track">Handle Track Selection</a>
159373
further in this training.</p>
160374

161-
<h2 id="setup">Define Your Setup Activity</h2>
375+
<h3 id="setup">Define your setup activity</h3>
162376

163377
<p>The system TV app works with the setup activity you define for your TV input. The
164378
setup activity is required and must provide at least one channel record for the system database. The
165-
system TV app will invoke the setup activity when it cannot find a channel for the TV input.
379+
system TV app invokes the setup activity when it cannot find a channel for the TV input.
166380
<p>The setup activity describes to the system TV app the channels made available through the TV
167381
input, as demonstrated in the next lesson, <a href="{@docRoot}training/tv/tif/channel.html">Creating
168-
and Updating Channel Data</a>.</p>
382+
and Updating Channel Data</a>.</p>

0 commit comments

Comments
 (0)