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.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.content.ComponentName; 23 import android.content.ContentResolver; 24 import android.content.ContentUris; 25 import android.content.Intent; 26 import android.net.Uri; 27 import android.os.IBinder; 28 import android.provider.BaseColumns; 29 import android.text.TextUtils; 30 import android.util.ArraySet; 31 32 import java.util.ArrayList; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Map; 36 37 /** 38 * The contract between the TV provider and applications. Contains definitions for the supported 39 * URIs and columns. 40 * <h3>Overview</h3> 41 * 42 * <p>TvContract defines a basic database of TV content metadata such as channel and program 43 * information. The information is stored in {@link Channels} and {@link Programs} tables. 44 * 45 * <ul> 46 * <li>A row in the {@link Channels} table represents information about a TV channel. The data 47 * format can vary greatly from standard to standard or according to service provider, thus 48 * the columns here are mostly comprised of basic entities that are usually seen to users 49 * regardless of standard such as channel number and name.</li> 50 * <li>A row in the {@link Programs} table represents a set of data describing a TV program such 51 * as program title and start time.</li> 52 * </ul> 53 */ 54 public final class TvContract { 55 /** The authority for the TV provider. */ 56 public static final String AUTHORITY = "android.media.tv"; 57 58 /** 59 * Permission to read TV listings. This is required to read all the TV channel and program 60 * information available on the system. 61 * @hide 62 */ 63 public static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS"; 64 65 private static final String PATH_CHANNEL = "channel"; 66 private static final String PATH_PROGRAM = "program"; 67 private static final String PATH_RECORDED_PROGRAM = "recorded_program"; 68 private static final String PATH_PASSTHROUGH = "passthrough"; 69 70 /** 71 * An optional query, update or delete URI parameter that allows the caller to specify TV input 72 * ID to filter channels. 73 * @hide 74 */ 75 public static final String PARAM_INPUT = "input"; 76 77 /** 78 * An optional query, update or delete URI parameter that allows the caller to specify channel 79 * ID to filter programs. 80 * @hide 81 */ 82 public static final String PARAM_CHANNEL = "channel"; 83 84 /** 85 * An optional query, update or delete URI parameter that allows the caller to specify start 86 * time (in milliseconds since the epoch) to filter programs. 87 * @hide 88 */ 89 public static final String PARAM_START_TIME = "start_time"; 90 91 /** 92 * An optional query, update or delete URI parameter that allows the caller to specify end time 93 * (in milliseconds since the epoch) to filter programs. 94 * @hide 95 */ 96 public static final String PARAM_END_TIME = "end_time"; 97 98 /** 99 * A query, update or delete URI parameter that allows the caller to operate on all or 100 * browsable-only channels. If set to "true", the rows that contain non-browsable channels are 101 * not affected. 102 * @hide 103 */ 104 public static final String PARAM_BROWSABLE_ONLY = "browsable_only"; 105 106 /** 107 * A optional query, update or delete URI parameter that allows the caller to specify canonical 108 * genre to filter programs. 109 * @hide 110 */ 111 public static final String PARAM_CANONICAL_GENRE = "canonical_genre"; 112 113 /** 114 * Builds an ID that uniquely identifies a TV input service. 115 * 116 * @param name The {@link ComponentName} of the TV input service to build ID for. 117 * @return the ID for the given TV input service. 118 */ buildInputId(ComponentName name)119 public static final String buildInputId(ComponentName name) { 120 return name.flattenToShortString(); 121 } 122 123 /** 124 * Builds a URI that points to a specific channel. 125 * 126 * @param channelId The ID of the channel to point to. 127 */ buildChannelUri(long channelId)128 public static final Uri buildChannelUri(long channelId) { 129 return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId); 130 } 131 132 /** 133 * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI) 134 * 135 * @param inputId The ID of the pass-through input to build a channels URI for. 136 * @see TvInputInfo#isPassthroughInput() 137 */ buildChannelUriForPassthroughInput(String inputId)138 public static final Uri buildChannelUriForPassthroughInput(String inputId) { 139 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY) 140 .appendPath(PATH_PASSTHROUGH).appendPath(inputId).build(); 141 } 142 143 /** 144 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 145 * 146 * @param channelId The ID of the channel whose logo is pointed to. 147 */ buildChannelLogoUri(long channelId)148 public static final Uri buildChannelLogoUri(long channelId) { 149 return buildChannelLogoUri(buildChannelUri(channelId)); 150 } 151 152 /** 153 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 154 * 155 * @param channelUri The URI of the channel whose logo is pointed to. 156 */ buildChannelLogoUri(Uri channelUri)157 public static final Uri buildChannelLogoUri(Uri channelUri) { 158 if (!isChannelUriForTunerInput(channelUri)) { 159 throw new IllegalArgumentException("Not a channel: " + channelUri); 160 } 161 return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY); 162 } 163 164 /** 165 * Builds a URI that points to all channels from a given TV input. 166 * 167 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 168 * URI for all the TV inputs. 169 */ buildChannelsUriForInput(@ullable String inputId)170 public static final Uri buildChannelsUriForInput(@Nullable String inputId) { 171 return buildChannelsUriForInput(inputId, false); 172 } 173 174 /** 175 * Builds a URI that points to all or browsable-only channels from a given TV input. 176 * 177 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 178 * URI for all the TV inputs. 179 * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set 180 * to {@code false} the URI points to all channels regardless of whether they are 181 * browsable or not. 182 * @hide 183 */ 184 @SystemApi buildChannelsUriForInput(@ullable String inputId, boolean browsableOnly)185 public static final Uri buildChannelsUriForInput(@Nullable String inputId, 186 boolean browsableOnly) { 187 Uri.Builder builder = Channels.CONTENT_URI.buildUpon(); 188 if (inputId != null) { 189 builder.appendQueryParameter(PARAM_INPUT, inputId); 190 } 191 return builder.appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)) 192 .build(); 193 } 194 195 /** 196 * Builds a URI that points to all or browsable-only channels which have programs with the given 197 * genre from the given TV input. 198 * 199 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 200 * URI for all the TV inputs. 201 * @param genre {@link Programs.Genres} to search. If {@code null}, builds a URI for all genres. 202 * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set 203 * to {@code false} the URI points to all channels regardless of whether they are 204 * browsable or not. 205 * @hide 206 */ 207 @SystemApi buildChannelsUriForInput(@ullable String inputId, @Nullable String genre, boolean browsableOnly)208 public static final Uri buildChannelsUriForInput(@Nullable String inputId, 209 @Nullable String genre, boolean browsableOnly) { 210 if (genre == null) { 211 return buildChannelsUriForInput(inputId, browsableOnly); 212 } 213 if (!Programs.Genres.isCanonical(genre)) { 214 throw new IllegalArgumentException("Not a canonical genre: '" + genre + "'"); 215 } 216 return buildChannelsUriForInput(inputId, browsableOnly).buildUpon() 217 .appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build(); 218 } 219 220 /** 221 * Builds a URI that points to a specific program. 222 * 223 * @param programId The ID of the program to point to. 224 */ buildProgramUri(long programId)225 public static final Uri buildProgramUri(long programId) { 226 return ContentUris.withAppendedId(Programs.CONTENT_URI, programId); 227 } 228 229 /** 230 * Builds a URI that points to all programs on a given channel. 231 * 232 * @param channelId The ID of the channel to return programs for. 233 */ buildProgramsUriForChannel(long channelId)234 public static final Uri buildProgramsUriForChannel(long channelId) { 235 return Programs.CONTENT_URI.buildUpon() 236 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build(); 237 } 238 239 /** 240 * Builds a URI that points to all programs on a given channel. 241 * 242 * @param channelUri The URI of the channel to return programs for. 243 */ buildProgramsUriForChannel(Uri channelUri)244 public static final Uri buildProgramsUriForChannel(Uri channelUri) { 245 if (!isChannelUriForTunerInput(channelUri)) { 246 throw new IllegalArgumentException("Not a channel: " + channelUri); 247 } 248 return buildProgramsUriForChannel(ContentUris.parseId(channelUri)); 249 } 250 251 /** 252 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 253 * given time frame. 254 * 255 * @param channelId The ID of the channel to return programs for. 256 * @param startTime The start time used to filter programs. The returned programs should have 257 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 258 * @param endTime The end time used to filter programs. The returned programs should have 259 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 260 */ buildProgramsUriForChannel(long channelId, long startTime, long endTime)261 public static final Uri buildProgramsUriForChannel(long channelId, long startTime, 262 long endTime) { 263 Uri uri = buildProgramsUriForChannel(channelId); 264 return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime)) 265 .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build(); 266 } 267 268 /** 269 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 270 * given time frame. 271 * 272 * @param channelUri The URI of the channel to return programs for. 273 * @param startTime The start time used to filter programs. The returned programs should have 274 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 275 * @param endTime The end time used to filter programs. The returned programs should have 276 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 277 */ buildProgramsUriForChannel(Uri channelUri, long startTime, long endTime)278 public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime, 279 long endTime) { 280 if (!isChannelUriForTunerInput(channelUri)) { 281 throw new IllegalArgumentException("Not a channel: " + channelUri); 282 } 283 return buildProgramsUriForChannel(ContentUris.parseId(channelUri), startTime, endTime); 284 } 285 286 /** 287 * Builds a URI that points to a specific recorded program. 288 * 289 * @param recordedProgramId The ID of the recorded program to point to. 290 */ buildRecordedProgramUri(long recordedProgramId)291 public static final Uri buildRecordedProgramUri(long recordedProgramId) { 292 return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId); 293 } 294 295 /** 296 * Builds a URI that points to a specific program the user watched. 297 * 298 * @param watchedProgramId The ID of the watched program to point to. 299 * @hide 300 */ buildWatchedProgramUri(long watchedProgramId)301 public static final Uri buildWatchedProgramUri(long watchedProgramId) { 302 return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId); 303 } 304 isTvUri(Uri uri)305 private static boolean isTvUri(Uri uri) { 306 return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) 307 && AUTHORITY.equals(uri.getAuthority()); 308 } 309 isTwoSegmentUriStartingWith(Uri uri, String pathSegment)310 private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) { 311 List<String> pathSegments = uri.getPathSegments(); 312 return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0)); 313 } 314 315 /** 316 * Returns {@code true}, if {@code uri} is a channel URI. 317 */ isChannelUri(Uri uri)318 public static final boolean isChannelUri(Uri uri) { 319 return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri); 320 } 321 322 /** 323 * Returns {@code true}, if {@code uri} is a channel URI for a tuner input. 324 */ isChannelUriForTunerInput(Uri uri)325 public static final boolean isChannelUriForTunerInput(Uri uri) { 326 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL); 327 } 328 329 /** 330 * Returns {@code true}, if {@code uri} is a channel URI for a pass-through input. 331 */ isChannelUriForPassthroughInput(Uri uri)332 public static final boolean isChannelUriForPassthroughInput(Uri uri) { 333 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH); 334 } 335 336 /** 337 * Returns {@code true}, if {@code uri} is a program URI. 338 */ isProgramUri(Uri uri)339 public static final boolean isProgramUri(Uri uri) { 340 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM); 341 } 342 343 TvContract()344 private TvContract() {} 345 346 /** 347 * Common base for the tables of TV channels/programs. 348 */ 349 public interface BaseTvColumns extends BaseColumns { 350 /** 351 * The name of the package that owns the current row. 352 * 353 * <p>The TV provider fills in this column with the name of the package that provides the 354 * initial data of the row. If the package is later uninstalled, the rows it owns are 355 * automatically removed from the tables. 356 * 357 * <p>Type: TEXT 358 */ 359 String COLUMN_PACKAGE_NAME = "package_name"; 360 } 361 362 /** Column definitions for the TV channels table. */ 363 public static final class Channels implements BaseTvColumns { 364 365 /** The content:// style URI for this table. */ 366 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 367 + PATH_CHANNEL); 368 369 /** The MIME type of a directory of TV channels. */ 370 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel"; 371 372 /** The MIME type of a single TV channel. */ 373 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel"; 374 375 /** 376 * A generic channel type. 377 * 378 * Use this if the current channel is streaming-based or its broadcast system type does not 379 * fit under any other types. This is the default channel type. 380 * 381 * @see #COLUMN_TYPE 382 */ 383 public static final String TYPE_OTHER = "TYPE_OTHER"; 384 385 /** 386 * The channel type for NTSC. 387 * 388 * @see #COLUMN_TYPE 389 */ 390 public static final String TYPE_NTSC = "TYPE_NTSC"; 391 392 /** 393 * The channel type for PAL. 394 * 395 * @see #COLUMN_TYPE 396 */ 397 public static final String TYPE_PAL = "TYPE_PAL"; 398 399 /** 400 * The channel type for SECAM. 401 * 402 * @see #COLUMN_TYPE 403 */ 404 public static final String TYPE_SECAM = "TYPE_SECAM"; 405 406 /** 407 * The channel type for DVB-T (terrestrial). 408 * 409 * @see #COLUMN_TYPE 410 */ 411 public static final String TYPE_DVB_T = "TYPE_DVB_T"; 412 413 /** 414 * The channel type for DVB-T2 (terrestrial). 415 * 416 * @see #COLUMN_TYPE 417 */ 418 public static final String TYPE_DVB_T2 = "TYPE_DVB_T2"; 419 420 /** 421 * The channel type for DVB-S (satellite). 422 * 423 * @see #COLUMN_TYPE 424 */ 425 public static final String TYPE_DVB_S = "TYPE_DVB_S"; 426 427 /** 428 * The channel type for DVB-S2 (satellite). 429 * 430 * @see #COLUMN_TYPE 431 */ 432 public static final String TYPE_DVB_S2 = "TYPE_DVB_S2"; 433 434 /** 435 * The channel type for DVB-C (cable). 436 * 437 * @see #COLUMN_TYPE 438 */ 439 public static final String TYPE_DVB_C = "TYPE_DVB_C"; 440 441 /** 442 * The channel type for DVB-C2 (cable). 443 * 444 * @see #COLUMN_TYPE 445 */ 446 public static final String TYPE_DVB_C2 = "TYPE_DVB_C2"; 447 448 /** 449 * The channel type for DVB-H (handheld). 450 * 451 * @see #COLUMN_TYPE 452 */ 453 public static final String TYPE_DVB_H = "TYPE_DVB_H"; 454 455 /** 456 * The channel type for DVB-SH (satellite). 457 * 458 * @see #COLUMN_TYPE 459 */ 460 public static final String TYPE_DVB_SH = "TYPE_DVB_SH"; 461 462 /** 463 * The channel type for ATSC (terrestrial). 464 * 465 * @see #COLUMN_TYPE 466 */ 467 public static final String TYPE_ATSC_T = "TYPE_ATSC_T"; 468 469 /** 470 * The channel type for ATSC (cable). 471 * 472 * @see #COLUMN_TYPE 473 */ 474 public static final String TYPE_ATSC_C = "TYPE_ATSC_C"; 475 476 /** 477 * The channel type for ATSC-M/H (mobile/handheld). 478 * 479 * @see #COLUMN_TYPE 480 */ 481 public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H"; 482 483 /** 484 * The channel type for ISDB-T (terrestrial). 485 * 486 * @see #COLUMN_TYPE 487 */ 488 public static final String TYPE_ISDB_T = "TYPE_ISDB_T"; 489 490 /** 491 * The channel type for ISDB-Tb (Brazil). 492 * 493 * @see #COLUMN_TYPE 494 */ 495 public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB"; 496 497 /** 498 * The channel type for ISDB-S (satellite). 499 * 500 * @see #COLUMN_TYPE 501 */ 502 public static final String TYPE_ISDB_S = "TYPE_ISDB_S"; 503 504 /** 505 * The channel type for ISDB-C (cable). 506 * 507 * @see #COLUMN_TYPE 508 */ 509 public static final String TYPE_ISDB_C = "TYPE_ISDB_C"; 510 511 /** 512 * The channel type for 1seg (handheld). 513 * 514 * @see #COLUMN_TYPE 515 */ 516 public static final String TYPE_1SEG = "TYPE_1SEG"; 517 518 /** 519 * The channel type for DTMB (terrestrial). 520 * 521 * @see #COLUMN_TYPE 522 */ 523 public static final String TYPE_DTMB = "TYPE_DTMB"; 524 525 /** 526 * The channel type for CMMB (handheld). 527 * 528 * @see #COLUMN_TYPE 529 */ 530 public static final String TYPE_CMMB = "TYPE_CMMB"; 531 532 /** 533 * The channel type for T-DMB (terrestrial). 534 * 535 * @see #COLUMN_TYPE 536 */ 537 public static final String TYPE_T_DMB = "TYPE_T_DMB"; 538 539 /** 540 * The channel type for S-DMB (satellite). 541 * 542 * @see #COLUMN_TYPE 543 */ 544 public static final String TYPE_S_DMB = "TYPE_S_DMB"; 545 546 /** A generic service type. */ 547 public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER"; 548 549 /** The service type for regular TV channels that have both audio and video. */ 550 public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO"; 551 552 /** The service type for radio channels that have audio only. */ 553 public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO"; 554 555 /** The video format for 240p. */ 556 public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P"; 557 558 /** The video format for 360p. */ 559 public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P"; 560 561 /** The video format for 480i. */ 562 public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I"; 563 564 /** The video format for 480p. */ 565 public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P"; 566 567 /** The video format for 576i. */ 568 public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I"; 569 570 /** The video format for 576p. */ 571 public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P"; 572 573 /** The video format for 720p. */ 574 public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P"; 575 576 /** The video format for 1080i. */ 577 public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I"; 578 579 /** The video format for 1080p. */ 580 public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P"; 581 582 /** The video format for 2160p. */ 583 public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P"; 584 585 /** The video format for 4320p. */ 586 public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P"; 587 588 /** The video resolution for standard-definition. */ 589 public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD"; 590 591 /** The video resolution for enhanced-definition. */ 592 public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED"; 593 594 /** The video resolution for high-definition. */ 595 public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD"; 596 597 /** The video resolution for full high-definition. */ 598 public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD"; 599 600 /** The video resolution for ultra high-definition. */ 601 public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD"; 602 603 private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>(); 604 605 static { VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD)606 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED)607 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD)608 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED)609 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD)610 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD)611 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD)612 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD)613 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD)614 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD); 615 } 616 617 /** 618 * Returns the video resolution (definition) for a given video format. 619 * 620 * @param videoFormat The video format defined in {@link Channels}. 621 * @return the corresponding video resolution string. {@code null} if the resolution string 622 * is not defined for the given video format. 623 * @see #COLUMN_VIDEO_FORMAT 624 */ 625 @Nullable getVideoResolution(String videoFormat)626 public static final String getVideoResolution(String videoFormat) { 627 return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat); 628 } 629 630 /** 631 * The ID of the TV input service that provides this TV channel. 632 * 633 * <p>Use {@link #buildInputId} to build the ID. 634 * 635 * <p>This is a required field. 636 * 637 * <p>Type: TEXT 638 */ 639 public static final String COLUMN_INPUT_ID = "input_id"; 640 641 /** 642 * The broadcast system type of this TV channel. 643 * 644 * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current 645 * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the 646 * default channel type. The value should match to one of the followings: 647 * {@link #TYPE_1SEG}, 648 * {@link #TYPE_ATSC_C}, 649 * {@link #TYPE_ATSC_M_H}, 650 * {@link #TYPE_ATSC_T}, 651 * {@link #TYPE_CMMB}, 652 * {@link #TYPE_DTMB}, 653 * {@link #TYPE_DVB_C}, 654 * {@link #TYPE_DVB_C2}, 655 * {@link #TYPE_DVB_H}, 656 * {@link #TYPE_DVB_S}, 657 * {@link #TYPE_DVB_S2}, 658 * {@link #TYPE_DVB_SH}, 659 * {@link #TYPE_DVB_T}, 660 * {@link #TYPE_DVB_T2}, 661 * {@link #TYPE_ISDB_C}, 662 * {@link #TYPE_ISDB_S}, 663 * {@link #TYPE_ISDB_T}, 664 * {@link #TYPE_ISDB_TB}, 665 * {@link #TYPE_NTSC}, 666 * {@link #TYPE_OTHER}, 667 * {@link #TYPE_PAL}, 668 * {@link #TYPE_SECAM}, 669 * {@link #TYPE_S_DMB}, and 670 * {@link #TYPE_T_DMB}. 671 * 672 * <p>This is a required field. 673 * 674 * <p>Type: TEXT 675 */ 676 public static final String COLUMN_TYPE = "type"; 677 678 /** 679 * The predefined service type of this TV channel. 680 * 681 * <p>This is primarily used to indicate whether the current channel is a regular TV channel 682 * or a radio-like channel. Use the same coding for {@code service_type} in the underlying 683 * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB 684 * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER}, 685 * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO} 686 * 687 * <p>This is a required field. 688 * 689 * <p>Type: TEXT 690 */ 691 public static final String COLUMN_SERVICE_TYPE = "service_type"; 692 693 /** 694 * The original network ID of this TV channel. 695 * 696 * <p>It is used to identify the originating delivery system, if applicable. Use the same 697 * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10. 698 * 699 * <p>This is a required field only if the underlying broadcast standard defines the same 700 * name field. Otherwise, leave empty. 701 * 702 * <p>Type: INTEGER 703 */ 704 public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; 705 706 /** 707 * The transport stream ID of this channel. 708 * 709 * <p>It is used to identify the Transport Stream that contains the current channel from any 710 * other multiplex within a network, if applicable. Use the same coding for 711 * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via 712 * the MPEG Transport Stream. 713 * 714 * <p>This is a required field only if the current channel is transmitted via the MPEG 715 * Transport Stream. Leave empty otherwise. 716 * 717 * <p>Type: INTEGER 718 */ 719 public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; 720 721 /** 722 * The service ID of this channel. 723 * 724 * <p>It is used to identify the current service, or channel from any other services within 725 * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in 726 * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1. 727 * 728 * <p>This is a required field only if the underlying broadcast standard defines the same 729 * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave 730 * empty otherwise. 731 * 732 * <p>Type: INTEGER 733 */ 734 public static final String COLUMN_SERVICE_ID = "service_id"; 735 736 /** 737 * The channel number that is displayed to the user. 738 * 739 * <p>The format can vary depending on broadcast standard and product specification. 740 * 741 * <p>Type: TEXT 742 */ 743 public static final String COLUMN_DISPLAY_NUMBER = "display_number"; 744 745 /** 746 * The channel name that is displayed to the user. 747 * 748 * <p>A call sign is a good candidate to use for this purpose but any name that helps the 749 * user recognize the current channel will be enough. Can also be empty depending on 750 * broadcast standard. 751 * 752 * <p> Type: TEXT 753 */ 754 public static final String COLUMN_DISPLAY_NAME = "display_name"; 755 756 /** 757 * The network affiliation for this TV channel. 758 * 759 * <p>This is used to identify a channel that is commonly called by its network affiliation 760 * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the 761 * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable. 762 * 763 * <p>Type: TEXT 764 */ 765 public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation"; 766 767 /** 768 * The description of this TV channel. 769 * 770 * <p>Can be empty initially. 771 * 772 * <p>Type: TEXT 773 */ 774 public static final String COLUMN_DESCRIPTION = "description"; 775 776 /** 777 * The typical video format for programs from this TV channel. 778 * 779 * <p>This is primarily used to filter out channels based on video format by applications. 780 * The value should match one of the followings: {@link #VIDEO_FORMAT_240P}, 781 * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P}, 782 * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P}, 783 * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P}, 784 * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a 785 * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and 786 * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution. 787 * 788 * <p>Type: TEXT 789 * 790 * @see #getVideoResolution 791 */ 792 public static final String COLUMN_VIDEO_FORMAT = "video_format"; 793 794 /** 795 * The flag indicating whether this TV channel is browsable or not. 796 * 797 * <p>A value of 1 indicates the channel is included in the channel list that applications 798 * use to browse channels, a value of 0 indicates the channel is not included in the list. 799 * If not specified, this value is set to 0 (not browsable) by default. 800 * 801 * <p>Type: INTEGER (boolean) 802 * @hide 803 */ 804 @SystemApi 805 public static final String COLUMN_BROWSABLE = "browsable"; 806 807 /** 808 * The flag indicating whether this TV channel is searchable or not. 809 * 810 * <p>The columns of searchable channels can be read by other applications that have proper 811 * permission. Care must be taken not to open sensitive data. 812 * 813 * <p>A value of 1 indicates that the channel is searchable and its columns can be read by 814 * other applications, a value of 0 indicates that the channel is hidden and its columns can 815 * be read only by the package that owns the channel and the system. If not specified, this 816 * value is set to 1 (searchable) by default. 817 * 818 * <p>Type: INTEGER (boolean) 819 */ 820 public static final String COLUMN_SEARCHABLE = "searchable"; 821 822 /** 823 * The flag indicating whether this TV channel is locked or not. 824 * 825 * <p>This is primarily used for alternative parental control to prevent unauthorized users 826 * from watching the current channel regardless of the content rating. A value of 1 827 * indicates the channel is locked and the user is required to enter passcode to unlock it 828 * in order to watch the current program from the channel, a value of 0 indicates the 829 * channel is not locked thus the user is not prompted to enter passcode If not specified, 830 * this value is set to 0 (not locked) by default. 831 * 832 * <p>Type: INTEGER (boolean) 833 * @hide 834 */ 835 @SystemApi 836 public static final String COLUMN_LOCKED = "locked"; 837 838 /** 839 * The URI for the app badge icon of the app link template for this channel. 840 * 841 * <p>This small icon is overlaid at the bottom of the poster art specified by 842 * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of 843 * the following formats: 844 * 845 * <ul> 846 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 847 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 848 * </li> 849 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 850 * </ul> 851 * 852 * <p>The app-linking allows channel input sources to provide activity links from their live 853 * channel programming to another activity. This enables content providers to increase user 854 * engagement by offering the viewer other content or actions. 855 * 856 * <p>Type: TEXT 857 * @see #COLUMN_APP_LINK_COLOR 858 * @see #COLUMN_APP_LINK_INTENT_URI 859 * @see #COLUMN_APP_LINK_POSTER_ART_URI 860 * @see #COLUMN_APP_LINK_TEXT 861 */ 862 public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri"; 863 864 /** 865 * The URI for the poster art used as the background of the app link template for this 866 * channel. 867 * 868 * <p>The data in the column must be a URL, or a URI in one of the following formats: 869 * 870 * <ul> 871 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 872 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 873 * </li> 874 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 875 * </ul> 876 * 877 * <p>The app-linking allows channel input sources to provide activity links from their live 878 * channel programming to another activity. This enables content providers to increase user 879 * engagement by offering the viewer other content or actions. 880 * 881 * <p>Type: TEXT 882 * @see #COLUMN_APP_LINK_COLOR 883 * @see #COLUMN_APP_LINK_ICON_URI 884 * @see #COLUMN_APP_LINK_INTENT_URI 885 * @see #COLUMN_APP_LINK_TEXT 886 */ 887 public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri"; 888 889 /** 890 * The link text of the app link template for this channel. 891 * 892 * <p>This provides a short description of the action that happens when the corresponding 893 * app link is clicked. 894 * 895 * <p>The app-linking allows channel input sources to provide activity links from their live 896 * channel programming to another activity. This enables content providers to increase user 897 * engagement by offering the viewer other content or actions. 898 * 899 * <p>Type: TEXT 900 * @see #COLUMN_APP_LINK_COLOR 901 * @see #COLUMN_APP_LINK_ICON_URI 902 * @see #COLUMN_APP_LINK_INTENT_URI 903 * @see #COLUMN_APP_LINK_POSTER_ART_URI 904 */ 905 public static final String COLUMN_APP_LINK_TEXT = "app_link_text"; 906 907 /** 908 * The accent color of the app link template for this channel. This is primarily used for 909 * the background color of the text box in the template. 910 * 911 * <p>The app-linking allows channel input sources to provide activity links from their live 912 * channel programming to another activity. This enables content providers to increase user 913 * engagement by offering the viewer other content or actions. 914 * 915 * <p>Type: INTEGER (color value) 916 * @see #COLUMN_APP_LINK_ICON_URI 917 * @see #COLUMN_APP_LINK_INTENT_URI 918 * @see #COLUMN_APP_LINK_POSTER_ART_URI 919 * @see #COLUMN_APP_LINK_TEXT 920 */ 921 public static final String COLUMN_APP_LINK_COLOR = "app_link_color"; 922 923 /** 924 * The intent URI of the app link for this channel. 925 * 926 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 927 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 928 * launched when the user clicks the corresponding app link for the current channel. 929 * 930 * <p>The app-linking allows channel input sources to provide activity links from their live 931 * channel programming to another activity. This enables content providers to increase user 932 * engagement by offering the viewer other content or actions. 933 * 934 * <p>Type: TEXT 935 * @see #COLUMN_APP_LINK_COLOR 936 * @see #COLUMN_APP_LINK_ICON_URI 937 * @see #COLUMN_APP_LINK_POSTER_ART_URI 938 * @see #COLUMN_APP_LINK_TEXT 939 */ 940 public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri"; 941 942 /** 943 * Internal data used by individual TV input services. 944 * 945 * <p>This is internal to the provider that inserted it, and should not be decoded by other 946 * apps. 947 * 948 * <p>Type: BLOB 949 */ 950 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 951 952 /** 953 * Internal integer flag used by individual TV input services. 954 * 955 * <p>This is internal to the provider that inserted it, and should not be decoded by other 956 * apps. 957 * 958 * <p>Type: INTEGER 959 */ 960 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 961 962 /** 963 * Internal integer flag used by individual TV input services. 964 * 965 * <p>This is internal to the provider that inserted it, and should not be decoded by other 966 * apps. 967 * 968 * <p>Type: INTEGER 969 */ 970 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 971 972 /** 973 * Internal integer flag used by individual TV input services. 974 * 975 * <p>This is internal to the provider that inserted it, and should not be decoded by other 976 * apps. 977 * 978 * <p>Type: INTEGER 979 */ 980 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 981 982 /** 983 * Internal integer flag used by individual TV input services. 984 * 985 * <p>This is internal to the provider that inserted it, and should not be decoded by other 986 * apps. 987 * 988 * <p>Type: INTEGER 989 */ 990 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 991 992 /** 993 * The version number of this row entry used by TV input services. 994 * 995 * <p>This is best used by sync adapters to identify the rows to update. The number can be 996 * defined by individual TV input services. One may assign the same value as 997 * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are 998 * coming from a TV broadcast. 999 * 1000 * <p>Type: INTEGER 1001 */ 1002 public static final String COLUMN_VERSION_NUMBER = "version_number"; 1003 Channels()1004 private Channels() {} 1005 1006 /** 1007 * A sub-directory of a single TV channel that represents its primary logo. 1008 * 1009 * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw 1010 * channel URI. The resulting URI represents an image file, and should be interacted 1011 * using ContentResolver.openAssetFileDescriptor. 1012 * 1013 * <p>Note that this sub-directory also supports opening the logo as an asset file in write 1014 * mode. Callers can create or replace the primary logo associated with this channel by 1015 * opening the asset file and writing the full-size photo contents into it. (Make sure there 1016 * is no padding around the logo image.) When the file is closed, the image will be parsed, 1017 * sized down if necessary, and stored. 1018 * 1019 * <p>Usage example: 1020 * <pre> 1021 * public void writeChannelLogo(long channelId, byte[] logo) { 1022 * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId); 1023 * try { 1024 * AssetFileDescriptor fd = 1025 * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw"); 1026 * OutputStream os = fd.createOutputStream(); 1027 * os.write(logo); 1028 * os.close(); 1029 * fd.close(); 1030 * } catch (IOException e) { 1031 * // Handle error cases. 1032 * } 1033 * } 1034 * </pre> 1035 */ 1036 public static final class Logo { 1037 1038 /** 1039 * The directory twig for this sub-table. 1040 */ 1041 public static final String CONTENT_DIRECTORY = "logo"; 1042 Logo()1043 private Logo() {} 1044 } 1045 } 1046 1047 /** 1048 * Column definitions for the TV programs table. 1049 * 1050 * <p>By default, the query results will be sorted by 1051 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order. 1052 */ 1053 public static final class Programs implements BaseTvColumns { 1054 1055 /** The content:// style URI for this table. */ 1056 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 1057 + PATH_PROGRAM); 1058 1059 /** The MIME type of a directory of TV programs. */ 1060 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program"; 1061 1062 /** The MIME type of a single TV program. */ 1063 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program"; 1064 1065 /** 1066 * The ID of the TV channel that provides this TV program. 1067 * 1068 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 1069 * 1070 * <p>This is a required field. 1071 * 1072 * <p>Type: INTEGER (long) 1073 */ 1074 public static final String COLUMN_CHANNEL_ID = "channel_id"; 1075 1076 /** 1077 * The title of this TV program. 1078 * 1079 * <p>If this program is an episodic TV show, it is recommended that the title is the series 1080 * title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or 1081 * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_SEASON_DISPLAY_NUMBER}, 1082 * {@link #COLUMN_EPISODE_DISPLAY_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in. 1083 * 1084 * <p>Type: TEXT 1085 */ 1086 public static final String COLUMN_TITLE = "title"; 1087 1088 /** 1089 * The season number of this TV program for episodic TV shows. 1090 * 1091 * <p>Can be empty. 1092 * 1093 * <p>Type: INTEGER 1094 * 1095 * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead. 1096 */ 1097 @Deprecated 1098 public static final String COLUMN_SEASON_NUMBER = "season_number"; 1099 1100 /** 1101 * The season display number of this TV program for episodic TV shows. 1102 * 1103 * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value 1104 * does not necessarily be numeric. (e.g. 12B) 1105 * 1106 * <p>Can be empty. 1107 * 1108 * <p>Type: TEXT 1109 */ 1110 public static final String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number"; 1111 1112 /** 1113 * The title of the season for this TV program for episodic TV shows. 1114 * 1115 * <p>This is an optional field supplied only when the season has a special title 1116 * (e.g. The Final Season). If provided, the applications should display it instead of 1117 * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, and should display it without alterations. 1118 * (e.g. for "The Final Season", displayed string should be "The Final Season", not 1119 * "Season The Final Season"). When displaying multiple programs, the order should be based 1120 * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists. 1121 * 1122 * <p>Can be empty. 1123 * 1124 * <p>Type: TEXT 1125 */ 1126 public static final String COLUMN_SEASON_TITLE = "season_title"; 1127 1128 /** 1129 * The episode number of this TV program for episodic TV shows. 1130 * 1131 * <p>Can be empty. 1132 * 1133 * <p>Type: INTEGER 1134 * 1135 * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead. 1136 */ 1137 @Deprecated 1138 public static final String COLUMN_EPISODE_NUMBER = "episode_number"; 1139 1140 /** 1141 * The episode display number of this TV program for episodic TV shows. 1142 * 1143 * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value 1144 * does not necessarily be numeric. (e.g. 12B) 1145 * 1146 * <p>Can be empty. 1147 * 1148 * <p>Type: TEXT 1149 */ 1150 public static final String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number"; 1151 1152 /** 1153 * The episode title of this TV program for episodic TV shows. 1154 * 1155 * <p>Can be empty. 1156 * 1157 * <p>Type: TEXT 1158 */ 1159 public static final String COLUMN_EPISODE_TITLE = "episode_title"; 1160 1161 /** 1162 * The start time of this TV program, in milliseconds since the epoch. 1163 * 1164 * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the 1165 * previous program in the same channel. In practice, start time will usually be the end 1166 * time of the previous program. 1167 * 1168 * <p>Type: INTEGER (long) 1169 */ 1170 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 1171 1172 /** 1173 * The end time of this TV program, in milliseconds since the epoch. 1174 * 1175 * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the 1176 * next program in the same channel. In practice, end time will usually be the start time of 1177 * the next program. 1178 * 1179 * <p>Type: INTEGER (long) 1180 */ 1181 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 1182 1183 /** 1184 * The comma-separated genre string of this TV program. 1185 * 1186 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 1187 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 1188 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 1189 * {@link Genres#encode} to create a text that can be stored in this column. Use 1190 * {@link Genres#decode} to get the broadcast genre strings from the text stored in the 1191 * column. 1192 * 1193 * <p>Type: TEXT 1194 * @see Genres#encode 1195 * @see Genres#decode 1196 */ 1197 public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre"; 1198 1199 /** 1200 * The comma-separated canonical genre string of this TV program. 1201 * 1202 * <p>Canonical genres are defined in {@link Genres}. Use {@link Genres#encode} to create a 1203 * text that can be stored in this column. Use {@link Genres#decode} to get the canonical 1204 * genre strings from the text stored in the column. 1205 * 1206 * <p>Type: TEXT 1207 * @see Genres 1208 * @see Genres#encode 1209 * @see Genres#decode 1210 */ 1211 public static final String COLUMN_CANONICAL_GENRE = "canonical_genre"; 1212 1213 /** 1214 * The short description of this TV program that is displayed to the user by default. 1215 * 1216 * <p>It is recommended to limit the length of the descriptions to 256 characters. 1217 * 1218 * <p>Type: TEXT 1219 */ 1220 public static final String COLUMN_SHORT_DESCRIPTION = "short_description"; 1221 1222 /** 1223 * The detailed, lengthy description of this TV program that is displayed only when the user 1224 * wants to see more information. 1225 * 1226 * <p>TV input services should leave this field empty if they have no additional details 1227 * beyond {@link #COLUMN_SHORT_DESCRIPTION}. 1228 * 1229 * <p>Type: TEXT 1230 */ 1231 public static final String COLUMN_LONG_DESCRIPTION = "long_description"; 1232 1233 /** 1234 * The width of the video for this TV program, in the unit of pixels. 1235 * 1236 * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video 1237 * resolution of the current TV program. Can be empty if it is not known initially or the 1238 * program does not convey any video such as the programs from type 1239 * {@link Channels#SERVICE_TYPE_AUDIO} channels. 1240 * 1241 * <p>Type: INTEGER 1242 */ 1243 public static final String COLUMN_VIDEO_WIDTH = "video_width"; 1244 1245 /** 1246 * The height of the video for this TV program, in the unit of pixels. 1247 * 1248 * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video 1249 * resolution of the current TV program. Can be empty if it is not known initially or the 1250 * program does not convey any video such as the programs from type 1251 * {@link Channels#SERVICE_TYPE_AUDIO} channels. 1252 * 1253 * <p>Type: INTEGER 1254 */ 1255 public static final String COLUMN_VIDEO_HEIGHT = "video_height"; 1256 1257 /** 1258 * The comma-separated audio languages of this TV program. 1259 * 1260 * <p>This is used to describe available audio languages included in the program. Use either 1261 * ISO 639-1 or 639-2/T codes. 1262 * 1263 * <p>Type: TEXT 1264 */ 1265 public static final String COLUMN_AUDIO_LANGUAGE = "audio_language"; 1266 1267 /** 1268 * The comma-separated content ratings of this TV program. 1269 * 1270 * <p>This is used to describe the content rating(s) of this program. Each comma-separated 1271 * content rating sub-string should be generated by calling 1272 * {@link TvContentRating#flattenToString}. Note that in most cases the program content is 1273 * rated by a single rating system, thus resulting in a corresponding single sub-string that 1274 * does not require comma separation and multiple sub-strings appear only when the program 1275 * content is rated by two or more content rating systems. If any of those ratings is 1276 * specified as "blocked rating" in the user's parental control settings, the TV input 1277 * service should block the current content and wait for the signal that it is okay to 1278 * unblock. 1279 * 1280 * <p>Type: TEXT 1281 */ 1282 public static final String COLUMN_CONTENT_RATING = "content_rating"; 1283 1284 /** 1285 * The URI for the poster art of this TV program. 1286 * 1287 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1288 * 1289 * <ul> 1290 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1291 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1292 * </li> 1293 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1294 * </ul> 1295 * 1296 * <p>Can be empty. 1297 * 1298 * <p>Type: TEXT 1299 */ 1300 public static final String COLUMN_POSTER_ART_URI = "poster_art_uri"; 1301 1302 /** 1303 * The URI for the thumbnail of this TV program. 1304 * 1305 * <p>The system can generate a thumbnail from the poster art if this column is not 1306 * specified. Thus it is not necessary for TV input services to include a thumbnail if it is 1307 * just a scaled image of the poster art. 1308 * 1309 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1310 * 1311 * <ul> 1312 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1313 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1314 * </li> 1315 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1316 * </ul> 1317 * 1318 * <p>Can be empty. 1319 * 1320 * <p>Type: TEXT 1321 */ 1322 public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri"; 1323 1324 /** 1325 * The flag indicating whether this TV program is searchable or not. 1326 * 1327 * <p>The columns of searchable programs can be read by other applications that have proper 1328 * permission. Care must be taken not to open sensitive data. 1329 * 1330 * <p>A value of 1 indicates that the program is searchable and its columns can be read by 1331 * other applications, a value of 0 indicates that the program is hidden and its columns can 1332 * be read only by the package that owns the program and the system. If not specified, this 1333 * value is set to 1 (searchable) by default. 1334 * 1335 * <p>Type: INTEGER (boolean) 1336 */ 1337 public static final String COLUMN_SEARCHABLE = "searchable"; 1338 1339 /** 1340 * The flag indicating whether recording of this program is prohibited. 1341 * 1342 * <p>A value of 1 indicates that recording of this program is prohibited and application 1343 * will not schedule any recording for this program. A value of 0 indicates that the 1344 * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by 1345 * default. 1346 * 1347 * <p>Type: INTEGER (boolean) 1348 */ 1349 public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited"; 1350 1351 /** 1352 * Internal data used by individual TV input services. 1353 * 1354 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1355 * apps. 1356 * 1357 * <p>Type: BLOB 1358 */ 1359 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 1360 1361 /** 1362 * Internal integer flag used by individual TV input services. 1363 * 1364 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1365 * apps. 1366 * 1367 * <p>Type: INTEGER 1368 */ 1369 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 1370 1371 /** 1372 * Internal integer flag used by individual TV input services. 1373 * 1374 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1375 * apps. 1376 * 1377 * <p>Type: INTEGER 1378 */ 1379 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 1380 1381 /** 1382 * Internal integer flag used by individual TV input services. 1383 * 1384 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1385 * apps. 1386 * 1387 * <p>Type: INTEGER 1388 */ 1389 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 1390 1391 /** 1392 * Internal integer flag used by individual TV input services. 1393 * 1394 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1395 * apps. 1396 * 1397 * <p>Type: INTEGER 1398 */ 1399 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 1400 1401 /** 1402 * The version number of this row entry used by TV input services. 1403 * 1404 * <p>This is best used by sync adapters to identify the rows to update. The number can be 1405 * defined by individual TV input services. One may assign the same value as 1406 * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV 1407 * broadcast. 1408 * 1409 * <p>Type: INTEGER 1410 */ 1411 public static final String COLUMN_VERSION_NUMBER = "version_number"; 1412 Programs()1413 private Programs() {} 1414 1415 /** Canonical genres for TV programs. */ 1416 public static final class Genres { 1417 /** The genre for Family/Kids. */ 1418 public static final String FAMILY_KIDS = "FAMILY_KIDS"; 1419 1420 /** The genre for Sports. */ 1421 public static final String SPORTS = "SPORTS"; 1422 1423 /** The genre for Shopping. */ 1424 public static final String SHOPPING = "SHOPPING"; 1425 1426 /** The genre for Movies. */ 1427 public static final String MOVIES = "MOVIES"; 1428 1429 /** The genre for Comedy. */ 1430 public static final String COMEDY = "COMEDY"; 1431 1432 /** The genre for Travel. */ 1433 public static final String TRAVEL = "TRAVEL"; 1434 1435 /** The genre for Drama. */ 1436 public static final String DRAMA = "DRAMA"; 1437 1438 /** The genre for Education. */ 1439 public static final String EDUCATION = "EDUCATION"; 1440 1441 /** The genre for Animal/Wildlife. */ 1442 public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE"; 1443 1444 /** The genre for News. */ 1445 public static final String NEWS = "NEWS"; 1446 1447 /** The genre for Gaming. */ 1448 public static final String GAMING = "GAMING"; 1449 1450 /** The genre for Arts. */ 1451 public static final String ARTS = "ARTS"; 1452 1453 /** The genre for Entertainment. */ 1454 public static final String ENTERTAINMENT = "ENTERTAINMENT"; 1455 1456 /** The genre for Life Style. */ 1457 public static final String LIFE_STYLE = "LIFE_STYLE"; 1458 1459 /** The genre for Music. */ 1460 public static final String MUSIC = "MUSIC"; 1461 1462 /** The genre for Premier. */ 1463 public static final String PREMIER = "PREMIER"; 1464 1465 /** The genre for Tech/Science. */ 1466 public static final String TECH_SCIENCE = "TECH_SCIENCE"; 1467 1468 private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>(); 1469 static { 1470 CANONICAL_GENRES.add(FAMILY_KIDS); 1471 CANONICAL_GENRES.add(SPORTS); 1472 CANONICAL_GENRES.add(SHOPPING); 1473 CANONICAL_GENRES.add(MOVIES); 1474 CANONICAL_GENRES.add(COMEDY); 1475 CANONICAL_GENRES.add(TRAVEL); 1476 CANONICAL_GENRES.add(DRAMA); 1477 CANONICAL_GENRES.add(EDUCATION); 1478 CANONICAL_GENRES.add(ANIMAL_WILDLIFE); 1479 CANONICAL_GENRES.add(NEWS); 1480 CANONICAL_GENRES.add(GAMING); 1481 CANONICAL_GENRES.add(ARTS); 1482 CANONICAL_GENRES.add(ENTERTAINMENT); 1483 CANONICAL_GENRES.add(LIFE_STYLE); 1484 CANONICAL_GENRES.add(MUSIC); 1485 CANONICAL_GENRES.add(PREMIER); 1486 CANONICAL_GENRES.add(TECH_SCIENCE); 1487 } 1488 1489 private static final char DOUBLE_QUOTE = '"'; 1490 private static final char COMMA = ','; 1491 private static final String DELIMITER = ","; 1492 1493 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 1494 Genres()1495 private Genres() {} 1496 1497 /** 1498 * Encodes genre strings to a text that can be put into the database. 1499 * 1500 * @param genres Genre strings. 1501 * @return an encoded genre string that can be inserted into the 1502 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 1503 */ encode(@onNull String... genres)1504 public static String encode(@NonNull String... genres) { 1505 if (genres == null) { 1506 // MNC and before will throw a NPE. 1507 return null; 1508 } 1509 StringBuilder sb = new StringBuilder(); 1510 String separator = ""; 1511 for (String genre : genres) { 1512 sb.append(separator).append(encodeToCsv(genre)); 1513 separator = DELIMITER; 1514 } 1515 return sb.toString(); 1516 } 1517 encodeToCsv(String genre)1518 private static String encodeToCsv(String genre) { 1519 StringBuilder sb = new StringBuilder(); 1520 int length = genre.length(); 1521 for (int i = 0; i < length; ++i) { 1522 char c = genre.charAt(i); 1523 switch (c) { 1524 case DOUBLE_QUOTE: 1525 sb.append(DOUBLE_QUOTE); 1526 break; 1527 case COMMA: 1528 sb.append(DOUBLE_QUOTE); 1529 break; 1530 } 1531 sb.append(c); 1532 } 1533 return sb.toString(); 1534 } 1535 1536 /** 1537 * Decodes the genre strings from the text stored in the database. 1538 * 1539 * @param genres The encoded genre string retrieved from the 1540 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 1541 * @return genre strings. 1542 */ decode(@onNull String genres)1543 public static String[] decode(@NonNull String genres) { 1544 if (TextUtils.isEmpty(genres)) { 1545 // MNC and before will throw a NPE for {@code null} genres. 1546 return EMPTY_STRING_ARRAY; 1547 } 1548 if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) { 1549 return new String[] {genres.trim()}; 1550 } 1551 StringBuilder sb = new StringBuilder(); 1552 List<String> results = new ArrayList<>(); 1553 int length = genres.length(); 1554 boolean escape = false; 1555 for (int i = 0; i < length; ++i) { 1556 char c = genres.charAt(i); 1557 switch (c) { 1558 case DOUBLE_QUOTE: 1559 if (!escape) { 1560 escape = true; 1561 continue; 1562 } 1563 break; 1564 case COMMA: 1565 if (!escape) { 1566 String string = sb.toString().trim(); 1567 if (string.length() > 0) { 1568 results.add(string); 1569 } 1570 sb = new StringBuilder(); 1571 continue; 1572 } 1573 break; 1574 } 1575 sb.append(c); 1576 escape = false; 1577 } 1578 String string = sb.toString().trim(); 1579 if (string.length() > 0) { 1580 results.add(string); 1581 } 1582 return results.toArray(new String[results.size()]); 1583 } 1584 1585 /** 1586 * Returns whether a given text is a canonical genre defined in {@link Genres}. 1587 * 1588 * @param genre The name of genre to be checked. 1589 * @return {@code true} if the genre is canonical, otherwise {@code false}. 1590 */ isCanonical(String genre)1591 public static boolean isCanonical(String genre) { 1592 return CANONICAL_GENRES.contains(genre); 1593 } 1594 } 1595 } 1596 1597 /** 1598 * Column definitions for the recorded TV programs table. 1599 * 1600 * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in 1601 * ascending order. 1602 */ 1603 public static final class RecordedPrograms implements BaseTvColumns { 1604 1605 /** The content:// style URI for this table. */ 1606 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 1607 + PATH_RECORDED_PROGRAM); 1608 1609 /** The MIME type of a directory of recorded TV programs. */ 1610 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program"; 1611 1612 /** The MIME type of a single recorded TV program. */ 1613 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program"; 1614 1615 /** 1616 * The ID of the TV input service that is associated with this recorded program. 1617 * 1618 * <p>Use {@link #buildInputId} to build the ID. 1619 * 1620 * <p>This is a required field. 1621 * 1622 * <p>Type: TEXT 1623 */ 1624 public static final String COLUMN_INPUT_ID = "input_id"; 1625 1626 /** 1627 * The ID of the TV channel that provided this recorded TV program. 1628 * 1629 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 1630 * 1631 * <p>This is a required field. 1632 * 1633 * <p>Type: INTEGER (long) 1634 * @see Programs#COLUMN_CHANNEL_ID 1635 */ 1636 public static final String COLUMN_CHANNEL_ID = Programs.COLUMN_CHANNEL_ID; 1637 1638 /** 1639 * The title of this recorded TV program. 1640 * 1641 * <p>If this recorded program is an episodic TV show, it is recommended that the title is 1642 * the series title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or 1643 * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_EPISODE_DISPLAY_NUMBER}, 1644 * and {@link #COLUMN_EPISODE_TITLE}) are filled in. 1645 * 1646 * <p>Type: TEXT 1647 * @see Programs#COLUMN_TITLE 1648 */ 1649 public static final String COLUMN_TITLE = Programs.COLUMN_TITLE; 1650 1651 /** 1652 * The season display number of this recorded TV program for episodic TV shows. 1653 * 1654 * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value 1655 * does not necessarily be numeric. (e.g. 12B) 1656 * 1657 * <p>Can be empty. 1658 * 1659 * <p>Type: TEXT 1660 */ 1661 public static final String COLUMN_SEASON_DISPLAY_NUMBER = 1662 Programs.COLUMN_SEASON_DISPLAY_NUMBER; 1663 1664 /** 1665 * The title of the season for this recorded TV program for episodic TV shows. 1666 * 1667 * <p>This is an optional field supplied only when the season has a special title 1668 * (e.g. The Final Season). If provided, the applications should display it instead of 1669 * {@link #COLUMN_SEASON_DISPLAY_NUMBER} without alterations. 1670 * (e.g. for "The Final Season", displayed string should be "The Final Season", not 1671 * "Season The Final Season"). When displaying multiple programs, the order should be based 1672 * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists. 1673 * 1674 * <p>Can be empty. 1675 * 1676 * <p>Type: TEXT 1677 */ 1678 public static final String COLUMN_SEASON_TITLE = Programs.COLUMN_SEASON_TITLE; 1679 1680 /** 1681 * The episode display number of this recorded TV program for episodic TV shows. 1682 * 1683 * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value 1684 * does not necessarily be numeric. (e.g. 12B) 1685 * 1686 * <p>Can be empty. 1687 * 1688 * <p>Type: TEXT 1689 */ 1690 public static final String COLUMN_EPISODE_DISPLAY_NUMBER = 1691 Programs.COLUMN_EPISODE_DISPLAY_NUMBER; 1692 1693 /** 1694 * The episode title of this recorded TV program for episodic TV shows. 1695 * 1696 * <p>Can be empty. 1697 * 1698 * <p>Type: TEXT 1699 * @see Programs#COLUMN_EPISODE_TITLE 1700 */ 1701 public static final String COLUMN_EPISODE_TITLE = Programs.COLUMN_EPISODE_TITLE; 1702 1703 /** 1704 * The start time of the original TV program, in milliseconds since the epoch. 1705 * 1706 * <p>Type: INTEGER (long) 1707 * @see Programs#COLUMN_START_TIME_UTC_MILLIS 1708 */ 1709 public static final String COLUMN_START_TIME_UTC_MILLIS = 1710 Programs.COLUMN_START_TIME_UTC_MILLIS; 1711 1712 /** 1713 * The end time of the original TV program, in milliseconds since the epoch. 1714 * 1715 * <p>Type: INTEGER (long) 1716 * @see Programs#COLUMN_END_TIME_UTC_MILLIS 1717 */ 1718 public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS; 1719 1720 /** 1721 * The comma-separated genre string of this recorded TV program. 1722 * 1723 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 1724 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 1725 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 1726 * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column. 1727 * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the 1728 * text stored in the column. 1729 * 1730 * <p>Type: TEXT 1731 * @see Programs#COLUMN_BROADCAST_GENRE 1732 */ 1733 public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE; 1734 1735 /** 1736 * The comma-separated canonical genre string of this recorded TV program. 1737 * 1738 * <p>Canonical genres are defined in {@link Programs.Genres}. Use 1739 * {@link Programs.Genres#encode Genres.encode()} to create a text that can be stored in 1740 * this column. Use {@link Programs.Genres#decode Genres.decode()} to get the canonical 1741 * genre strings from the text stored in the column. 1742 * 1743 * <p>Type: TEXT 1744 * @see Programs#COLUMN_CANONICAL_GENRE 1745 * @see Programs.Genres 1746 */ 1747 public static final String COLUMN_CANONICAL_GENRE = Programs.COLUMN_CANONICAL_GENRE; 1748 1749 /** 1750 * The short description of this recorded TV program that is displayed to the user by 1751 * default. 1752 * 1753 * <p>It is recommended to limit the length of the descriptions to 256 characters. 1754 * 1755 * <p>Type: TEXT 1756 * @see Programs#COLUMN_SHORT_DESCRIPTION 1757 */ 1758 public static final String COLUMN_SHORT_DESCRIPTION = Programs.COLUMN_SHORT_DESCRIPTION; 1759 1760 /** 1761 * The detailed, lengthy description of this recorded TV program that is displayed only when 1762 * the user wants to see more information. 1763 * 1764 * <p>TV input services should leave this field empty if they have no additional details 1765 * beyond {@link #COLUMN_SHORT_DESCRIPTION}. 1766 * 1767 * <p>Type: TEXT 1768 * @see Programs#COLUMN_LONG_DESCRIPTION 1769 */ 1770 public static final String COLUMN_LONG_DESCRIPTION = Programs.COLUMN_LONG_DESCRIPTION; 1771 1772 /** 1773 * The width of the video for this recorded TV program, in the unit of pixels. 1774 * 1775 * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video 1776 * resolution of the current recorded TV program. Can be empty if it is not known or the 1777 * recorded program does not convey any video. 1778 * 1779 * <p>Type: INTEGER 1780 * @see Programs#COLUMN_VIDEO_WIDTH 1781 */ 1782 public static final String COLUMN_VIDEO_WIDTH = Programs.COLUMN_VIDEO_WIDTH; 1783 1784 /** 1785 * The height of the video for this recorded TV program, in the unit of pixels. 1786 * 1787 * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video 1788 * resolution of the current recorded TV program. Can be empty if it is not known or the 1789 * recorded program does not convey any video. 1790 * 1791 * <p>Type: INTEGER 1792 * @see Programs#COLUMN_VIDEO_HEIGHT 1793 */ 1794 public static final String COLUMN_VIDEO_HEIGHT = Programs.COLUMN_VIDEO_HEIGHT; 1795 1796 /** 1797 * The comma-separated audio languages of this recorded TV program. 1798 * 1799 * <p>This is used to describe available audio languages included in the recorded program. 1800 * Use either ISO 639-1 or 639-2/T codes. 1801 * 1802 * <p>Type: TEXT 1803 * @see Programs#COLUMN_AUDIO_LANGUAGE 1804 */ 1805 public static final String COLUMN_AUDIO_LANGUAGE = Programs.COLUMN_AUDIO_LANGUAGE; 1806 1807 /** 1808 * The comma-separated content ratings of this recorded TV program. 1809 * 1810 * <p>This is used to describe the content rating(s) of this recorded program. Each 1811 * comma-separated content rating sub-string should be generated by calling 1812 * {@link TvContentRating#flattenToString}. Note that in most cases the recorded program 1813 * content is rated by a single rating system, thus resulting in a corresponding single 1814 * sub-string that does not require comma separation and multiple sub-strings appear only 1815 * when the recorded program content is rated by two or more content rating systems. If any 1816 * of those ratings is specified as "blocked rating" in the user's parental control 1817 * settings, the TV input service should block the current content and wait for the signal 1818 * that it is okay to unblock. 1819 * 1820 * <p>Type: TEXT 1821 * @see Programs#COLUMN_CONTENT_RATING 1822 */ 1823 public static final String COLUMN_CONTENT_RATING = Programs.COLUMN_CONTENT_RATING; 1824 1825 /** 1826 * The URI for the poster art of this recorded TV program. 1827 * 1828 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1829 * 1830 * <ul> 1831 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1832 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1833 * </li> 1834 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1835 * </ul> 1836 * 1837 * <p>Can be empty. 1838 * 1839 * <p>Type: TEXT 1840 * @see Programs#COLUMN_POSTER_ART_URI 1841 */ 1842 public static final String COLUMN_POSTER_ART_URI = Programs.COLUMN_POSTER_ART_URI; 1843 1844 /** 1845 * The URI for the thumbnail of this recorded TV program. 1846 * 1847 * <p>The system can generate a thumbnail from the poster art if this column is not 1848 * specified. Thus it is not necessary for TV input services to include a thumbnail if it is 1849 * just a scaled image of the poster art. 1850 * 1851 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1852 * 1853 * <ul> 1854 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1855 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1856 * </li> 1857 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1858 * </ul> 1859 * 1860 * <p>Can be empty. 1861 * 1862 * <p>Type: TEXT 1863 * @see Programs#COLUMN_THUMBNAIL_URI 1864 */ 1865 public static final String COLUMN_THUMBNAIL_URI = Programs.COLUMN_THUMBNAIL_URI; 1866 1867 /** 1868 * The flag indicating whether this recorded TV program is searchable or not. 1869 * 1870 * <p>The columns of searchable recorded programs can be read by other applications that 1871 * have proper permission. Care must be taken not to open sensitive data. 1872 * 1873 * <p>A value of 1 indicates that the recorded program is searchable and its columns can be 1874 * read by other applications, a value of 0 indicates that the recorded program is hidden 1875 * and its columns can be read only by the package that owns the recorded program and the 1876 * system. If not specified, this value is set to 1 (searchable) by default. 1877 * 1878 * <p>Type: INTEGER (boolean) 1879 * @see Programs#COLUMN_SEARCHABLE 1880 */ 1881 public static final String COLUMN_SEARCHABLE = Programs.COLUMN_SEARCHABLE; 1882 1883 /** 1884 * The URI of the recording data for this recorded program. 1885 * 1886 * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this 1887 * information to manage recording storage. The URI should indicate a file or directory with 1888 * the scheme {@link android.content.ContentResolver#SCHEME_FILE}. 1889 * 1890 * <p>Type: TEXT 1891 * @see #COLUMN_RECORDING_DATA_BYTES 1892 */ 1893 public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri"; 1894 1895 /** 1896 * The data size (in bytes) for this recorded program. 1897 * 1898 * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this 1899 * information to manage recording storage. 1900 * 1901 * <p>Type: INTEGER (long) 1902 * @see #COLUMN_RECORDING_DATA_URI 1903 */ 1904 public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes"; 1905 1906 /** 1907 * The duration (in milliseconds) of this recorded program. 1908 * 1909 * <p>The actual duration of the recorded program can differ from the one calculated by 1910 * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program 1911 * recording can be interrupted in the middle for some reason, resulting in a partially 1912 * recorded program, which is still playable. 1913 * 1914 * <p>Type: INTEGER 1915 */ 1916 public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis"; 1917 1918 /** 1919 * The expiration time for this recorded program, in milliseconds since the epoch. 1920 * 1921 * <p>Recorded TV programs do not expire by default unless explicitly requested by the user 1922 * or the user allows applications to delete them in order to free up disk space for future 1923 * recording. However, some TV content can have expiration date set by the content provider 1924 * when recorded. This field is used to indicate such a restriction. 1925 * 1926 * <p>Can be empty. 1927 * 1928 * <p>Type: INTEGER (long) 1929 */ 1930 public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = 1931 "recording_expire_time_utc_millis"; 1932 1933 1934 /** 1935 * Internal data used by individual TV input services. 1936 * 1937 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1938 * apps. 1939 * 1940 * <p>Type: BLOB 1941 * @see Programs#COLUMN_INTERNAL_PROVIDER_DATA 1942 */ 1943 public static final String COLUMN_INTERNAL_PROVIDER_DATA = 1944 Programs.COLUMN_INTERNAL_PROVIDER_DATA; 1945 1946 /** 1947 * Internal integer flag used by individual TV input services. 1948 * 1949 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1950 * apps. 1951 * 1952 * <p>Type: INTEGER 1953 * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG1 1954 */ 1955 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = 1956 Programs.COLUMN_INTERNAL_PROVIDER_FLAG1; 1957 1958 /** 1959 * Internal integer flag used by individual TV input services. 1960 * 1961 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1962 * apps. 1963 * 1964 * <p>Type: INTEGER 1965 * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG2 1966 */ 1967 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = 1968 Programs.COLUMN_INTERNAL_PROVIDER_FLAG2; 1969 1970 /** 1971 * Internal integer flag used by individual TV input services. 1972 * 1973 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1974 * apps. 1975 * 1976 * <p>Type: INTEGER 1977 * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG3 1978 */ 1979 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = 1980 Programs.COLUMN_INTERNAL_PROVIDER_FLAG3; 1981 1982 /** 1983 * Internal integer flag used by individual TV input services. 1984 * 1985 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1986 * apps. 1987 * 1988 * <p>Type: INTEGER 1989 * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG4 1990 */ 1991 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = 1992 Programs.COLUMN_INTERNAL_PROVIDER_FLAG4; 1993 1994 /** 1995 * The version number of this row entry used by TV input services. 1996 * 1997 * <p>This is best used by sync adapters to identify the rows to update. The number can be 1998 * defined by individual TV input services. One may assign the same value as 1999 * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV 2000 * broadcast. 2001 * 2002 * <p>Type: INTEGER 2003 * @see Programs#COLUMN_VERSION_NUMBER 2004 */ 2005 public static final String COLUMN_VERSION_NUMBER = Programs.COLUMN_VERSION_NUMBER; 2006 RecordedPrograms()2007 private RecordedPrograms() {} 2008 } 2009 2010 /** 2011 * Column definitions for the TV programs that the user watched. Applications do not have access 2012 * to this table. 2013 * 2014 * <p>By default, the query results will be sorted by 2015 * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order. 2016 * @hide 2017 */ 2018 @SystemApi 2019 public static final class WatchedPrograms implements BaseTvColumns { 2020 2021 /** The content:// style URI for this table. */ 2022 public static final Uri CONTENT_URI = 2023 Uri.parse("content://" + AUTHORITY + "/watched_program"); 2024 2025 /** The MIME type of a directory of watched programs. */ 2026 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program"; 2027 2028 /** The MIME type of a single item in this table. */ 2029 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program"; 2030 2031 /** 2032 * The UTC time that the user started watching this TV program, in milliseconds since the 2033 * epoch. 2034 * 2035 * <p>Type: INTEGER (long) 2036 */ 2037 public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS = 2038 "watch_start_time_utc_millis"; 2039 2040 /** 2041 * The UTC time that the user stopped watching this TV program, in milliseconds since the 2042 * epoch. 2043 * 2044 * <p>Type: INTEGER (long) 2045 */ 2046 public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis"; 2047 2048 /** 2049 * The ID of the TV channel that provides this TV program. 2050 * 2051 * <p>This is a required field. 2052 * 2053 * <p>Type: INTEGER (long) 2054 */ 2055 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2056 2057 /** 2058 * The title of this TV program. 2059 * 2060 * <p>Type: TEXT 2061 */ 2062 public static final String COLUMN_TITLE = "title"; 2063 2064 /** 2065 * The start time of this TV program, in milliseconds since the epoch. 2066 * 2067 * <p>Type: INTEGER (long) 2068 */ 2069 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 2070 2071 /** 2072 * The end time of this TV program, in milliseconds since the epoch. 2073 * 2074 * <p>Type: INTEGER (long) 2075 */ 2076 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 2077 2078 /** 2079 * The description of this TV program. 2080 * 2081 * <p>Type: TEXT 2082 */ 2083 public static final String COLUMN_DESCRIPTION = "description"; 2084 2085 /** 2086 * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle) 2087 * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that 2088 * provides this TV program. (Used internally.) 2089 * 2090 * <p>This column contains an encoded string that represents comma-separated key-value pairs of 2091 * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape 2092 * character for '%', '=', and ','. 2093 * 2094 * <p>Type: TEXT 2095 */ 2096 public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params"; 2097 2098 /** 2099 * The session token of this TV program. (Used internally.) 2100 * 2101 * <p>This contains a String representation of {@link IBinder} for 2102 * {@link TvInputService.Session} that provides the current TV program. It is used 2103 * internally to distinguish watched programs entries from different TV input sessions. 2104 * 2105 * <p>Type: TEXT 2106 */ 2107 public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token"; 2108 WatchedPrograms()2109 private WatchedPrograms() {} 2110 } 2111 } 2112