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