• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media.tv;
18 
19 import android.annotation.Nullable;
20 import android.annotation.SystemApi;
21 import android.content.ComponentName;
22 import android.content.ContentResolver;
23 import android.content.ContentUris;
24 import android.content.Intent;
25 import android.net.Uri;
26 import android.os.IBinder;
27 import android.provider.BaseColumns;
28 import android.util.ArraySet;
29 
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 
34 /**
35  * The contract between the TV provider and applications. Contains definitions for the supported
36  * URIs and columns.
37  * <h3>Overview</h3>
38  *
39  * <p>TvContract defines a basic database of TV content metadata such as channel and program
40  * information. The information is stored in {@link Channels} and {@link Programs} tables.
41  *
42  * <ul>
43  *     <li>A row in the {@link Channels} table represents information about a TV channel. The data
44  *         format can vary greatly from standard to standard or according to service provider, thus
45  *         the columns here are mostly comprised of basic entities that are usually seen to users
46  *         regardless of standard such as channel number and name.</li>
47  *     <li>A row in the {@link Programs} table represents a set of data describing a TV program such
48  *         as program title and start time.</li>
49  * </ul>
50  */
51 public final class TvContract {
52     /** The authority for the TV provider. */
53     public static final String AUTHORITY = "android.media.tv";
54 
55     private static final String PATH_CHANNEL = "channel";
56     private static final String PATH_PROGRAM = "program";
57     private static final String PATH_PASSTHROUGH = "passthrough";
58 
59     /**
60      * An optional query, update or delete URI parameter that allows the caller to specify TV input
61      * ID to filter channels.
62      * @hide
63      */
64     public static final String PARAM_INPUT = "input";
65 
66     /**
67      * An optional query, update or delete URI parameter that allows the caller to specify channel
68      * ID to filter programs.
69      * @hide
70      */
71     public static final String PARAM_CHANNEL = "channel";
72 
73     /**
74      * An optional query, update or delete URI parameter that allows the caller to specify start
75      * time (in milliseconds since the epoch) to filter programs.
76      * @hide
77      */
78     public static final String PARAM_START_TIME = "start_time";
79 
80     /**
81      * An optional query, update or delete URI parameter that allows the caller to specify end time
82      * (in milliseconds since the epoch) to filter programs.
83      * @hide
84      */
85     public static final String PARAM_END_TIME = "end_time";
86 
87     /**
88      * A query, update or delete URI parameter that allows the caller to operate on all or
89      * browsable-only channels. If set to "true", the rows that contain non-browsable channels are
90      * not affected.
91      * @hide
92      */
93     public static final String PARAM_BROWSABLE_ONLY = "browsable_only";
94 
95     /**
96      * A optional query, update or delete URI parameter that allows the caller to specify canonical
97      * genre to filter programs.
98      * @hide
99      */
100     public static final String PARAM_CANONICAL_GENRE = "canonical_genre";
101 
102     /**
103      * Builds an ID that uniquely identifies a TV input service.
104      *
105      * @param name The {@link ComponentName} of the TV input service to build ID for.
106      * @return the ID for the given TV input service.
107      */
buildInputId(ComponentName name)108     public static final String buildInputId(ComponentName name) {
109         return name.flattenToShortString();
110     }
111 
112     /**
113      * Builds a URI that points to a specific channel.
114      *
115      * @param channelId The ID of the channel to point to.
116      */
buildChannelUri(long channelId)117     public static final Uri buildChannelUri(long channelId) {
118         return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId);
119     }
120 
121     /**
122      * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
123      *
124      * @param inputId The ID of the pass-through input to build a channels URI for.
125      * @see TvInputInfo#isPassthroughInput()
126      */
buildChannelUriForPassthroughInput(String inputId)127     public static final Uri buildChannelUriForPassthroughInput(String inputId) {
128         return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
129                 .appendPath(PATH_PASSTHROUGH).appendPath(inputId).build();
130     }
131 
132     /**
133      * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
134      *
135      * @param channelId The ID of the channel whose logo is pointed to.
136      */
buildChannelLogoUri(long channelId)137     public static final Uri buildChannelLogoUri(long channelId) {
138         return buildChannelLogoUri(buildChannelUri(channelId));
139     }
140 
141     /**
142      * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
143      *
144      * @param channelUri The URI of the channel whose logo is pointed to.
145      */
buildChannelLogoUri(Uri channelUri)146     public static final Uri buildChannelLogoUri(Uri channelUri) {
147         if (!isChannelUriForTunerInput(channelUri)) {
148             throw new IllegalArgumentException("Not a channel: " + channelUri);
149         }
150         return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY);
151     }
152 
153     /**
154      * Builds a URI that points to all channels from a given TV input.
155      *
156      * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
157      *            URI for all the TV inputs.
158      */
buildChannelsUriForInput(@ullable String inputId)159     public static final Uri buildChannelsUriForInput(@Nullable String inputId) {
160         return buildChannelsUriForInput(inputId, false);
161     }
162 
163     /**
164      * Builds a URI that points to all or browsable-only channels from a given TV input.
165      *
166      * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
167      *            URI for all the TV inputs.
168      * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
169      *            to {@code false} the URI points to all channels regardless of whether they are
170      *            browsable or not.
171      * @hide
172      */
173     @SystemApi
buildChannelsUriForInput(@ullable String inputId, boolean browsableOnly)174     public static final Uri buildChannelsUriForInput(@Nullable String inputId,
175             boolean browsableOnly) {
176         Uri.Builder builder = Channels.CONTENT_URI.buildUpon();
177         if (inputId != null) {
178             builder.appendQueryParameter(PARAM_INPUT, inputId);
179         }
180         return builder.appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly))
181                 .build();
182     }
183 
184     /**
185      * Builds a URI that points to all or browsable-only channels which have programs with the given
186      * genre from the given TV input.
187      *
188      * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
189      *            URI for all the TV inputs.
190      * @param genre {@link Programs.Genres} to search. If {@code null}, builds a URI for all genres.
191      * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
192      *            to {@code false} the URI points to all channels regardless of whether they are
193      *            browsable or not.
194      * @hide
195      */
196     @SystemApi
buildChannelsUriForInput(@ullable String inputId, @Nullable String genre, boolean browsableOnly)197     public static final Uri buildChannelsUriForInput(@Nullable String inputId,
198             @Nullable String genre, boolean browsableOnly) {
199         if (genre == null) {
200             return buildChannelsUriForInput(inputId, browsableOnly);
201         }
202         if (!Programs.Genres.isCanonical(genre)) {
203             throw new IllegalArgumentException("Not a canonical genre: '" + genre + "'");
204         }
205         return buildChannelsUriForInput(inputId, browsableOnly).buildUpon()
206                 .appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build();
207     }
208 
209     /**
210      * Builds a URI that points to a specific program.
211      *
212      * @param programId The ID of the program to point to.
213      */
buildProgramUri(long programId)214     public static final Uri buildProgramUri(long programId) {
215         return ContentUris.withAppendedId(Programs.CONTENT_URI, programId);
216     }
217 
218     /**
219      * Builds a URI that points to all programs on a given channel.
220      *
221      * @param channelId The ID of the channel to return programs for.
222      */
buildProgramsUriForChannel(long channelId)223     public static final Uri buildProgramsUriForChannel(long channelId) {
224         return Programs.CONTENT_URI.buildUpon()
225                 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
226     }
227 
228     /**
229      * Builds a URI that points to all programs on a given channel.
230      *
231      * @param channelUri The URI of the channel to return programs for.
232      */
buildProgramsUriForChannel(Uri channelUri)233     public static final Uri buildProgramsUriForChannel(Uri channelUri) {
234         if (!isChannelUriForTunerInput(channelUri)) {
235             throw new IllegalArgumentException("Not a channel: " + channelUri);
236         }
237         return buildProgramsUriForChannel(ContentUris.parseId(channelUri));
238     }
239 
240     /**
241      * Builds a URI that points to programs on a specific channel whose schedules overlap with the
242      * given time frame.
243      *
244      * @param channelId The ID of the channel to return programs for.
245      * @param startTime The start time used to filter programs. The returned programs should have
246      *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
247      * @param endTime The end time used to filter programs. The returned programs should have
248      *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
249      */
buildProgramsUriForChannel(long channelId, long startTime, long endTime)250     public static final Uri buildProgramsUriForChannel(long channelId, long startTime,
251             long endTime) {
252         Uri uri = buildProgramsUriForChannel(channelId);
253         return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime))
254                 .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build();
255     }
256 
257     /**
258      * Builds a URI that points to programs on a specific channel whose schedules overlap with the
259      * given time frame.
260      *
261      * @param channelUri The URI of the channel to return programs for.
262      * @param startTime The start time used to filter programs. The returned programs should have
263      *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
264      * @param endTime The end time used to filter programs. The returned programs should have
265      *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
266      */
buildProgramsUriForChannel(Uri channelUri, long startTime, long endTime)267     public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
268             long endTime) {
269         if (!isChannelUriForTunerInput(channelUri)) {
270             throw new IllegalArgumentException("Not a channel: " + channelUri);
271         }
272         return buildProgramsUriForChannel(ContentUris.parseId(channelUri), startTime, endTime);
273     }
274 
275     /**
276      * Builds a URI that points to a specific program the user watched.
277      *
278      * @param watchedProgramId The ID of the watched program to point to.
279      * @hide
280      */
buildWatchedProgramUri(long watchedProgramId)281     public static final Uri buildWatchedProgramUri(long watchedProgramId) {
282         return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
283     }
284 
isTvUri(Uri uri)285     private static boolean isTvUri(Uri uri) {
286         return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())
287                 && AUTHORITY.equals(uri.getAuthority());
288     }
289 
isTwoSegmentUriStartingWith(Uri uri, String pathSegment)290     private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) {
291         List<String> pathSegments = uri.getPathSegments();
292         return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0));
293     }
294 
295     /**
296      * Returns true, if {@code uri} is a channel URI.
297      * @hide
298      */
isChannelUri(Uri uri)299     public static final boolean isChannelUri(Uri uri) {
300         return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri);
301     }
302 
303     /**
304      * Returns true, if {@code uri} is a channel URI for a tuner input.
305      * @hide
306      */
isChannelUriForTunerInput(Uri uri)307     public static final boolean isChannelUriForTunerInput(Uri uri) {
308         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL);
309     }
310 
311     /**
312      * Returns true, if {@code uri} is a channel URI for a passthrough input.
313      * @hide
314      */
315     @SystemApi
isChannelUriForPassthroughInput(Uri uri)316     public static final boolean isChannelUriForPassthroughInput(Uri uri) {
317         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH);
318     }
319 
320     /**
321      * Returns true, if {@code uri} is a program URI.
322      * @hide
323      */
isProgramUri(Uri uri)324     public static final boolean isProgramUri(Uri uri) {
325         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM);
326     }
327 
328 
TvContract()329     private TvContract() {}
330 
331     /**
332      * Common base for the tables of TV channels/programs.
333      */
334     public interface BaseTvColumns extends BaseColumns {
335         /**
336          * The name of the package that owns the current row.
337          *
338          * <p>The TV provider fills in this column with the name of the package that provides the
339          * initial data of the row. If the package is later uninstalled, the rows it owns are
340          * automatically removed from the tables.
341          *
342          * <p>Type: TEXT
343          */
344         String COLUMN_PACKAGE_NAME = "package_name";
345     }
346 
347     /** Column definitions for the TV channels table. */
348     public static final class Channels implements BaseTvColumns {
349 
350         /** The content:// style URI for this table. */
351         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
352                 + PATH_CHANNEL);
353 
354         /** The MIME type of a directory of TV channels. */
355         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
356 
357         /** The MIME type of a single TV channel. */
358         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
359 
360         /** A generic channel type. */
361         public static final String TYPE_OTHER = "TYPE_OTHER";
362 
363         /** The channel type for NTSC. */
364         public static final String TYPE_NTSC = "TYPE_NTSC";
365 
366         /** The channel type for PAL. */
367         public static final String TYPE_PAL = "TYPE_PAL";
368 
369         /** The channel type for SECAM. */
370         public static final String TYPE_SECAM = "TYPE_SECAM";
371 
372         /** The channel type for DVB-T (terrestrial). */
373         public static final String TYPE_DVB_T = "TYPE_DVB_T";
374 
375         /** The channel type for DVB-T2 (terrestrial). */
376         public static final String TYPE_DVB_T2 = "TYPE_DVB_T2";
377 
378         /** The channel type for DVB-S (satellite). */
379         public static final String TYPE_DVB_S = "TYPE_DVB_S";
380 
381         /** The channel type for DVB-S2 (satellite). */
382         public static final String TYPE_DVB_S2 = "TYPE_DVB_S2";
383 
384         /** The channel type for DVB-C (cable). */
385         public static final String TYPE_DVB_C = "TYPE_DVB_C";
386 
387         /** The channel type for DVB-C2 (cable). */
388         public static final String TYPE_DVB_C2 = "TYPE_DVB_C2";
389 
390         /** The channel type for DVB-H (handheld). */
391         public static final String TYPE_DVB_H = "TYPE_DVB_H";
392 
393         /** The channel type for DVB-SH (satellite). */
394         public static final String TYPE_DVB_SH = "TYPE_DVB_SH";
395 
396         /** The channel type for ATSC (terrestrial). */
397         public static final String TYPE_ATSC_T = "TYPE_ATSC_T";
398 
399         /** The channel type for ATSC (cable). */
400         public static final String TYPE_ATSC_C = "TYPE_ATSC_C";
401 
402         /** The channel type for ATSC-M/H (mobile/handheld). */
403         public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
404 
405         /** The channel type for ISDB-T (terrestrial). */
406         public static final String TYPE_ISDB_T = "TYPE_ISDB_T";
407 
408         /** The channel type for ISDB-Tb (Brazil). */
409         public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB";
410 
411         /** The channel type for ISDB-S (satellite). */
412         public static final String TYPE_ISDB_S = "TYPE_ISDB_S";
413 
414         /** The channel type for ISDB-C (cable). */
415         public static final String TYPE_ISDB_C = "TYPE_ISDB_C";
416 
417         /** The channel type for 1seg (handheld). */
418         public static final String TYPE_1SEG = "TYPE_1SEG";
419 
420         /** The channel type for DTMB (terrestrial). */
421         public static final String TYPE_DTMB = "TYPE_DTMB";
422 
423         /** The channel type for CMMB (handheld). */
424         public static final String TYPE_CMMB = "TYPE_CMMB";
425 
426         /** The channel type for T-DMB (terrestrial). */
427         public static final String TYPE_T_DMB = "TYPE_T_DMB";
428 
429         /** The channel type for S-DMB (satellite). */
430         public static final String TYPE_S_DMB = "TYPE_S_DMB";
431 
432         /** A generic service type. */
433         public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
434 
435         /** The service type for regular TV channels that have both audio and video. */
436         public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
437 
438         /** The service type for radio channels that have audio only. */
439         public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
440 
441         /** The video format for 240p. */
442         public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
443 
444         /** The video format for 360p. */
445         public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
446 
447         /** The video format for 480i. */
448         public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
449 
450         /** The video format for 480p. */
451         public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
452 
453         /** The video format for 576i. */
454         public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
455 
456         /** The video format for 576p. */
457         public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
458 
459         /** The video format for 720p. */
460         public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
461 
462         /** The video format for 1080i. */
463         public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
464 
465         /** The video format for 1080p. */
466         public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
467 
468         /** The video format for 2160p. */
469         public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
470 
471         /** The video format for 4320p. */
472         public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
473 
474         /** The video resolution for standard-definition. */
475         public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
476 
477         /** The video resolution for enhanced-definition. */
478         public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
479 
480         /** The video resolution for high-definition. */
481         public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
482 
483         /** The video resolution for full high-definition. */
484         public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
485 
486         /** The video resolution for ultra high-definition. */
487         public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
488 
489         private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>();
490 
491         static {
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD)492             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED)493             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD)494             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED)495             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD)496             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD)497             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD)498             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD)499             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD);
VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD)500             VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD);
501         }
502 
503         /**
504          * Returns the video resolution (definition) for a given video format.
505          *
506          * @param videoFormat The video format defined in {@link Channels}.
507          * @return the corresponding video resolution string. {@code null} if the resolution string
508          *         is not defined for the given video format.
509          * @see #COLUMN_VIDEO_FORMAT
510          */
511         @Nullable
getVideoResolution(String videoFormat)512         public static final String getVideoResolution(String videoFormat) {
513             return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat);
514         }
515 
516         /**
517          * The ID of the TV input service that provides this TV channel.
518          *
519          * <p>Use {@link #buildInputId} to build the ID.
520          *
521          * <p>This is a required field.
522          *
523          * <p>Type: TEXT
524          */
525         public static final String COLUMN_INPUT_ID = "input_id";
526 
527         /**
528          * The predefined type of this TV channel.
529          *
530          * <p>This is primarily used to indicate which broadcast standard (e.g. ATSC, DVB or ISDB)
531          * the current channel conforms to. The value should match to one of the followings:
532          * {@link #TYPE_OTHER}, {@link #TYPE_DVB_T}, {@link #TYPE_DVB_T2}, {@link #TYPE_DVB_S},
533          * {@link #TYPE_DVB_S2}, {@link #TYPE_DVB_C}, {@link #TYPE_DVB_C2}, {@link #TYPE_DVB_H},
534          * {@link #TYPE_DVB_SH}, {@link #TYPE_ATSC_T}, {@link #TYPE_ATSC_C},
535          * {@link #TYPE_ATSC_M_H}, {@link #TYPE_ISDB_T}, {@link #TYPE_ISDB_TB},
536          * {@link #TYPE_ISDB_S}, {@link #TYPE_ISDB_C}, {@link #TYPE_1SEG}, {@link #TYPE_DTMB},
537          * {@link #TYPE_CMMB}, {@link #TYPE_T_DMB}, {@link #TYPE_S_DMB}
538          *
539          * <p>This is a required field.
540          *
541          * <p>Type: TEXT
542          */
543         public static final String COLUMN_TYPE = "type";
544 
545         /**
546          * The predefined service type of this TV channel.
547          *
548          * <p>This is primarily used to indicate whether the current channel is a regular TV channel
549          * or a radio-like channel. Use the same coding for {@code service_type} in the underlying
550          * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB
551          * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER},
552          * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO}
553          *
554          * <p>This is a required field.
555          *
556          * <p>Type: TEXT
557          */
558         public static final String COLUMN_SERVICE_TYPE = "service_type";
559 
560         /**
561          * The original network ID of this TV channel.
562          *
563          * <p>This is used to identify the originating delivery system, if applicable. Use the same
564          * coding for {@code original_network_id} in the underlying broadcast standard if it is
565          * defined there (e.g. ETSI EN 300 468/TR 101 211 and ARIB STD-B10). If channels cannot be
566          * globally identified by 2-tuple {{@link #COLUMN_TRANSPORT_STREAM_ID},
567          * {@link #COLUMN_SERVICE_ID}}, one must carefully assign a value to this field to form a
568          * unique 3-tuple identification {{@code COLUMN_ORIGINAL_NETWORK_ID},
569          * {@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}} for its channels.
570          *
571          * <p>This is a required field if the channel cannot be uniquely identified by a 2-tuple
572          * {{@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}}.
573          *
574          * <p>Type: INTEGER
575          */
576         public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
577 
578         /**
579          * The transport stream ID of this channel.
580          *
581          * <p>This is used to identify the Transport Stream that contains the current channel from
582          * any other multiplex within a network, if applicable. Use the same coding for
583          * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via
584          * the MPEG Transport Stream as is the case for many digital broadcast standards.
585          *
586          * <p>This is a required field if the current channel is transmitted via the MPEG Transport
587          * Stream.
588          *
589          * <p>Type: INTEGER
590          */
591         public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
592 
593         /**
594          * The service ID of this channel.
595          *
596          * <p>This is used to identify the current service (roughly equivalent to channel) from any
597          * other service within the Transport Stream, if applicable. Use the same coding for
598          * {@code service_id} in the underlying broadcast standard if it is defined there (e.g. ETSI
599          * EN 300 468 and ARIB STD-B10) or {@code program_number} (which usually has the same value
600          * as {@code service_id}) in ISO/IEC 13818-1 if the channel is transmitted via the MPEG
601          * Transport Stream.
602          *
603          * <p>This is a required field if the current channel is transmitted via the MPEG Transport
604          * Stream.
605          *
606          * <p>Type: INTEGER
607          */
608         public static final String COLUMN_SERVICE_ID = "service_id";
609 
610         /**
611          * The channel number that is displayed to the user.
612          *
613          * <p>The format can vary depending on broadcast standard and product specification.
614          *
615          * <p>Type: TEXT
616          */
617         public static final String COLUMN_DISPLAY_NUMBER = "display_number";
618 
619         /**
620          * The channel name that is displayed to the user.
621          *
622          * <p>A call sign is a good candidate to use for this purpose but any name that helps the
623          * user recognize the current channel will be enough. Can also be empty depending on
624          * broadcast standard.
625          *
626          * <p> Type: TEXT
627          */
628         public static final String COLUMN_DISPLAY_NAME = "display_name";
629 
630         /**
631          * The network affiliation for this TV channel.
632          *
633          * <p>This is used to identify a channel that is commonly called by its network affiliation
634          * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the
635          * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable.
636          *
637          * <p>Type: TEXT
638          */
639         public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
640 
641         /**
642          * The description of this TV channel.
643          *
644          * <p>Can be empty initially.
645          *
646          * <p>Type: TEXT
647          */
648         public static final String COLUMN_DESCRIPTION = "description";
649 
650         /**
651          * The typical video format for programs from this TV channel.
652          *
653          * <p>This is primarily used to filter out channels based on video format by applications.
654          * The value should match one of the followings: {@link #VIDEO_FORMAT_240P},
655          * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P},
656          * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P},
657          * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P},
658          * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a
659          * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and
660          * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution.
661          *
662          * <p>Type: TEXT
663          *
664          * @see #getVideoResolution
665          */
666         public static final String COLUMN_VIDEO_FORMAT = "video_format";
667 
668         /**
669          * The flag indicating whether this TV channel is browsable or not.
670          *
671          * <p>A value of 1 indicates the channel is included in the channel list that applications
672          * use to browse channels, a value of 0 indicates the channel is not included in the list.
673          * If not specified, this value is set to 0 (not browsable) by default.
674          *
675          * <p>Type: INTEGER (boolean)
676          * @hide
677          */
678         @SystemApi
679         public static final String COLUMN_BROWSABLE = "browsable";
680 
681         /**
682          * The flag indicating whether this TV channel is searchable or not.
683          *
684          * <p>The columns of searchable channels can be read by other applications that have proper
685          * permission. Care must be taken not to open sensitive data.
686          *
687          * <p>A value of 1 indicates that the channel is searchable and its columns can be read by
688          * other applications, a value of 0 indicates that the channel is hidden and its columns can
689          * be read only by the package that owns the channel and the system. If not specified, this
690          * value is set to 1 (searchable) by default.
691          *
692          * <p>Type: INTEGER (boolean)
693          */
694         public static final String COLUMN_SEARCHABLE = "searchable";
695 
696         /**
697          * The flag indicating whether this TV channel is locked or not.
698          *
699          * <p>This is primarily used for alternative parental control to prevent unauthorized users
700          * from watching the current channel regardless of the content rating. A value of 1
701          * indicates the channel is locked and the user is required to enter passcode to unlock it
702          * in order to watch the current program from the channel, a value of 0 indicates the
703          * channel is not locked thus the user is not prompted to enter passcode If not specified,
704          * this value is set to 0 (not locked) by default.
705          *
706          * <p>Type: INTEGER (boolean)
707          * @hide
708          */
709         @SystemApi
710         public static final String COLUMN_LOCKED = "locked";
711 
712         /**
713          * The URI for the app badge icon of the app link template for this channel.
714          *
715          * <p>This small icon is overlaid at the bottom of the poster art specified by
716          * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of
717          * the following formats:
718          *
719          * <ul>
720          * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
721          * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
722          * </li>
723          * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
724          * </ul>
725          *
726          * <p>The app-linking allows channel input sources to provide activity links from their live
727          * channel programming to another activity. This enables content providers to increase user
728          * engagement by offering the viewer other content or actions.
729          *
730          * <p>Type: TEXT
731          * @see #COLUMN_APP_LINK_COLOR
732          * @see #COLUMN_APP_LINK_INTENT_URI
733          * @see #COLUMN_APP_LINK_POSTER_ART_URI
734          * @see #COLUMN_APP_LINK_TEXT
735          */
736         public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
737 
738         /**
739          * The URI for the poster art used as the background of the app link template for this
740          * channel.
741          *
742          * <p>The data in the column must be a URL, or a URI in one of the following formats:
743          *
744          * <ul>
745          * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
746          * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
747          * </li>
748          * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
749          * </ul>
750          *
751          * <p>The app-linking allows channel input sources to provide activity links from their live
752          * channel programming to another activity. This enables content providers to increase user
753          * engagement by offering the viewer other content or actions.
754          *
755          * <p>Type: TEXT
756          * @see #COLUMN_APP_LINK_COLOR
757          * @see #COLUMN_APP_LINK_ICON_URI
758          * @see #COLUMN_APP_LINK_INTENT_URI
759          * @see #COLUMN_APP_LINK_TEXT
760          */
761         public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
762 
763         /**
764          * The link text of the app link template for this channel.
765          *
766          * <p>This provides a short description of the action that happens when the corresponding
767          * app link is clicked.
768          *
769          * <p>The app-linking allows channel input sources to provide activity links from their live
770          * channel programming to another activity. This enables content providers to increase user
771          * engagement by offering the viewer other content or actions.
772          *
773          * <p>Type: TEXT
774          * @see #COLUMN_APP_LINK_COLOR
775          * @see #COLUMN_APP_LINK_ICON_URI
776          * @see #COLUMN_APP_LINK_INTENT_URI
777          * @see #COLUMN_APP_LINK_POSTER_ART_URI
778          */
779         public static final String COLUMN_APP_LINK_TEXT = "app_link_text";
780 
781         /**
782          * The accent color of the app link template for this channel. This is primarily used for
783          * the background color of the text box in the template.
784          *
785          * <p>The app-linking allows channel input sources to provide activity links from their live
786          * channel programming to another activity. This enables content providers to increase user
787          * engagement by offering the viewer other content or actions.
788          *
789          * <p>Type: INTEGER (color value)
790          * @see #COLUMN_APP_LINK_ICON_URI
791          * @see #COLUMN_APP_LINK_INTENT_URI
792          * @see #COLUMN_APP_LINK_POSTER_ART_URI
793          * @see #COLUMN_APP_LINK_TEXT
794          */
795         public static final String COLUMN_APP_LINK_COLOR = "app_link_color";
796 
797         /**
798          * The intent URI of the app link for this channel.
799          *
800          * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
801          * and converted back to the original intent with {@link Intent#parseUri}. The intent is
802          * launched when the user clicks the corresponding app link for the current channel.
803          *
804          * <p>The app-linking allows channel input sources to provide activity links from their live
805          * channel programming to another activity. This enables content providers to increase user
806          * engagement by offering the viewer other content or actions.
807          *
808          * <p>Type: TEXT
809          * @see #COLUMN_APP_LINK_COLOR
810          * @see #COLUMN_APP_LINK_ICON_URI
811          * @see #COLUMN_APP_LINK_POSTER_ART_URI
812          * @see #COLUMN_APP_LINK_TEXT
813          */
814         public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
815 
816         /**
817          * Internal data used by individual TV input services.
818          *
819          * <p>This is internal to the provider that inserted it, and should not be decoded by other
820          * apps.
821          *
822          * <p>Type: BLOB
823          */
824         public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
825 
826         /**
827          * Internal integer flag used by individual TV input services.
828          *
829          * <p>This is internal to the provider that inserted it, and should not be decoded by other
830          * apps.
831          *
832          * <p>Type: INTEGER
833          */
834         public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
835 
836         /**
837          * Internal integer flag used by individual TV input services.
838          *
839          * <p>This is internal to the provider that inserted it, and should not be decoded by other
840          * apps.
841          *
842          * <p>Type: INTEGER
843          */
844         public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
845 
846         /**
847          * Internal integer flag used by individual TV input services.
848          *
849          * <p>This is internal to the provider that inserted it, and should not be decoded by other
850          * apps.
851          *
852          * <p>Type: INTEGER
853          */
854         public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
855 
856         /**
857          * Internal integer flag used by individual TV input services.
858          *
859          * <p>This is internal to the provider that inserted it, and should not be decoded by other
860          * apps.
861          *
862          * <p>Type: INTEGER
863          */
864         public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
865 
866         /**
867          * The version number of this row entry used by TV input services.
868          *
869          * <p>This is best used by sync adapters to identify the rows to update. The number can be
870          * defined by individual TV input services. One may assign the same value as
871          * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are
872          * coming from a TV broadcast.
873          *
874          * <p>Type: INTEGER
875          */
876         public static final String COLUMN_VERSION_NUMBER = "version_number";
877 
Channels()878         private Channels() {}
879 
880         /**
881          * A sub-directory of a single TV channel that represents its primary logo.
882          *
883          * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
884          * channel URI.  The resulting URI represents an image file, and should be interacted
885          * using ContentResolver.openAssetFileDescriptor.
886          *
887          * <p>Note that this sub-directory also supports opening the logo as an asset file in write
888          * mode.  Callers can create or replace the primary logo associated with this channel by
889          * opening the asset file and writing the full-size photo contents into it. (Make sure there
890          * is no padding around the logo image.) When the file is closed, the image will be parsed,
891          * sized down if necessary, and stored.
892          *
893          * <p>Usage example:
894          * <pre>
895          * public void writeChannelLogo(long channelId, byte[] logo) {
896          *     Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId);
897          *     try {
898          *         AssetFileDescriptor fd =
899          *             getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw");
900          *         OutputStream os = fd.createOutputStream();
901          *         os.write(logo);
902          *         os.close();
903          *         fd.close();
904          *     } catch (IOException e) {
905          *         // Handle error cases.
906          *     }
907          * }
908          * </pre>
909          */
910         public static final class Logo {
911 
912             /**
913              * The directory twig for this sub-table.
914              */
915             public static final String CONTENT_DIRECTORY = "logo";
916 
Logo()917             private Logo() {}
918         }
919     }
920 
921     /**
922      * Column definitions for the TV programs table.
923      *
924      * <p>By default, the query results will be sorted by
925      * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order.
926      */
927     public static final class Programs implements BaseTvColumns {
928 
929         /** The content:// style URI for this table. */
930         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
931                 + PATH_PROGRAM);
932 
933         /** The MIME type of a directory of TV programs. */
934         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program";
935 
936         /** The MIME type of a single TV program. */
937         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
938 
939         /**
940          * The ID of the TV channel that provides this TV program.
941          *
942          * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
943          *
944          * <p>Type: INTEGER (long)
945          */
946         public static final String COLUMN_CHANNEL_ID = "channel_id";
947 
948         /**
949          * The title of this TV program.
950          *
951          * <p>If this program is an episodic TV show, it is recommended that the title is the series
952          * title and its related fields ({@link #COLUMN_SEASON_NUMBER},
953          * {@link #COLUMN_EPISODE_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in.
954          *
955          * <p>Type: TEXT
956          */
957         public static final String COLUMN_TITLE = "title";
958 
959         /**
960          * The season number of this TV program for episodic TV shows.
961          *
962          * <p>Can be empty.
963          *
964          * <p>Type: INTEGER
965          */
966         public static final String COLUMN_SEASON_NUMBER = "season_number";
967 
968         /**
969          * The episode number of this TV program for episodic TV shows.
970          *
971          * <p>Can be empty.
972          *
973          * <p>Type: INTEGER
974          */
975         public static final String COLUMN_EPISODE_NUMBER = "episode_number";
976 
977         /**
978          * The episode title of this TV program for episodic TV shows.
979          *
980          * <p>Can be empty.
981          *
982          * <p>Type: TEXT
983          */
984         public static final String COLUMN_EPISODE_TITLE = "episode_title";
985 
986         /**
987          * The start time of this TV program, in milliseconds since the epoch.
988          *
989          * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the
990          * previous program in the same channel.
991          *
992          * <p>Type: INTEGER (long)
993          */
994         public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
995 
996         /**
997          * The end time of this TV program, in milliseconds since the epoch.
998          *
999          * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the
1000          * next program in the same channel.
1001          *
1002          * <p>Type: INTEGER (long)
1003          */
1004         public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
1005 
1006         /**
1007          * The comma-separated genre string of this TV program.
1008          *
1009          * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
1010          * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
1011          * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty.
1012          *
1013          * <p>Type: TEXT
1014          */
1015         public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre";
1016 
1017         /**
1018          * The comma-separated canonical genre string of this TV program.
1019          *
1020          * <p>Canonical genres are defined in {@link Genres}. Use
1021          * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column.
1022          * Use {@link Genres#decode Genres.decode()} to get the canonical genre strings from the
1023          * text stored in this column.
1024          *
1025          * <p>Type: TEXT
1026          * @see Genres
1027          */
1028         public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";
1029 
1030         /**
1031          * The short description of this TV program that is displayed to the user by default.
1032          *
1033          * <p>It is recommended to limit the length of the descriptions to 256 characters.
1034          *
1035          * <p>Type: TEXT
1036          */
1037         public static final String COLUMN_SHORT_DESCRIPTION = "short_description";
1038 
1039         /**
1040          * The detailed, lengthy description of this TV program that is displayed only when the user
1041          * wants to see more information.
1042          *
1043          * <p>TV input services should leave this field empty if they have no additional details
1044          * beyond {@link #COLUMN_SHORT_DESCRIPTION}.
1045          *
1046          * <p>Type: TEXT
1047          */
1048         public static final String COLUMN_LONG_DESCRIPTION = "long_description";
1049 
1050         /**
1051          * The width of the video for this TV program, in the unit of pixels.
1052          *
1053          * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video
1054          * resolution of the current TV program. Can be empty if it is not known initially or the
1055          * program does not convey any video such as the programs from type
1056          * {@link Channels#SERVICE_TYPE_AUDIO} channels.
1057          *
1058          * <p>Type: INTEGER
1059          */
1060         public static final String COLUMN_VIDEO_WIDTH = "video_width";
1061 
1062         /**
1063          * The height of the video for this TV program, in the unit of pixels.
1064          *
1065          * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video
1066          * resolution of the current TV program. Can be empty if it is not known initially or the
1067          * program does not convey any video such as the programs from type
1068          * {@link Channels#SERVICE_TYPE_AUDIO} channels.
1069          *
1070          * <p>Type: INTEGER
1071          */
1072         public static final String COLUMN_VIDEO_HEIGHT = "video_height";
1073 
1074         /**
1075          * The comma-separated audio languages of this TV program.
1076          *
1077          * <p>This is used to describe available audio languages included in the program. Use either
1078          * ISO 639-1 or 639-2/T codes.
1079          *
1080          * <p>Type: TEXT
1081          */
1082         public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
1083 
1084         /**
1085          * The comma-separated content ratings of this TV program.
1086          *
1087          * <p>This is used to describe the content rating(s) of this program. Each comma-separated
1088          * content rating sub-string should be generated by calling
1089          * {@link TvContentRating#flattenToString}. Note that in most cases the program content is
1090          * rated by a single rating system, thus resulting in a corresponding single sub-string that
1091          * does not require comma separation and multiple sub-strings appear only when the program
1092          * content is rated by two or more content rating systems. If any of those ratings is
1093          * specified as "blocked rating" in the user's parental control settings, the TV input
1094          * service should block the current content and wait for the signal that it is okay to
1095          * unblock.
1096          *
1097          * <p>Type: TEXT
1098          */
1099         public static final String COLUMN_CONTENT_RATING = "content_rating";
1100 
1101         /**
1102          * The URI for the poster art of this TV program.
1103          *
1104          * <p>The data in the column must be a URL, or a URI in one of the following formats:
1105          *
1106          * <ul>
1107          * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
1108          * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
1109          * </li>
1110          * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
1111          * </ul>
1112          *
1113          * <p>Can be empty.
1114          *
1115          * <p>Type: TEXT
1116          */
1117         public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
1118 
1119         /**
1120          * The URI for the thumbnail of this TV program.
1121          *
1122          * <p>The system can generate a thumbnail from the poster art if this column is not
1123          * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
1124          * just a scaled image of the poster art.
1125          *
1126          * <p>The data in the column must be a URL, or a URI in one of the following formats:
1127          *
1128          * <ul>
1129          * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
1130          * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
1131          * </li>
1132          * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
1133          * </ul>
1134          *
1135          * <p>Can be empty.
1136          *
1137          * <p>Type: TEXT
1138          */
1139         public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
1140 
1141         /**
1142          * The flag indicating whether this TV program is searchable or not.
1143          *
1144          * <p>The columns of searchable programs can be read by other applications that have proper
1145          * permission. Care must be taken not to open sensitive data.
1146          *
1147          * <p>A value of 1 indicates that the program is searchable and its columns can be read by
1148          * other applications, a value of 0 indicates that the program is hidden and its columns can
1149          * be read only by the package that owns the program and the system. If not specified, this
1150          * value is set to 1 (searchable) by default.
1151          *
1152          * <p>Type: INTEGER (boolean)
1153          */
1154         public static final String COLUMN_SEARCHABLE = "searchable";
1155 
1156         /**
1157          * Internal data used by individual TV input services.
1158          *
1159          * <p>This is internal to the provider that inserted it, and should not be decoded by other
1160          * apps.
1161          *
1162          * <p>Type: BLOB
1163          */
1164         public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
1165 
1166         /**
1167          * Internal integer flag used by individual TV input services.
1168          *
1169          * <p>This is internal to the provider that inserted it, and should not be decoded by other
1170          * apps.
1171          *
1172          * <p>Type: INTEGER
1173          */
1174         public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
1175 
1176         /**
1177          * Internal integer flag used by individual TV input services.
1178          *
1179          * <p>This is internal to the provider that inserted it, and should not be decoded by other
1180          * apps.
1181          *
1182          * <p>Type: INTEGER
1183          */
1184         public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
1185 
1186         /**
1187          * Internal integer flag used by individual TV input services.
1188          *
1189          * <p>This is internal to the provider that inserted it, and should not be decoded by other
1190          * apps.
1191          *
1192          * <p>Type: INTEGER
1193          */
1194         public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
1195 
1196         /**
1197          * Internal integer flag used by individual TV input services.
1198          *
1199          * <p>This is internal to the provider that inserted it, and should not be decoded by other
1200          * apps.
1201          *
1202          * <p>Type: INTEGER
1203          */
1204         public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
1205 
1206         /**
1207          * The version number of this row entry used by TV input services.
1208          *
1209          * <p>This is best used by sync adapters to identify the rows to update. The number can be
1210          * defined by individual TV input services. One may assign the same value as
1211          * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
1212          * broadcast.
1213          *
1214          * <p>Type: INTEGER
1215          */
1216         public static final String COLUMN_VERSION_NUMBER = "version_number";
1217 
Programs()1218         private Programs() {}
1219 
1220         /** Canonical genres for TV programs. */
1221         public static final class Genres {
1222             /** The genre for Family/Kids. */
1223             public static final String FAMILY_KIDS = "FAMILY_KIDS";
1224 
1225             /** The genre for Sports. */
1226             public static final String SPORTS = "SPORTS";
1227 
1228             /** The genre for Shopping. */
1229             public static final String SHOPPING = "SHOPPING";
1230 
1231             /** The genre for Movies. */
1232             public static final String MOVIES = "MOVIES";
1233 
1234             /** The genre for Comedy. */
1235             public static final String COMEDY = "COMEDY";
1236 
1237             /** The genre for Travel. */
1238             public static final String TRAVEL = "TRAVEL";
1239 
1240             /** The genre for Drama. */
1241             public static final String DRAMA = "DRAMA";
1242 
1243             /** The genre for Education. */
1244             public static final String EDUCATION = "EDUCATION";
1245 
1246             /** The genre for Animal/Wildlife. */
1247             public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
1248 
1249             /** The genre for News. */
1250             public static final String NEWS = "NEWS";
1251 
1252             /** The genre for Gaming. */
1253             public static final String GAMING = "GAMING";
1254 
1255             /** The genre for Arts. */
1256             public static final String ARTS = "ARTS";
1257 
1258             /** The genre for Entertainment. */
1259             public static final String ENTERTAINMENT = "ENTERTAINMENT";
1260 
1261             /** The genre for Life Style. */
1262             public static final String LIFE_STYLE = "LIFE_STYLE";
1263 
1264             /** The genre for Music. */
1265             public static final String MUSIC = "MUSIC";
1266 
1267             /** The genre for Premier. */
1268             public static final String PREMIER = "PREMIER";
1269 
1270             /** The genre for Tech/Science. */
1271             public static final String TECH_SCIENCE = "TECH_SCIENCE";
1272 
1273             private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>();
1274             static {
1275                 CANONICAL_GENRES.add(FAMILY_KIDS);
1276                 CANONICAL_GENRES.add(SPORTS);
1277                 CANONICAL_GENRES.add(SHOPPING);
1278                 CANONICAL_GENRES.add(MOVIES);
1279                 CANONICAL_GENRES.add(COMEDY);
1280                 CANONICAL_GENRES.add(TRAVEL);
1281                 CANONICAL_GENRES.add(DRAMA);
1282                 CANONICAL_GENRES.add(EDUCATION);
1283                 CANONICAL_GENRES.add(ANIMAL_WILDLIFE);
1284                 CANONICAL_GENRES.add(NEWS);
1285                 CANONICAL_GENRES.add(GAMING);
1286                 CANONICAL_GENRES.add(ARTS);
1287                 CANONICAL_GENRES.add(ENTERTAINMENT);
1288                 CANONICAL_GENRES.add(LIFE_STYLE);
1289                 CANONICAL_GENRES.add(MUSIC);
1290                 CANONICAL_GENRES.add(PREMIER);
1291                 CANONICAL_GENRES.add(TECH_SCIENCE);
1292             }
1293 
Genres()1294             private Genres() {}
1295 
1296             /**
1297              * Encodes canonical genre strings to a text that can be put into the database.
1298              *
1299              * @param genres Canonical genre strings. Use the strings defined in this class.
1300              * @return an encoded genre string that can be inserted into the
1301              *         {@link #COLUMN_CANONICAL_GENRE} column.
1302              */
encode(String... genres)1303             public static String encode(String... genres) {
1304                 StringBuilder sb = new StringBuilder();
1305                 String separator = "";
1306                 for (String genre : genres) {
1307                     sb.append(separator).append(genre);
1308                     separator = ",";
1309                 }
1310                 return sb.toString();
1311             }
1312 
1313             /**
1314              * Decodes the canonical genre strings from the text stored in the database.
1315              *
1316              * @param genres The encoded genre string retrieved from the
1317              *            {@link #COLUMN_CANONICAL_GENRE} column.
1318              * @return canonical genre strings.
1319              */
decode(String genres)1320             public static String[] decode(String genres) {
1321                 return genres.split("\\s*,\\s*");
1322             }
1323 
1324             /**
1325              * Check whether a given genre is canonical or not.
1326              *
1327              * @param genre The name of genre to be checked.
1328              * @return {@code true} if the genre is canonical, otherwise {@code false}.
1329              * @hide
1330              */
1331             @SystemApi
isCanonical(String genre)1332             public static boolean isCanonical(String genre) {
1333                 return CANONICAL_GENRES.contains(genre);
1334             }
1335         }
1336     }
1337 
1338     /**
1339      * Column definitions for the TV programs that the user watched. Applications do not have access
1340      * to this table.
1341      *
1342      * <p>By default, the query results will be sorted by
1343      * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order.
1344      * @hide
1345      */
1346     @SystemApi
1347     public static final class WatchedPrograms implements BaseTvColumns {
1348 
1349         /** The content:// style URI for this table. */
1350         public static final Uri CONTENT_URI =
1351                 Uri.parse("content://" + AUTHORITY + "/watched_program");
1352 
1353         /** The MIME type of a directory of watched programs. */
1354         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program";
1355 
1356         /** The MIME type of a single item in this table. */
1357         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program";
1358 
1359         /**
1360          * The UTC time that the user started watching this TV program, in milliseconds since the
1361          * epoch.
1362          *
1363          * <p>Type: INTEGER (long)
1364          */
1365         public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS =
1366                 "watch_start_time_utc_millis";
1367 
1368         /**
1369          * The UTC time that the user stopped watching this TV program, in milliseconds since the
1370          * epoch.
1371          *
1372          * <p>Type: INTEGER (long)
1373          */
1374         public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis";
1375 
1376         /**
1377          * The ID of the TV channel that provides this TV program.
1378          *
1379          * <p>Type: INTEGER (long)
1380          */
1381         public static final String COLUMN_CHANNEL_ID = "channel_id";
1382 
1383         /**
1384          * The title of this TV program.
1385          *
1386          * <p>Type: TEXT
1387          */
1388         public static final String COLUMN_TITLE = "title";
1389 
1390         /**
1391          * The start time of this TV program, in milliseconds since the epoch.
1392          *
1393          * <p>Type: INTEGER (long)
1394          */
1395         public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
1396 
1397         /**
1398          * The end time of this TV program, in milliseconds since the epoch.
1399          *
1400          * <p>Type: INTEGER (long)
1401          */
1402         public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
1403 
1404         /**
1405          * The description of this TV program.
1406          *
1407          * <p>Type: TEXT
1408          */
1409         public static final String COLUMN_DESCRIPTION = "description";
1410 
1411         /**
1412          * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle)
1413          * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that
1414          * provides this TV program. (Used internally.)
1415          *
1416          * <p>This column contains an encoded string that represents comma-separated key-value pairs of
1417          * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape
1418          * character for '%', '=', and ','.
1419          *
1420          * <p>Type: TEXT
1421          */
1422         public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params";
1423 
1424         /**
1425          * The session token of this TV program. (Used internally.)
1426          *
1427          * <p>This contains a String representation of {@link IBinder} for
1428          * {@link TvInputService.Session} that provides the current TV program. It is used
1429          * internally to distinguish watched programs entries from different TV input sessions.
1430          *
1431          * <p>Type: TEXT
1432          */
1433         public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token";
1434 
WatchedPrograms()1435         private WatchedPrograms() {}
1436     }
1437 }
1438