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 17package android.media.tv; 18 19import android.annotation.IntDef; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.annotation.SdkConstant; 23import android.annotation.StringDef; 24import android.annotation.SystemApi; 25import android.annotation.SdkConstant.SdkConstantType; 26import android.app.Activity; 27import android.content.ComponentName; 28import android.content.ContentResolver; 29import android.content.ContentUris; 30import android.content.Context; 31import android.content.Intent; 32import android.net.Uri; 33import android.os.Bundle; 34import android.os.IBinder; 35import android.provider.BaseColumns; 36import android.text.TextUtils; 37import android.util.ArraySet; 38 39import java.lang.annotation.Retention; 40import java.lang.annotation.RetentionPolicy; 41import java.util.ArrayList; 42import java.util.HashMap; 43import java.util.List; 44import java.util.Map; 45 46/** 47 * The contract between the TV provider and applications. Contains definitions for the supported 48 * URIs and columns. 49 * <h3>Overview</h3> 50 * 51 * <p>TvContract defines a basic database of TV content metadata such as channel and program 52 * information. The information is stored in {@link Channels} and {@link Programs} tables. 53 * 54 * <ul> 55 * <li>A row in the {@link Channels} table represents information about a TV channel. The data 56 * format can vary greatly from standard to standard or according to service provider, thus 57 * the columns here are mostly comprised of basic entities that are usually seen to users 58 * regardless of standard such as channel number and name.</li> 59 * <li>A row in the {@link Programs} table represents a set of data describing a TV program such 60 * as program title and start time.</li> 61 * </ul> 62 */ 63public final class TvContract { 64 /** The authority for the TV provider. */ 65 public static final String AUTHORITY = "android.media.tv"; 66 67 /** 68 * Permission to read TV listings. This is required to read all the TV channel and program 69 * information available on the system. 70 * @hide 71 */ 72 public static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS"; 73 74 private static final String PATH_CHANNEL = "channel"; 75 private static final String PATH_PROGRAM = "program"; 76 private static final String PATH_RECORDED_PROGRAM = "recorded_program"; 77 private static final String PATH_PREVIEW_PROGRAM = "preview_program"; 78 private static final String PATH_WATCH_NEXT_PROGRAM = "watch_next_program"; 79 private static final String PATH_PASSTHROUGH = "passthrough"; 80 81 /** 82 * Broadcast Action: sent when an application requests the system to make the given channel 83 * browsable. The operation is performed in the background without user interaction. This 84 * is only relevant to channels with {@link Channels#TYPE_PREVIEW} type. 85 * 86 * <p>The intent must contain the following bundle parameters: 87 * <ul> 88 * <li>{@link #EXTRA_CHANNEL_ID}: ID for the {@link Channels#TYPE_PREVIEW} channel as a long 89 * integer.</li> 90 * <li>{@link #EXTRA_PACKAGE_NAME}: the package name of the requesting application.</li> 91 * </ul> 92 * @hide 93 */ 94 @SystemApi 95 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 96 public static final String ACTION_CHANNEL_BROWSABLE_REQUESTED = 97 "android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED"; 98 99 /** 100 * Activity Action: sent by an application telling the system to make the given channel 101 * browsable with user interaction. The system may show UI to ask user to approve the channel. 102 * This is only relevant to channels with {@link Channels#TYPE_PREVIEW} type. Use 103 * {@link Activity#startActivityForResult} to get the result of the request. 104 * 105 * <p>The intent must contain the following bundle parameters: 106 * <ul> 107 * <li>{@link #EXTRA_CHANNEL_ID}: ID for the {@link Channels#TYPE_PREVIEW} channel as a long 108 * integer.</li> 109 * </ul> 110 */ 111 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 112 public static final String ACTION_REQUEST_CHANNEL_BROWSABLE = 113 "android.media.tv.action.REQUEST_CHANNEL_BROWSABLE"; 114 115 /** 116 * Broadcast Action: sent by the system to tell the target TV input that one of its preview 117 * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for 118 * example, might be a result of users' interaction with UI. The input is expected to delete the 119 * preview program from the content provider. 120 * 121 * <p>The intent must contain the following bundle parameter: 122 * <ul> 123 * <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the disabled preview program ID.</li> 124 * </ul> 125 */ 126 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 127 public static final String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = 128 "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED"; 129 130 /** 131 * Broadcast Action: sent by the system to tell the target TV input that one of its "watch next" 132 * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for 133 * example, might be a result of users' interaction with UI. The input is expected to delete the 134 * "watch next" program from the content provider. 135 * 136 * <p>The intent must contain the following bundle parameter: 137 * <ul> 138 * <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the disabled "watch next" program ID.</li> 139 * </ul> 140 */ 141 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 142 public static final String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED = 143 "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED"; 144 145 /** 146 * Broadcast Action: sent by the system to tell the target TV input that one of its existing 147 * preview programs is added to the watch next programs table by user. 148 * 149 * <p>The intent must contain the following bundle parameters: 150 * <ul> 151 * <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the ID of the existing preview program.</li> 152 * <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the ID of the new watch next program.</li> 153 * </ul> 154 */ 155 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 156 public static final String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = 157 "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT"; 158 159 /** 160 * Broadcast Action: sent to the target TV input after it is first installed to notify the input 161 * to initialize its channels and programs to the system content provider. 162 * 163 * <p>Note that this intent is sent only on devices with 164 * {@link android.content.pm.PackageManager#FEATURE_LEANBACK} enabled. Besides that, in order 165 * to receive this intent, the target TV input must: 166 * <ul> 167 * <li>Declare a broadcast receiver for this intent in its 168 * <code>AndroidManifest.xml</code>.</li> 169 * <li>Declare appropriate permissions to write channel and program data in its 170 * <code>AndroidManifest.xml</code>.</li> 171 * </ul> 172 */ 173 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 174 public static final String ACTION_INITIALIZE_PROGRAMS = 175 "android.media.tv.action.INITIALIZE_PROGRAMS"; 176 177 /** 178 * The key for a bundle parameter containing a channel ID as a long integer 179 */ 180 public static final String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID"; 181 182 /** 183 * The key for a bundle parameter containing a package name as a string. 184 * @hide 185 */ 186 @SystemApi 187 public static final String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME"; 188 189 /** The key for a bundle parameter containing a program ID as a long integer. */ 190 public static final String EXTRA_PREVIEW_PROGRAM_ID = 191 "android.media.tv.extra.PREVIEW_PROGRAM_ID"; 192 193 /** The key for a bundle parameter containing a watch next program ID as a long integer. */ 194 public static final String EXTRA_WATCH_NEXT_PROGRAM_ID = 195 "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID"; 196 197 /** 198 * The key for a bundle parameter containing the result code of a method call as an integer. 199 * 200 * @see #RESULT_OK 201 * @see #RESULT_ERROR_IO 202 * @see #RESULT_ERROR_INVALID_ARGUMENT 203 * @hide 204 */ 205 @SystemApi 206 public static final String EXTRA_RESULT_CODE = "android.media.tv.extra.RESULT_CODE"; 207 208 /** 209 * The result code for a successful execution without error. 210 * @hide 211 */ 212 @SystemApi 213 public static final int RESULT_OK = 0; 214 215 /** 216 * The result code for a failure from I/O operation. 217 * @hide 218 */ 219 @SystemApi 220 public static final int RESULT_ERROR_IO = 1; 221 222 /** 223 * The result code for a failure from invalid argument. 224 * @hide 225 */ 226 @SystemApi 227 public static final int RESULT_ERROR_INVALID_ARGUMENT = 2; 228 229 /** 230 * The method name to get existing columns in the given table of the specified content provider. 231 * 232 * <p>The method caller must provide the following parameter: 233 * <ul> 234 * <li>{@code arg}: The content URI of the target table as a {@link String}.</li> 235 * </ul> 236 237 * <p>On success, the returned {@link android.os.Bundle} will include existing column names 238 * with the key {@link #EXTRA_EXISTING_COLUMN_NAMES}. Otherwise, the return value will be {@code null}. 239 * 240 * @see ContentResolver#call(Uri, String, String, Bundle) 241 * @see #EXTRA_EXISTING_COLUMN_NAMES 242 * @hide 243 */ 244 @SystemApi 245 public static final String METHOD_GET_COLUMNS = "get_columns"; 246 247 /** 248 * The method name to add a new column in the given table of the specified content provider. 249 * 250 * <p>The method caller must provide the following parameter: 251 * <ul> 252 * <li>{@code arg}: The content URI of the target table as a {@link String}.</li> 253 * <li>{@code extra}: Name, data type, and default value of the new column in a Bundle: 254 * <ul> 255 * <li>{@link #EXTRA_COLUMN_NAME} the column name as a {@link String}.</li> 256 * <li>{@link #EXTRA_DATA_TYPE} the data type as a {@link String}.</li> 257 * <li>{@link #EXTRA_DEFAULT_VALUE} the default value as a {@link String}. 258 * (optional)</li> 259 * </ul> 260 * </li> 261 * </ul> 262 * 263 * <p>On success, the returned {@link android.os.Bundle} will include current colum names after 264 * the addition operation with the key {@link #EXTRA_EXISTING_COLUMN_NAMES}. Otherwise, the 265 * return value will be {@code null}. 266 * 267 * @see ContentResolver#call(Uri, String, String, Bundle) 268 * @see #EXTRA_COLUMN_NAME 269 * @see #EXTRA_DATA_TYPE 270 * @see #EXTRA_DEFAULT_VALUE 271 * @see #EXTRA_EXISTING_COLUMN_NAMES 272 * @hide 273 */ 274 @SystemApi 275 public static final String METHOD_ADD_COLUMN = "add_column"; 276 277 /** 278 * The method name to get all the blocked packages. When a package is blocked, all the data for 279 * preview programs/channels and watch next programs belonging to this package in the content 280 * provider will be cleared. Once a package is blocked, {@link SecurityException} will be thrown 281 * for all the requests to preview programs/channels and watch next programs via 282 * {@link android.content.ContentProvider} from it. 283 * 284 * <p>The returned {@link android.os.Bundle} will include all the blocked package names with the 285 * key {@link #EXTRA_BLOCKED_PACKAGES}. 286 * 287 * @see ContentResolver#call(Uri, String, String, Bundle) 288 * @see #EXTRA_BLOCKED_PACKAGES 289 * @see #METHOD_BLOCK_PACKAGE 290 * @see #METHOD_UNBLOCK_PACKAGE 291 * @hide 292 */ 293 @SystemApi 294 public static final String METHOD_GET_BLOCKED_PACKAGES = "get_blocked_packages"; 295 296 /** 297 * The method name to block the access from the given package. When a package is blocked, all 298 * the data for preview programs/channels and watch next programs belonging to this package in 299 * the content provider will be cleared. Once a package is blocked, {@link SecurityException} 300 * will be thrown for all the requests to preview programs/channels and watch next programs via 301 * {@link android.content.ContentProvider} from it. 302 * 303 * <p>The method caller must provide the following parameter: 304 * <ul> 305 * <li>{@code arg}: The package name to be added as blocked package {@link String}.</li> 306 * </ul> 307 * 308 * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the 309 * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is 310 * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result 311 * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}. 312 * 313 * @see ContentResolver#call(Uri, String, String, Bundle) 314 * @see #EXTRA_RESULT_CODE 315 * @see #METHOD_GET_BLOCKED_PACKAGES 316 * @see #METHOD_UNBLOCK_PACKAGE 317 * @hide 318 */ 319 @SystemApi 320 public static final String METHOD_BLOCK_PACKAGE = "block_package"; 321 322 /** 323 * The method name to unblock the access from the given package. When a package is blocked, all 324 * the data for preview programs/channels and watch next programs belonging to this package in 325 * the content provider will be cleared. Once a package is blocked, {@link SecurityException} 326 * will be thrown for all the requests to preview programs/channels and watch next programs via 327 * {@link android.content.ContentProvider} from it. 328 * 329 * <p>The method caller must provide the following parameter: 330 * <ul> 331 * <li>{@code arg}: The package name to be removed from blocked list as a {@link String}. 332 * </li> 333 * </ul> 334 * 335 * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the 336 * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is 337 * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result 338 * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}. 339 * 340 * @see ContentResolver#call(Uri, String, String, Bundle) 341 * @see #EXTRA_RESULT_CODE 342 * @see #METHOD_GET_BLOCKED_PACKAGES 343 * @see #METHOD_BLOCK_PACKAGE 344 * @hide 345 */ 346 @SystemApi 347 public static final String METHOD_UNBLOCK_PACKAGE = "unblock_package"; 348 349 /** 350 * The key for a returned {@link Bundle} value containing existing column names in the given 351 * table as an {@link ArrayList} of {@link String}. 352 * 353 * @see #METHOD_GET_COLUMNS 354 * @see #METHOD_ADD_COLUMN 355 * @hide 356 */ 357 @SystemApi 358 public static final String EXTRA_EXISTING_COLUMN_NAMES = 359 "android.media.tv.extra.EXISTING_COLUMN_NAMES"; 360 361 /** 362 * The key for a {@link Bundle} parameter containing the new column name to be added in the 363 * given table as a non-empty {@link CharSequence}. 364 * 365 * @see #METHOD_ADD_COLUMN 366 * @hide 367 */ 368 @SystemApi 369 public static final String EXTRA_COLUMN_NAME = "android.media.tv.extra.COLUMN_NAME"; 370 371 /** 372 * The key for a {@link Bundle} parameter containing the data type of the new column to be added 373 * in the given table as a non-empty {@link CharSequence}, which should be one of the following 374 * values: {@code "TEXT"}, {@code "INTEGER"}, {@code "REAL"}, or {@code "BLOB"}. 375 * 376 * @see #METHOD_ADD_COLUMN 377 * @hide 378 */ 379 @SystemApi 380 public static final String EXTRA_DATA_TYPE = "android.media.tv.extra.DATA_TYPE"; 381 382 /** 383 * The key for a {@link Bundle} parameter containing the default value of the new column to be 384 * added in the given table as a {@link CharSequence}, which represents a valid default value 385 * according to the data type provided with {@link #EXTRA_DATA_TYPE}. 386 * 387 * @see #METHOD_ADD_COLUMN 388 * @hide 389 */ 390 @SystemApi 391 public static final String EXTRA_DEFAULT_VALUE = "android.media.tv.extra.DEFAULT_VALUE"; 392 393 /** 394 * The key for a returned {@link Bundle} value containing all the blocked package names as an 395 * {@link ArrayList} of {@link String}. 396 * 397 * @see #METHOD_GET_BLOCKED_PACKAGES 398 * @hide 399 */ 400 @SystemApi 401 public static final String EXTRA_BLOCKED_PACKAGES = "android.media.tv.extra.BLOCKED_PACKAGES"; 402 403 /** 404 * An optional query, update or delete URI parameter that allows the caller to specify TV input 405 * ID to filter channels. 406 * @hide 407 */ 408 public static final String PARAM_INPUT = "input"; 409 410 /** 411 * An optional query, update or delete URI parameter that allows the caller to specify channel 412 * ID to filter programs. 413 * @hide 414 */ 415 public static final String PARAM_CHANNEL = "channel"; 416 417 /** 418 * An optional query, update or delete URI parameter that allows the caller to specify start 419 * time (in milliseconds since the epoch) to filter programs. 420 * @hide 421 */ 422 public static final String PARAM_START_TIME = "start_time"; 423 424 /** 425 * An optional query, update or delete URI parameter that allows the caller to specify end time 426 * (in milliseconds since the epoch) to filter programs. 427 * @hide 428 */ 429 public static final String PARAM_END_TIME = "end_time"; 430 431 /** 432 * A query, update or delete URI parameter that allows the caller to operate on all or 433 * browsable-only channels. If set to "true", the rows that contain non-browsable channels are 434 * not affected. 435 * @hide 436 */ 437 public static final String PARAM_BROWSABLE_ONLY = "browsable_only"; 438 439 /** 440 * An optional query, update or delete URI parameter that allows the caller to specify canonical 441 * genre to filter programs. 442 * @hide 443 */ 444 public static final String PARAM_CANONICAL_GENRE = "canonical_genre"; 445 446 /** 447 * A query, update or delete URI parameter that allows the caller to operate only on preview or 448 * non-preview channels. If set to "true", the operation affects the rows for preview channels 449 * only. If set to "false", the operation affects the rows for non-preview channels only. 450 * @hide 451 */ 452 public static final String PARAM_PREVIEW = "preview"; 453 454 /** 455 * An optional query, update or delete URI parameter that allows the caller to specify package 456 * name to filter channels. 457 * @hide 458 */ 459 public static final String PARAM_PACKAGE = "package"; 460 461 /** 462 * Builds an ID that uniquely identifies a TV input service. 463 * 464 * @param name The {@link ComponentName} of the TV input service to build ID for. 465 * @return the ID for the given TV input service. 466 */ 467 public static String buildInputId(ComponentName name) { 468 return name.flattenToShortString(); 469 } 470 471 /** 472 * Builds a URI that points to a specific channel. 473 * 474 * @param channelId The ID of the channel to point to. 475 */ 476 public static Uri buildChannelUri(long channelId) { 477 return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId); 478 } 479 480 /** 481 * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI) 482 * 483 * @param inputId The ID of the pass-through input to build a channels URI for. 484 * @see TvInputInfo#isPassthroughInput() 485 */ 486 public static Uri buildChannelUriForPassthroughInput(String inputId) { 487 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY) 488 .appendPath(PATH_PASSTHROUGH).appendPath(inputId).build(); 489 } 490 491 /** 492 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 493 * 494 * @param channelId The ID of the channel whose logo is pointed to. 495 */ 496 public static Uri buildChannelLogoUri(long channelId) { 497 return buildChannelLogoUri(buildChannelUri(channelId)); 498 } 499 500 /** 501 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 502 * 503 * @param channelUri The URI of the channel whose logo is pointed to. 504 */ 505 public static Uri buildChannelLogoUri(Uri channelUri) { 506 if (!isChannelUriForTunerInput(channelUri)) { 507 throw new IllegalArgumentException("Not a channel: " + channelUri); 508 } 509 return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY); 510 } 511 512 /** 513 * Builds a URI that points to all channels from a given TV input. 514 * 515 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 516 * URI for all the TV inputs. 517 */ 518 public static Uri buildChannelsUriForInput(@Nullable String inputId) { 519 return buildChannelsUriForInput(inputId, false); 520 } 521 522 /** 523 * Builds a URI that points to all or browsable-only channels from a given TV input. 524 * 525 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 526 * URI for all the TV inputs. 527 * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set 528 * to {@code false} the URI points to all channels regardless of whether they are 529 * browsable or not. 530 * @hide 531 */ 532 @SystemApi 533 public static Uri buildChannelsUriForInput(@Nullable String inputId, 534 boolean browsableOnly) { 535 Uri.Builder builder = Channels.CONTENT_URI.buildUpon(); 536 if (inputId != null) { 537 builder.appendQueryParameter(PARAM_INPUT, inputId); 538 } 539 return builder.appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)) 540 .build(); 541 } 542 543 /** 544 * Builds a URI that points to all or browsable-only channels which have programs with the given 545 * genre from the given TV input. 546 * 547 * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a 548 * URI for all the TV inputs. 549 * @param genre {@link Programs.Genres} to search. If {@code null}, builds a URI for all genres. 550 * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set 551 * to {@code false} the URI points to all channels regardless of whether they are 552 * browsable or not. 553 * @hide 554 */ 555 @SystemApi 556 public static Uri buildChannelsUriForInput(@Nullable String inputId, 557 @Nullable String genre, boolean browsableOnly) { 558 if (genre == null) { 559 return buildChannelsUriForInput(inputId, browsableOnly); 560 } 561 if (!Programs.Genres.isCanonical(genre)) { 562 throw new IllegalArgumentException("Not a canonical genre: '" + genre + "'"); 563 } 564 return buildChannelsUriForInput(inputId, browsableOnly).buildUpon() 565 .appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build(); 566 } 567 568 /** 569 * Builds a URI that points to a specific program. 570 * 571 * @param programId The ID of the program to point to. 572 */ 573 public static Uri buildProgramUri(long programId) { 574 return ContentUris.withAppendedId(Programs.CONTENT_URI, programId); 575 } 576 577 /** 578 * Builds a URI that points to all programs on a given channel. 579 * 580 * @param channelId The ID of the channel to return programs for. 581 */ 582 public static Uri buildProgramsUriForChannel(long channelId) { 583 return Programs.CONTENT_URI.buildUpon() 584 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build(); 585 } 586 587 /** 588 * Builds a URI that points to all programs on a given channel. 589 * 590 * @param channelUri The URI of the channel to return programs for. 591 */ 592 public static Uri buildProgramsUriForChannel(Uri channelUri) { 593 if (!isChannelUriForTunerInput(channelUri)) { 594 throw new IllegalArgumentException("Not a channel: " + channelUri); 595 } 596 return buildProgramsUriForChannel(ContentUris.parseId(channelUri)); 597 } 598 599 /** 600 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 601 * given time frame. 602 * 603 * @param channelId The ID of the channel to return programs for. 604 * @param startTime The start time used to filter programs. The returned programs should have 605 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 606 * @param endTime The end time used to filter programs. The returned programs should have 607 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 608 */ 609 public static Uri buildProgramsUriForChannel(long channelId, long startTime, 610 long endTime) { 611 Uri uri = buildProgramsUriForChannel(channelId); 612 return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime)) 613 .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build(); 614 } 615 616 /** 617 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 618 * given time frame. 619 * 620 * @param channelUri The URI of the channel to return programs for. 621 * @param startTime The start time used to filter programs. The returned programs should have 622 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 623 * @param endTime The end time used to filter programs. The returned programs should have 624 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 625 */ 626 public static Uri buildProgramsUriForChannel(Uri channelUri, long startTime, 627 long endTime) { 628 if (!isChannelUriForTunerInput(channelUri)) { 629 throw new IllegalArgumentException("Not a channel: " + channelUri); 630 } 631 return buildProgramsUriForChannel(ContentUris.parseId(channelUri), startTime, endTime); 632 } 633 634 /** 635 * Builds a URI that points to a specific recorded program. 636 * 637 * @param recordedProgramId The ID of the recorded program to point to. 638 */ 639 public static Uri buildRecordedProgramUri(long recordedProgramId) { 640 return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId); 641 } 642 643 /** 644 * Builds a URI that points to a specific preview program. 645 * 646 * @param previewProgramId The ID of the preview program to point to. 647 */ 648 public static Uri buildPreviewProgramUri(long previewProgramId) { 649 return ContentUris.withAppendedId(PreviewPrograms.CONTENT_URI, previewProgramId); 650 } 651 652 /** 653 * Builds a URI that points to all preview programs on a given channel. 654 * 655 * @param channelId The ID of the channel to return preview programs for. 656 */ 657 public static Uri buildPreviewProgramsUriForChannel(long channelId) { 658 return PreviewPrograms.CONTENT_URI.buildUpon() 659 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build(); 660 } 661 662 /** 663 * Builds a URI that points to all preview programs on a given channel. 664 * 665 * @param channelUri The URI of the channel to return preview programs for. 666 */ 667 public static Uri buildPreviewProgramsUriForChannel(Uri channelUri) { 668 if (!isChannelUriForTunerInput(channelUri)) { 669 throw new IllegalArgumentException("Not a channel: " + channelUri); 670 } 671 return buildPreviewProgramsUriForChannel(ContentUris.parseId(channelUri)); 672 } 673 674 /** 675 * Builds a URI that points to a specific watch next program. 676 * 677 * @param watchNextProgramId The ID of the watch next program to point to. 678 */ 679 public static Uri buildWatchNextProgramUri(long watchNextProgramId) { 680 return ContentUris.withAppendedId(WatchNextPrograms.CONTENT_URI, watchNextProgramId); 681 } 682 683 /** 684 * Builds a URI that points to a specific program the user watched. 685 * 686 * @param watchedProgramId The ID of the watched program to point to. 687 * @hide 688 */ 689 public static Uri buildWatchedProgramUri(long watchedProgramId) { 690 return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId); 691 } 692 693 private static boolean isTvUri(Uri uri) { 694 return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) 695 && AUTHORITY.equals(uri.getAuthority()); 696 } 697 698 private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) { 699 List<String> pathSegments = uri.getPathSegments(); 700 return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0)); 701 } 702 703 /** 704 * Returns {@code true}, if {@code uri} is a channel URI. 705 */ 706 public static boolean isChannelUri(Uri uri) { 707 return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri); 708 } 709 710 /** 711 * Returns {@code true}, if {@code uri} is a channel URI for a tuner input. 712 */ 713 public static boolean isChannelUriForTunerInput(Uri uri) { 714 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL); 715 } 716 717 /** 718 * Returns {@code true}, if {@code uri} is a channel URI for a pass-through input. 719 */ 720 public static boolean isChannelUriForPassthroughInput(Uri uri) { 721 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH); 722 } 723 724 /** 725 * Returns {@code true}, if {@code uri} is a program URI. 726 */ 727 public static boolean isProgramUri(Uri uri) { 728 return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM); 729 } 730 731 /** 732 * Requests to make a channel browsable. 733 * 734 * <p>Once called, the system will review the request and make the channel browsable based on 735 * its policy. The first request from a package is guaranteed to be approved. This is only 736 * relevant to channels with {@link Channels#TYPE_PREVIEW} type. 737 * 738 * @param context The context for accessing content provider. 739 * @param channelId The channel ID to be browsable. 740 * @see Channels#COLUMN_BROWSABLE 741 */ 742 public static void requestChannelBrowsable(Context context, long channelId) { 743 TvInputManager manager = (TvInputManager) context.getSystemService( 744 Context.TV_INPUT_SERVICE); 745 if (manager != null) { 746 manager.requestChannelBrowsable(buildChannelUri(channelId)); 747 } 748 } 749 750 private TvContract() {} 751 752 /** 753 * Common base for the tables of TV channels/programs. 754 */ 755 public interface BaseTvColumns extends BaseColumns { 756 /** 757 * The name of the package that owns the current row. 758 * 759 * <p>The TV provider fills in this column with the name of the package that provides the 760 * initial data of the row. If the package is later uninstalled, the rows it owns are 761 * automatically removed from the tables. 762 * 763 * <p>Type: TEXT 764 */ 765 String COLUMN_PACKAGE_NAME = "package_name"; 766 } 767 768 /** 769 * Common columns for the tables of TV programs. 770 * @hide 771 */ 772 interface ProgramColumns { 773 /** @hide */ 774 @IntDef({ 775 REVIEW_RATING_STYLE_STARS, 776 REVIEW_RATING_STYLE_THUMBS_UP_DOWN, 777 REVIEW_RATING_STYLE_PERCENTAGE, 778 }) 779 @Retention(RetentionPolicy.SOURCE) 780 @interface ReviewRatingStyle {} 781 782 /** 783 * The review rating style for five star rating. 784 * 785 * @see #COLUMN_REVIEW_RATING_STYLE 786 */ 787 int REVIEW_RATING_STYLE_STARS = 0; 788 789 /** 790 * The review rating style for thumbs-up and thumbs-down rating. 791 * 792 * @see #COLUMN_REVIEW_RATING_STYLE 793 */ 794 int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; 795 796 /** 797 * The review rating style for 0 to 100 point system. 798 * 799 * @see #COLUMN_REVIEW_RATING_STYLE 800 */ 801 int REVIEW_RATING_STYLE_PERCENTAGE = 2; 802 803 /** 804 * The title of this TV program. 805 * 806 * <p>If this program is an episodic TV show, it is recommended that the title is the series 807 * title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or 808 * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_SEASON_DISPLAY_NUMBER}, 809 * {@link #COLUMN_EPISODE_DISPLAY_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in. 810 * 811 * <p>Type: TEXT 812 */ 813 String COLUMN_TITLE = "title"; 814 815 /** 816 * The season display number of this TV program for episodic TV shows. 817 * 818 * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value 819 * does not necessarily be numeric. (e.g. 12B) 820 * 821 * <p>Can be empty. 822 * 823 * <p>Type: TEXT 824 */ 825 String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number"; 826 827 /** 828 * The title of the season for this TV program for episodic TV shows. 829 * 830 * <p>This is an optional field supplied only when the season has a special title 831 * (e.g. The Final Season). If provided, the applications should display it instead of 832 * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, and should display it without alterations. 833 * (e.g. for "The Final Season", displayed string should be "The Final Season", not 834 * "Season The Final Season"). When displaying multiple programs, the order should be based 835 * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists. 836 * 837 * <p>Can be empty. 838 * 839 * <p>Type: TEXT 840 */ 841 String COLUMN_SEASON_TITLE = "season_title"; 842 843 /** 844 * The episode display number of this TV program for episodic TV shows. 845 * 846 * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value 847 * does not necessarily be numeric. (e.g. 12B) 848 * 849 * <p>Can be empty. 850 * 851 * <p>Type: TEXT 852 */ 853 String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number"; 854 855 /** 856 * The episode title of this TV program for episodic TV shows. 857 * 858 * <p>Can be empty. 859 * 860 * <p>Type: TEXT 861 */ 862 String COLUMN_EPISODE_TITLE = "episode_title"; 863 864 /** 865 * The comma-separated canonical genre string of this TV program. 866 * 867 * <p>Canonical genres are defined in {@link Genres}. Use {@link Genres#encode} to create a 868 * text that can be stored in this column. Use {@link Genres#decode} to get the canonical 869 * genre strings from the text stored in the column. 870 * 871 * <p>Type: TEXT 872 * @see Genres 873 * @see Genres#encode 874 * @see Genres#decode 875 */ 876 String COLUMN_CANONICAL_GENRE = "canonical_genre"; 877 878 /** 879 * The short description of this TV program that is displayed to the user by default. 880 * 881 * <p>It is recommended to limit the length of the descriptions to 256 characters. 882 * 883 * <p>Type: TEXT 884 */ 885 String COLUMN_SHORT_DESCRIPTION = "short_description"; 886 887 /** 888 * The detailed, lengthy description of this TV program that is displayed only when the user 889 * wants to see more information. 890 * 891 * <p>TV input services should leave this field empty if they have no additional details 892 * beyond {@link #COLUMN_SHORT_DESCRIPTION}. 893 * 894 * <p>Type: TEXT 895 */ 896 String COLUMN_LONG_DESCRIPTION = "long_description"; 897 898 /** 899 * The width of the video for this TV program, in the unit of pixels. 900 * 901 * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video 902 * resolution of the current TV program. Can be empty if it is not known initially or the 903 * program does not convey any video such as the programs from type 904 * {@link Channels#SERVICE_TYPE_AUDIO} channels. 905 * 906 * <p>Type: INTEGER 907 */ 908 String COLUMN_VIDEO_WIDTH = "video_width"; 909 910 /** 911 * The height of the video for this TV program, in the unit of pixels. 912 * 913 * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video 914 * resolution of the current TV program. Can be empty if it is not known initially or the 915 * program does not convey any video such as the programs from type 916 * {@link Channels#SERVICE_TYPE_AUDIO} channels. 917 * 918 * <p>Type: INTEGER 919 */ 920 String COLUMN_VIDEO_HEIGHT = "video_height"; 921 922 /** 923 * The comma-separated audio languages of this TV program. 924 * 925 * <p>This is used to describe available audio languages included in the program. Use either 926 * ISO 639-1 or 639-2/T codes. 927 * 928 * <p>Type: TEXT 929 */ 930 String COLUMN_AUDIO_LANGUAGE = "audio_language"; 931 932 /** 933 * The comma-separated content ratings of this TV program. 934 * 935 * <p>This is used to describe the content rating(s) of this program. Each comma-separated 936 * content rating sub-string should be generated by calling 937 * {@link TvContentRating#flattenToString}. Note that in most cases the program content is 938 * rated by a single rating system, thus resulting in a corresponding single sub-string that 939 * does not require comma separation and multiple sub-strings appear only when the program 940 * content is rated by two or more content rating systems. If any of those ratings is 941 * specified as "blocked rating" in the user's parental control settings, the TV input 942 * service should block the current content and wait for the signal that it is okay to 943 * unblock. 944 * 945 * <p>Type: TEXT 946 */ 947 String COLUMN_CONTENT_RATING = "content_rating"; 948 949 /** 950 * The URI for the poster art of this TV program. 951 * 952 * <p>The data in the column must be a URL, or a URI in one of the following formats: 953 * 954 * <ul> 955 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 956 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 957 * </li> 958 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 959 * </ul> 960 * 961 * <p>Can be empty. 962 * 963 * <p>Type: TEXT 964 */ 965 String COLUMN_POSTER_ART_URI = "poster_art_uri"; 966 967 /** 968 * The URI for the thumbnail of this TV program. 969 * 970 * <p>The system can generate a thumbnail from the poster art if this column is not 971 * specified. Thus it is not necessary for TV input services to include a thumbnail if it is 972 * just a scaled image of the poster art. 973 * 974 * <p>The data in the column must be a URL, or a URI in one of the following formats: 975 * 976 * <ul> 977 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 978 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 979 * </li> 980 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 981 * </ul> 982 * 983 * <p>Can be empty. 984 * 985 * <p>Type: TEXT 986 */ 987 String COLUMN_THUMBNAIL_URI = "thumbnail_uri"; 988 989 /** 990 * The flag indicating whether this TV program is searchable or not. 991 * 992 * <p>The columns of searchable programs can be read by other applications that have proper 993 * permission. Care must be taken not to open sensitive data. 994 * 995 * <p>A value of 1 indicates that the program is searchable and its columns can be read by 996 * other applications, a value of 0 indicates that the program is hidden and its columns can 997 * be read only by the package that owns the program and the system. If not specified, this 998 * value is set to 1 (searchable) by default. 999 * 1000 * <p>Type: INTEGER (boolean) 1001 */ 1002 String COLUMN_SEARCHABLE = "searchable"; 1003 1004 /** 1005 * Internal data used by individual TV input services. 1006 * 1007 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1008 * apps. 1009 * 1010 * <p>Type: BLOB 1011 */ 1012 String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 1013 1014 /** 1015 * Internal integer flag used by individual TV input services. 1016 * 1017 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1018 * apps. 1019 * 1020 * <p>Type: INTEGER 1021 */ 1022 String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 1023 1024 /** 1025 * Internal integer flag used by individual TV input services. 1026 * 1027 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1028 * apps. 1029 * 1030 * <p>Type: INTEGER 1031 */ 1032 String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 1033 1034 /** 1035 * Internal integer flag used by individual TV input services. 1036 * 1037 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1038 * apps. 1039 * 1040 * <p>Type: INTEGER 1041 */ 1042 String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 1043 1044 /** 1045 * Internal integer flag used by individual TV input services. 1046 * 1047 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1048 * apps. 1049 * 1050 * <p>Type: INTEGER 1051 */ 1052 String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 1053 1054 /** 1055 * The version number of this row entry used by TV input services. 1056 * 1057 * <p>This is best used by sync adapters to identify the rows to update. The number can be 1058 * defined by individual TV input services. One may assign the same value as 1059 * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV 1060 * broadcast. 1061 * 1062 * <p>Type: INTEGER 1063 */ 1064 String COLUMN_VERSION_NUMBER = "version_number"; 1065 1066 /** 1067 * The review rating score style used for {@link #COLUMN_REVIEW_RATING}. 1068 * 1069 * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS}, 1070 * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}. 1071 * 1072 * <p>Type: INTEGER 1073 * @see #COLUMN_REVIEW_RATING 1074 */ 1075 String COLUMN_REVIEW_RATING_STYLE = "review_rating_style"; 1076 1077 /** 1078 * The review rating score for this program. 1079 * 1080 * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the 1081 * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between 1082 * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, 1083 * the value should be two integers, one for thumbs-up count and the other for thumbs-down 1084 * count, with a comma between them. (e.g. "200,40") If the style is 1085 * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and 1086 * 100. (e.g. "99.9") 1087 * 1088 * <p>Type: TEXT 1089 * @see #COLUMN_REVIEW_RATING_STYLE 1090 */ 1091 String COLUMN_REVIEW_RATING = "review_rating"; 1092 } 1093 1094 /** 1095 * Common columns for the tables of preview programs. 1096 * @hide 1097 */ 1098 interface PreviewProgramColumns { 1099 1100 /** @hide */ 1101 @IntDef({ 1102 TYPE_MOVIE, 1103 TYPE_TV_SERIES, 1104 TYPE_TV_SEASON, 1105 TYPE_TV_EPISODE, 1106 TYPE_CLIP, 1107 TYPE_EVENT, 1108 TYPE_CHANNEL, 1109 TYPE_TRACK, 1110 TYPE_ALBUM, 1111 TYPE_ARTIST, 1112 TYPE_PLAYLIST, 1113 TYPE_STATION, 1114 }) 1115 @Retention(RetentionPolicy.SOURCE) 1116 public @interface Type {} 1117 1118 /** 1119 * The program type for movie. 1120 * 1121 * @see #COLUMN_TYPE 1122 */ 1123 int TYPE_MOVIE = 0; 1124 1125 /** 1126 * The program type for TV series. 1127 * 1128 * @see #COLUMN_TYPE 1129 */ 1130 int TYPE_TV_SERIES = 1; 1131 1132 /** 1133 * The program type for TV season. 1134 * 1135 * @see #COLUMN_TYPE 1136 */ 1137 int TYPE_TV_SEASON = 2; 1138 1139 /** 1140 * The program type for TV episode. 1141 * 1142 * @see #COLUMN_TYPE 1143 */ 1144 int TYPE_TV_EPISODE = 3; 1145 1146 /** 1147 * The program type for clip. 1148 * 1149 * @see #COLUMN_TYPE 1150 */ 1151 int TYPE_CLIP = 4; 1152 1153 /** 1154 * The program type for event. 1155 * 1156 * @see #COLUMN_TYPE 1157 */ 1158 int TYPE_EVENT = 5; 1159 1160 /** 1161 * The program type for channel. 1162 * 1163 * @see #COLUMN_TYPE 1164 */ 1165 int TYPE_CHANNEL = 6; 1166 1167 /** 1168 * The program type for track. 1169 * 1170 * @see #COLUMN_TYPE 1171 */ 1172 int TYPE_TRACK = 7; 1173 1174 /** 1175 * The program type for album. 1176 * 1177 * @see #COLUMN_TYPE 1178 */ 1179 int TYPE_ALBUM = 8; 1180 1181 /** 1182 * The program type for artist. 1183 * 1184 * @see #COLUMN_TYPE 1185 */ 1186 int TYPE_ARTIST = 9; 1187 1188 /** 1189 * The program type for playlist. 1190 * 1191 * @see #COLUMN_TYPE 1192 */ 1193 int TYPE_PLAYLIST = 10; 1194 1195 /** 1196 * The program type for station. 1197 * 1198 * @see #COLUMN_TYPE 1199 */ 1200 int TYPE_STATION = 11; 1201 1202 /** @hide */ 1203 @IntDef({ 1204 ASPECT_RATIO_16_9, 1205 ASPECT_RATIO_3_2, 1206 ASPECT_RATIO_1_1, 1207 ASPECT_RATIO_2_3, 1208 ASPECT_RATIO_4_3, 1209 }) 1210 @Retention(RetentionPolicy.SOURCE) 1211 public @interface AspectRatio {} 1212 1213 /** 1214 * The aspect ratio for 16:9. 1215 * 1216 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1217 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1218 */ 1219 int ASPECT_RATIO_16_9 = 0; 1220 1221 /** 1222 * The aspect ratio for 3:2. 1223 * 1224 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1225 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1226 */ 1227 int ASPECT_RATIO_3_2 = 1; 1228 1229 /** 1230 * The aspect ratio for 4:3. 1231 * 1232 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1233 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1234 */ 1235 int ASPECT_RATIO_4_3 = 2; 1236 1237 /** 1238 * The aspect ratio for 1:1. 1239 * 1240 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1241 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1242 */ 1243 int ASPECT_RATIO_1_1 = 3; 1244 1245 /** 1246 * The aspect ratio for 2:3. 1247 * 1248 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1249 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1250 */ 1251 int ASPECT_RATIO_2_3 = 4; 1252 1253 /** @hide */ 1254 @IntDef({ 1255 AVAILABILITY_AVAILABLE, 1256 AVAILABILITY_FREE_WITH_SUBSCRIPTION, 1257 AVAILABILITY_PAID_CONTENT, 1258 }) 1259 @Retention(RetentionPolicy.SOURCE) 1260 public @interface Availability {} 1261 1262 /** 1263 * The availability for "available to this user". 1264 * 1265 * @see #COLUMN_AVAILABILITY 1266 */ 1267 int AVAILABILITY_AVAILABLE = 0; 1268 1269 /** 1270 * The availability for "free with subscription". 1271 * 1272 * @see #COLUMN_AVAILABILITY 1273 */ 1274 int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; 1275 1276 /** 1277 * The availability for "paid content, either to-own or rental 1278 * (user has not purchased/rented). 1279 * 1280 * @see #COLUMN_AVAILABILITY 1281 */ 1282 int AVAILABILITY_PAID_CONTENT = 2; 1283 1284 /** @hide */ 1285 @IntDef({ 1286 INTERACTION_TYPE_VIEWS, 1287 INTERACTION_TYPE_LISTENS, 1288 INTERACTION_TYPE_FOLLOWERS, 1289 INTERACTION_TYPE_FANS, 1290 INTERACTION_TYPE_LIKES, 1291 INTERACTION_TYPE_THUMBS, 1292 INTERACTION_TYPE_VIEWERS, 1293 }) 1294 @Retention(RetentionPolicy.SOURCE) 1295 public @interface InteractionType {} 1296 1297 /** 1298 * The interaction type for "views". 1299 * 1300 * @see #COLUMN_INTERACTION_TYPE 1301 */ 1302 int INTERACTION_TYPE_VIEWS = 0; 1303 1304 /** 1305 * The interaction type for "listens". 1306 * 1307 * @see #COLUMN_INTERACTION_TYPE 1308 */ 1309 int INTERACTION_TYPE_LISTENS = 1; 1310 1311 /** 1312 * The interaction type for "followers". 1313 * 1314 * @see #COLUMN_INTERACTION_TYPE 1315 */ 1316 int INTERACTION_TYPE_FOLLOWERS = 2; 1317 1318 /** 1319 * The interaction type for "fans". 1320 * 1321 * @see #COLUMN_INTERACTION_TYPE 1322 */ 1323 int INTERACTION_TYPE_FANS = 3; 1324 1325 /** 1326 * The interaction type for "likes". 1327 * 1328 * @see #COLUMN_INTERACTION_TYPE 1329 */ 1330 int INTERACTION_TYPE_LIKES = 4; 1331 1332 /** 1333 * The interaction type for "thumbs". 1334 * 1335 * @see #COLUMN_INTERACTION_TYPE 1336 */ 1337 int INTERACTION_TYPE_THUMBS = 5; 1338 1339 /** 1340 * The interaction type for "viewers". 1341 * 1342 * @see #COLUMN_INTERACTION_TYPE 1343 */ 1344 int INTERACTION_TYPE_VIEWERS = 6; 1345 1346 /** 1347 * The type of this program content. 1348 * 1349 * <p>The value should match one of the followings: 1350 * {@link #TYPE_MOVIE}, 1351 * {@link #TYPE_TV_SERIES}, 1352 * {@link #TYPE_TV_SEASON}, 1353 * {@link #TYPE_TV_EPISODE}, 1354 * {@link #TYPE_CLIP}, 1355 * {@link #TYPE_EVENT}, 1356 * {@link #TYPE_CHANNEL}, 1357 * {@link #TYPE_TRACK}, 1358 * {@link #TYPE_ALBUM}, 1359 * {@link #TYPE_ARTIST}, 1360 * {@link #TYPE_PLAYLIST}, and 1361 * {@link #TYPE_STATION}. 1362 * 1363 * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW} 1364 * channel. 1365 * 1366 * <p>Type: INTEGER 1367 */ 1368 String COLUMN_TYPE = "type"; 1369 1370 /** 1371 * The aspect ratio of the poster art for this TV program. 1372 * 1373 * <p>The value should match one of the followings: 1374 * {@link #ASPECT_RATIO_16_9}, 1375 * {@link #ASPECT_RATIO_3_2}, 1376 * {@link #ASPECT_RATIO_4_3}, 1377 * {@link #ASPECT_RATIO_1_1}, and 1378 * {@link #ASPECT_RATIO_2_3}. 1379 * 1380 * <p>Type: INTEGER 1381 */ 1382 String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio"; 1383 1384 /** 1385 * The aspect ratio of the thumbnail for this TV program. 1386 * 1387 * <p>The value should match one of the followings: 1388 * {@link #ASPECT_RATIO_16_9}, 1389 * {@link #ASPECT_RATIO_3_2}, 1390 * {@link #ASPECT_RATIO_4_3}, 1391 * {@link #ASPECT_RATIO_1_1}, and 1392 * {@link #ASPECT_RATIO_2_3}. 1393 * 1394 * <p>Type: INTEGER 1395 */ 1396 String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio"; 1397 1398 /** 1399 * The URI for the logo of this TV program. 1400 * 1401 * <p>This is a small badge shown on top of the poster art or thumbnail representing the 1402 * source of the content. 1403 * 1404 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1405 * 1406 * <ul> 1407 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1408 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1409 * </li> 1410 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1411 * </ul> 1412 * 1413 * <p>Can be empty. 1414 * 1415 * <p>Type: TEXT 1416 */ 1417 String COLUMN_LOGO_URI = "logo_uri"; 1418 1419 /** 1420 * The availability of this TV program. 1421 * 1422 * <p>The value should match one of the followings: 1423 * {@link #AVAILABILITY_AVAILABLE}, 1424 * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and 1425 * {@link #AVAILABILITY_PAID_CONTENT}. 1426 * 1427 * <p>Type: INTEGER 1428 */ 1429 String COLUMN_AVAILABILITY = "availability"; 1430 1431 /** 1432 * The starting price of this TV program. 1433 * 1434 * <p>This indicates the lowest regular acquisition cost of the content. It is only used 1435 * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}. 1436 * 1437 * <p>Type: TEXT 1438 * @see #COLUMN_OFFER_PRICE 1439 */ 1440 String COLUMN_STARTING_PRICE = "starting_price"; 1441 1442 /** 1443 * The offer price of this TV program. 1444 * 1445 * <p>This is the promotional cost of the content. It is only used if the availability of 1446 * the program is {@link #AVAILABILITY_PAID_CONTENT}. 1447 * 1448 * <p>Type: TEXT 1449 * @see #COLUMN_STARTING_PRICE 1450 */ 1451 String COLUMN_OFFER_PRICE = "offer_price"; 1452 1453 /** 1454 * The release date of this TV program. 1455 * 1456 * <p>The value should be in one of the following formats: 1457 * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601). 1458 * 1459 * <p>Type: TEXT 1460 */ 1461 String COLUMN_RELEASE_DATE = "release_date"; 1462 1463 /** 1464 * The count of the items included in this TV program. 1465 * 1466 * <p>This is only relevant if the program represents a collection of items such as series, 1467 * episodes, or music tracks. 1468 * 1469 * <p>Type: INTEGER 1470 */ 1471 String COLUMN_ITEM_COUNT = "item_count"; 1472 1473 /** 1474 * The flag indicating whether this TV program is live or not. 1475 * 1476 * <p>A value of 1 indicates that the content is airing and should be consumed now, a value 1477 * of 0 indicates that the content is off the air and does not need to be consumed at the 1478 * present time. If not specified, the value is set to 0 (not live) by default. 1479 * 1480 * <p>Type: INTEGER (boolean) 1481 */ 1482 String COLUMN_LIVE = "live"; 1483 1484 /** 1485 * The internal ID used by individual TV input services. 1486 * 1487 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1488 * apps. 1489 * 1490 * <p>Can be empty. 1491 * 1492 * <p>Type: TEXT 1493 */ 1494 String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id"; 1495 1496 /** 1497 * The URI for the preview video. 1498 * 1499 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1500 * 1501 * <ul> 1502 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1503 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1504 * </li> 1505 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1506 * </ul> 1507 * 1508 * <p>Can be empty. 1509 * 1510 * <p>Type: TEXT 1511 */ 1512 String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri"; 1513 1514 /** 1515 * The last playback position (in milliseconds) of the original content of this preview 1516 * program. 1517 * 1518 * <p>Can be empty. 1519 * 1520 * <p>Type: INTEGER 1521 */ 1522 String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = 1523 "last_playback_position_millis"; 1524 1525 /** 1526 * The duration (in milliseconds) of the original content of this preview program. 1527 * 1528 * <p>Can be empty. 1529 * 1530 * <p>Type: INTEGER 1531 */ 1532 String COLUMN_DURATION_MILLIS = "duration_millis"; 1533 1534 /** 1535 * The intent URI which is launched when the preview program is selected. 1536 * 1537 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 1538 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 1539 * launched when the user selects the preview program item. 1540 * 1541 * <p>Can be empty. 1542 * 1543 * <p>Type: TEXT 1544 */ 1545 String COLUMN_INTENT_URI = "intent_uri"; 1546 1547 /** 1548 * The flag indicating whether this program is transient or not. 1549 * 1550 * <p>A value of 1 indicates that the channel will be automatically removed by the system on 1551 * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not 1552 * specified, this value is set to 0 (not transient) by default. 1553 * 1554 * <p>Type: INTEGER (boolean) 1555 * @see Channels#COLUMN_TRANSIENT 1556 */ 1557 String COLUMN_TRANSIENT = "transient"; 1558 1559 /** 1560 * The type of interaction for this TV program. 1561 * 1562 * <p> The value should match one of the followings: 1563 * {@link #INTERACTION_TYPE_VIEWS}, 1564 * {@link #INTERACTION_TYPE_LISTENS}, 1565 * {@link #INTERACTION_TYPE_FOLLOWERS}, 1566 * {@link #INTERACTION_TYPE_FANS}, 1567 * {@link #INTERACTION_TYPE_LIKES}, 1568 * {@link #INTERACTION_TYPE_THUMBS}, and 1569 * {@link #INTERACTION_TYPE_VIEWERS}. 1570 * 1571 * <p>Type: INTEGER 1572 * @see #COLUMN_INTERACTION_COUNT 1573 */ 1574 String COLUMN_INTERACTION_TYPE = "interaction_type"; 1575 1576 /** 1577 * The interaction count for this program. 1578 * 1579 * <p>This indicates the number of times interaction has happened. 1580 * 1581 * <p>Type: INTEGER (long) 1582 * @see #COLUMN_INTERACTION_TYPE 1583 */ 1584 String COLUMN_INTERACTION_COUNT = "interaction_count"; 1585 1586 /** 1587 * The author or artist of this content. 1588 * 1589 * <p>Type: TEXT 1590 */ 1591 String COLUMN_AUTHOR = "author"; 1592 1593 /** 1594 * The flag indicating whether this TV program is browsable or not. 1595 * 1596 * <p>This column can only be set by applications having proper system permission. For 1597 * other applications, this is a read-only column. 1598 * 1599 * <p>A value of 1 indicates that the program is browsable and can be shown to users in 1600 * the UI. A value of 0 indicates that the program should be hidden from users and the 1601 * application who changes this value to 0 should send 1602 * {@link #ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED} to the owner of the program 1603 * to notify this change. 1604 * 1605 * <p>This value is set to 1 (browsable) by default. 1606 * 1607 * <p>Type: INTEGER (boolean) 1608 */ 1609 String COLUMN_BROWSABLE = "browsable"; 1610 1611 /** 1612 * The content ID of this TV program. 1613 * 1614 * <p>A public ID of the content which allows the application to apply the same operation to 1615 * all the program copies in different channels. 1616 * 1617 * <p>Can be empty. 1618 * 1619 * <p>Type: TEXT 1620 */ 1621 String COLUMN_CONTENT_ID = "content_id"; 1622 1623 } 1624 1625 /** Column definitions for the TV channels table. */ 1626 public static final class Channels implements BaseTvColumns { 1627 1628 /** 1629 * The content:// style URI for this table. 1630 * 1631 * <p>SQL selection is not supported for {@link ContentResolver#query}, 1632 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 1633 */ 1634 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 1635 + PATH_CHANNEL); 1636 1637 /** The MIME type of a directory of TV channels. */ 1638 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel"; 1639 1640 /** The MIME type of a single TV channel. */ 1641 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel"; 1642 1643 /** @hide */ 1644 @StringDef({ 1645 TYPE_OTHER, 1646 TYPE_NTSC, 1647 TYPE_PAL, 1648 TYPE_SECAM, 1649 TYPE_DVB_T, 1650 TYPE_DVB_T2, 1651 TYPE_DVB_S, 1652 TYPE_DVB_S2, 1653 TYPE_DVB_C, 1654 TYPE_DVB_C2, 1655 TYPE_DVB_H, 1656 TYPE_DVB_SH, 1657 TYPE_ATSC_T, 1658 TYPE_ATSC_C, 1659 TYPE_ATSC_M_H, 1660 TYPE_ISDB_T, 1661 TYPE_ISDB_TB, 1662 TYPE_ISDB_S, 1663 TYPE_ISDB_C, 1664 TYPE_1SEG, 1665 TYPE_DTMB, 1666 TYPE_CMMB, 1667 TYPE_T_DMB, 1668 TYPE_S_DMB, 1669 TYPE_PREVIEW, 1670 }) 1671 @Retention(RetentionPolicy.SOURCE) 1672 public @interface Type {} 1673 1674 /** 1675 * A generic channel type. 1676 * 1677 * Use this if the current channel is streaming-based or its broadcast system type does not 1678 * fit under any other types. This is the default channel type. 1679 * 1680 * @see #COLUMN_TYPE 1681 */ 1682 public static final String TYPE_OTHER = "TYPE_OTHER"; 1683 1684 /** 1685 * The channel type for NTSC. 1686 * 1687 * @see #COLUMN_TYPE 1688 */ 1689 public static final String TYPE_NTSC = "TYPE_NTSC"; 1690 1691 /** 1692 * The channel type for PAL. 1693 * 1694 * @see #COLUMN_TYPE 1695 */ 1696 public static final String TYPE_PAL = "TYPE_PAL"; 1697 1698 /** 1699 * The channel type for SECAM. 1700 * 1701 * @see #COLUMN_TYPE 1702 */ 1703 public static final String TYPE_SECAM = "TYPE_SECAM"; 1704 1705 /** 1706 * The channel type for DVB-T (terrestrial). 1707 * 1708 * @see #COLUMN_TYPE 1709 */ 1710 public static final String TYPE_DVB_T = "TYPE_DVB_T"; 1711 1712 /** 1713 * The channel type for DVB-T2 (terrestrial). 1714 * 1715 * @see #COLUMN_TYPE 1716 */ 1717 public static final String TYPE_DVB_T2 = "TYPE_DVB_T2"; 1718 1719 /** 1720 * The channel type for DVB-S (satellite). 1721 * 1722 * @see #COLUMN_TYPE 1723 */ 1724 public static final String TYPE_DVB_S = "TYPE_DVB_S"; 1725 1726 /** 1727 * The channel type for DVB-S2 (satellite). 1728 * 1729 * @see #COLUMN_TYPE 1730 */ 1731 public static final String TYPE_DVB_S2 = "TYPE_DVB_S2"; 1732 1733 /** 1734 * The channel type for DVB-C (cable). 1735 * 1736 * @see #COLUMN_TYPE 1737 */ 1738 public static final String TYPE_DVB_C = "TYPE_DVB_C"; 1739 1740 /** 1741 * The channel type for DVB-C2 (cable). 1742 * 1743 * @see #COLUMN_TYPE 1744 */ 1745 public static final String TYPE_DVB_C2 = "TYPE_DVB_C2"; 1746 1747 /** 1748 * The channel type for DVB-H (handheld). 1749 * 1750 * @see #COLUMN_TYPE 1751 */ 1752 public static final String TYPE_DVB_H = "TYPE_DVB_H"; 1753 1754 /** 1755 * The channel type for DVB-SH (satellite). 1756 * 1757 * @see #COLUMN_TYPE 1758 */ 1759 public static final String TYPE_DVB_SH = "TYPE_DVB_SH"; 1760 1761 /** 1762 * The channel type for ATSC (terrestrial). 1763 * 1764 * @see #COLUMN_TYPE 1765 */ 1766 public static final String TYPE_ATSC_T = "TYPE_ATSC_T"; 1767 1768 /** 1769 * The channel type for ATSC (cable). 1770 * 1771 * @see #COLUMN_TYPE 1772 */ 1773 public static final String TYPE_ATSC_C = "TYPE_ATSC_C"; 1774 1775 /** 1776 * The channel type for ATSC-M/H (mobile/handheld). 1777 * 1778 * @see #COLUMN_TYPE 1779 */ 1780 public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H"; 1781 1782 /** 1783 * The channel type for ISDB-T (terrestrial). 1784 * 1785 * @see #COLUMN_TYPE 1786 */ 1787 public static final String TYPE_ISDB_T = "TYPE_ISDB_T"; 1788 1789 /** 1790 * The channel type for ISDB-Tb (Brazil). 1791 * 1792 * @see #COLUMN_TYPE 1793 */ 1794 public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB"; 1795 1796 /** 1797 * The channel type for ISDB-S (satellite). 1798 * 1799 * @see #COLUMN_TYPE 1800 */ 1801 public static final String TYPE_ISDB_S = "TYPE_ISDB_S"; 1802 1803 /** 1804 * The channel type for ISDB-C (cable). 1805 * 1806 * @see #COLUMN_TYPE 1807 */ 1808 public static final String TYPE_ISDB_C = "TYPE_ISDB_C"; 1809 1810 /** 1811 * The channel type for 1seg (handheld). 1812 * 1813 * @see #COLUMN_TYPE 1814 */ 1815 public static final String TYPE_1SEG = "TYPE_1SEG"; 1816 1817 /** 1818 * The channel type for DTMB (terrestrial). 1819 * 1820 * @see #COLUMN_TYPE 1821 */ 1822 public static final String TYPE_DTMB = "TYPE_DTMB"; 1823 1824 /** 1825 * The channel type for CMMB (handheld). 1826 * 1827 * @see #COLUMN_TYPE 1828 */ 1829 public static final String TYPE_CMMB = "TYPE_CMMB"; 1830 1831 /** 1832 * The channel type for T-DMB (terrestrial). 1833 * 1834 * @see #COLUMN_TYPE 1835 */ 1836 public static final String TYPE_T_DMB = "TYPE_T_DMB"; 1837 1838 /** 1839 * The channel type for S-DMB (satellite). 1840 * 1841 * @see #COLUMN_TYPE 1842 */ 1843 public static final String TYPE_S_DMB = "TYPE_S_DMB"; 1844 1845 /** 1846 * The channel type for preview videos. 1847 * 1848 * <P>Unlike other broadcast TV channel types, the programs in the preview channel usually 1849 * are promotional videos. The UI may treat the preview channels differently from the other 1850 * broadcast channels. 1851 * 1852 * @see #COLUMN_TYPE 1853 */ 1854 public static final String TYPE_PREVIEW = "TYPE_PREVIEW"; 1855 1856 /** @hide */ 1857 @StringDef({ 1858 SERVICE_TYPE_OTHER, 1859 SERVICE_TYPE_AUDIO_VIDEO, 1860 SERVICE_TYPE_AUDIO, 1861 }) 1862 @Retention(RetentionPolicy.SOURCE) 1863 public @interface ServiceType {} 1864 1865 /** A generic service type. */ 1866 public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER"; 1867 1868 /** The service type for regular TV channels that have both audio and video. */ 1869 public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO"; 1870 1871 /** The service type for radio channels that have audio only. */ 1872 public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO"; 1873 1874 /** @hide */ 1875 @StringDef({ 1876 VIDEO_FORMAT_240P, 1877 VIDEO_FORMAT_360P, 1878 VIDEO_FORMAT_480I, 1879 VIDEO_FORMAT_576I, 1880 VIDEO_FORMAT_576P, 1881 VIDEO_FORMAT_720P, 1882 VIDEO_FORMAT_1080I, 1883 VIDEO_FORMAT_1080P, 1884 VIDEO_FORMAT_2160P, 1885 VIDEO_FORMAT_4320P, 1886 }) 1887 @Retention(RetentionPolicy.SOURCE) 1888 public @interface VideoFormat {} 1889 1890 /** The video format for 240p. */ 1891 public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P"; 1892 1893 /** The video format for 360p. */ 1894 public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P"; 1895 1896 /** The video format for 480i. */ 1897 public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I"; 1898 1899 /** The video format for 480p. */ 1900 public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P"; 1901 1902 /** The video format for 576i. */ 1903 public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I"; 1904 1905 /** The video format for 576p. */ 1906 public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P"; 1907 1908 /** The video format for 720p. */ 1909 public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P"; 1910 1911 /** The video format for 1080i. */ 1912 public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I"; 1913 1914 /** The video format for 1080p. */ 1915 public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P"; 1916 1917 /** The video format for 2160p. */ 1918 public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P"; 1919 1920 /** The video format for 4320p. */ 1921 public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P"; 1922 1923 /** @hide */ 1924 @StringDef({ 1925 VIDEO_RESOLUTION_SD, 1926 VIDEO_RESOLUTION_ED, 1927 VIDEO_RESOLUTION_HD, 1928 VIDEO_RESOLUTION_FHD, 1929 VIDEO_RESOLUTION_UHD, 1930 }) 1931 @Retention(RetentionPolicy.SOURCE) 1932 public @interface VideoResolution {} 1933 1934 /** The video resolution for standard-definition. */ 1935 public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD"; 1936 1937 /** The video resolution for enhanced-definition. */ 1938 public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED"; 1939 1940 /** The video resolution for high-definition. */ 1941 public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD"; 1942 1943 /** The video resolution for full high-definition. */ 1944 public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD"; 1945 1946 /** The video resolution for ultra high-definition. */ 1947 public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD"; 1948 1949 private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>(); 1950 1951 static { 1952 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD); 1953 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED); 1954 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD); 1955 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED); 1956 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD); 1957 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD); 1958 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD); 1959 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD); 1960 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD); 1961 } 1962 1963 /** 1964 * Returns the video resolution (definition) for a given video format. 1965 * 1966 * @param videoFormat The video format defined in {@link Channels}. 1967 * @return the corresponding video resolution string. {@code null} if the resolution string 1968 * is not defined for the given video format. 1969 * @see #COLUMN_VIDEO_FORMAT 1970 */ 1971 @Nullable 1972 public static final String getVideoResolution(@VideoFormat String videoFormat) { 1973 return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat); 1974 } 1975 1976 /** 1977 * The ID of the TV input service that provides this TV channel. 1978 * 1979 * <p>Use {@link #buildInputId} to build the ID. 1980 * 1981 * <p>This is a required field. 1982 * 1983 * <p>Type: TEXT 1984 */ 1985 public static final String COLUMN_INPUT_ID = "input_id"; 1986 1987 /** 1988 * The broadcast system type of this TV channel. 1989 * 1990 * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current 1991 * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the 1992 * default channel type. The value should match one of the followings: 1993 * {@link #TYPE_1SEG}, 1994 * {@link #TYPE_ATSC_C}, 1995 * {@link #TYPE_ATSC_M_H}, 1996 * {@link #TYPE_ATSC_T}, 1997 * {@link #TYPE_CMMB}, 1998 * {@link #TYPE_DTMB}, 1999 * {@link #TYPE_DVB_C}, 2000 * {@link #TYPE_DVB_C2}, 2001 * {@link #TYPE_DVB_H}, 2002 * {@link #TYPE_DVB_S}, 2003 * {@link #TYPE_DVB_S2}, 2004 * {@link #TYPE_DVB_SH}, 2005 * {@link #TYPE_DVB_T}, 2006 * {@link #TYPE_DVB_T2}, 2007 * {@link #TYPE_ISDB_C}, 2008 * {@link #TYPE_ISDB_S}, 2009 * {@link #TYPE_ISDB_T}, 2010 * {@link #TYPE_ISDB_TB}, 2011 * {@link #TYPE_NTSC}, 2012 * {@link #TYPE_OTHER}, 2013 * {@link #TYPE_PAL}, 2014 * {@link #TYPE_SECAM}, 2015 * {@link #TYPE_S_DMB}, 2016 * {@link #TYPE_T_DMB}, and 2017 * {@link #TYPE_PREVIEW}. 2018 * 2019 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2020 * fail. 2021 * 2022 * <p>This is a required field. 2023 * 2024 * <p>Type: TEXT 2025 */ 2026 public static final String COLUMN_TYPE = "type"; 2027 2028 /** 2029 * The predefined service type of this TV channel. 2030 * 2031 * <p>This is primarily used to indicate whether the current channel is a regular TV channel 2032 * or a radio-like channel. Use the same coding for {@code service_type} in the underlying 2033 * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB 2034 * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER}, 2035 * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO} 2036 * 2037 * <p>This is a required field. 2038 * 2039 * <p>Type: TEXT 2040 */ 2041 public static final String COLUMN_SERVICE_TYPE = "service_type"; 2042 2043 /** 2044 * The original network ID of this TV channel. 2045 * 2046 * <p>It is used to identify the originating delivery system, if applicable. Use the same 2047 * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10. 2048 * 2049 * <p>This is a required field only if the underlying broadcast standard defines the same 2050 * name field. Otherwise, leave empty. 2051 * 2052 * <p>Type: INTEGER 2053 */ 2054 public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; 2055 2056 /** 2057 * The transport stream ID of this channel. 2058 * 2059 * <p>It is used to identify the Transport Stream that contains the current channel from any 2060 * other multiplex within a network, if applicable. Use the same coding for 2061 * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via 2062 * the MPEG Transport Stream. 2063 * 2064 * <p>This is a required field only if the current channel is transmitted via the MPEG 2065 * Transport Stream. Leave empty otherwise. 2066 * 2067 * <p>Type: INTEGER 2068 */ 2069 public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; 2070 2071 /** 2072 * The service ID of this channel. 2073 * 2074 * <p>It is used to identify the current service, or channel from any other services within 2075 * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in 2076 * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1. 2077 * 2078 * <p>This is a required field only if the underlying broadcast standard defines the same 2079 * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave 2080 * empty otherwise. 2081 * 2082 * <p>Type: INTEGER 2083 */ 2084 public static final String COLUMN_SERVICE_ID = "service_id"; 2085 2086 /** 2087 * The channel number that is displayed to the user. 2088 * 2089 * <p>The format can vary depending on broadcast standard and product specification. 2090 * 2091 * <p>Type: TEXT 2092 */ 2093 public static final String COLUMN_DISPLAY_NUMBER = "display_number"; 2094 2095 /** 2096 * The channel name that is displayed to the user. 2097 * 2098 * <p>A call sign is a good candidate to use for this purpose but any name that helps the 2099 * user recognize the current channel will be enough. Can also be empty depending on 2100 * broadcast standard. 2101 * 2102 * <p> Type: TEXT 2103 */ 2104 public static final String COLUMN_DISPLAY_NAME = "display_name"; 2105 2106 /** 2107 * The network affiliation for this TV channel. 2108 * 2109 * <p>This is used to identify a channel that is commonly called by its network affiliation 2110 * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the 2111 * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable. 2112 * 2113 * <p>Type: TEXT 2114 */ 2115 public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation"; 2116 2117 /** 2118 * The description of this TV channel. 2119 * 2120 * <p>Can be empty initially. 2121 * 2122 * <p>Type: TEXT 2123 */ 2124 public static final String COLUMN_DESCRIPTION = "description"; 2125 2126 /** 2127 * The typical video format for programs from this TV channel. 2128 * 2129 * <p>This is primarily used to filter out channels based on video format by applications. 2130 * The value should match one of the followings: {@link #VIDEO_FORMAT_240P}, 2131 * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P}, 2132 * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P}, 2133 * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P}, 2134 * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a 2135 * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and 2136 * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution. 2137 * 2138 * <p>Type: TEXT 2139 * 2140 * @see #getVideoResolution 2141 */ 2142 public static final String COLUMN_VIDEO_FORMAT = "video_format"; 2143 2144 /** 2145 * The flag indicating whether this TV channel is browsable or not. 2146 * 2147 * <p>This column can only be set by applications having proper system permission. For 2148 * other applications, this is a read-only column. 2149 * 2150 * <p>A value of 1 indicates the channel is included in the channel list that applications 2151 * use to browse channels, a value of 0 indicates the channel is not included in the list. 2152 * If not specified, this value is set to 0 (not browsable) by default. 2153 * 2154 * <p>Type: INTEGER (boolean) 2155 */ 2156 public static final String COLUMN_BROWSABLE = "browsable"; 2157 2158 /** 2159 * The flag indicating whether this TV channel is searchable or not. 2160 * 2161 * <p>The columns of searchable channels can be read by other applications that have proper 2162 * permission. Care must be taken not to open sensitive data. 2163 * 2164 * <p>A value of 1 indicates that the channel is searchable and its columns can be read by 2165 * other applications, a value of 0 indicates that the channel is hidden and its columns can 2166 * be read only by the package that owns the channel and the system. If not specified, this 2167 * value is set to 1 (searchable) by default. 2168 * 2169 * <p>Type: INTEGER (boolean) 2170 */ 2171 public static final String COLUMN_SEARCHABLE = "searchable"; 2172 2173 /** 2174 * The flag indicating whether this TV channel is locked or not. 2175 * 2176 * <p>This is primarily used for alternative parental control to prevent unauthorized users 2177 * from watching the current channel regardless of the content rating. A value of 1 2178 * indicates the channel is locked and the user is required to enter passcode to unlock it 2179 * in order to watch the current program from the channel, a value of 0 indicates the 2180 * channel is not locked thus the user is not prompted to enter passcode If not specified, 2181 * this value is set to 0 (not locked) by default. 2182 * 2183 * <p>This column can only be set by applications having proper system permission to 2184 * modify parental control settings. For other applications, this is a read-only column. 2185 2186 * <p>Type: INTEGER (boolean) 2187 */ 2188 public static final String COLUMN_LOCKED = "locked"; 2189 2190 /** 2191 * The URI for the app badge icon of the app link template for this channel. 2192 * 2193 * <p>This small icon is overlaid at the bottom of the poster art specified by 2194 * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of 2195 * the following formats: 2196 * 2197 * <ul> 2198 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2199 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2200 * </li> 2201 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2202 * </ul> 2203 * 2204 * <p>The app-linking allows channel input sources to provide activity links from their live 2205 * channel programming to another activity. This enables content providers to increase user 2206 * engagement by offering the viewer other content or actions. 2207 * 2208 * <p>Type: TEXT 2209 * @see #COLUMN_APP_LINK_COLOR 2210 * @see #COLUMN_APP_LINK_INTENT_URI 2211 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2212 * @see #COLUMN_APP_LINK_TEXT 2213 */ 2214 public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri"; 2215 2216 /** 2217 * The URI for the poster art used as the background of the app link template for this 2218 * channel. 2219 * 2220 * <p>The data in the column must be a URL, or a URI in one of the following formats: 2221 * 2222 * <ul> 2223 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2224 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2225 * </li> 2226 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2227 * </ul> 2228 * 2229 * <p>The app-linking allows channel input sources to provide activity links from their live 2230 * channel programming to another activity. This enables content providers to increase user 2231 * engagement by offering the viewer other content or actions. 2232 * 2233 * <p>Type: TEXT 2234 * @see #COLUMN_APP_LINK_COLOR 2235 * @see #COLUMN_APP_LINK_ICON_URI 2236 * @see #COLUMN_APP_LINK_INTENT_URI 2237 * @see #COLUMN_APP_LINK_TEXT 2238 */ 2239 public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri"; 2240 2241 /** 2242 * The link text of the app link template for this channel. 2243 * 2244 * <p>This provides a short description of the action that happens when the corresponding 2245 * app link is clicked. 2246 * 2247 * <p>The app-linking allows channel input sources to provide activity links from their live 2248 * channel programming to another activity. This enables content providers to increase user 2249 * engagement by offering the viewer other content or actions. 2250 * 2251 * <p>Type: TEXT 2252 * @see #COLUMN_APP_LINK_COLOR 2253 * @see #COLUMN_APP_LINK_ICON_URI 2254 * @see #COLUMN_APP_LINK_INTENT_URI 2255 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2256 */ 2257 public static final String COLUMN_APP_LINK_TEXT = "app_link_text"; 2258 2259 /** 2260 * The accent color of the app link template for this channel. This is primarily used for 2261 * the background color of the text box in the template. 2262 * 2263 * <p>The app-linking allows channel input sources to provide activity links from their live 2264 * channel programming to another activity. This enables content providers to increase user 2265 * engagement by offering the viewer other content or actions. 2266 * 2267 * <p>Type: INTEGER (color value) 2268 * @see #COLUMN_APP_LINK_ICON_URI 2269 * @see #COLUMN_APP_LINK_INTENT_URI 2270 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2271 * @see #COLUMN_APP_LINK_TEXT 2272 */ 2273 public static final String COLUMN_APP_LINK_COLOR = "app_link_color"; 2274 2275 /** 2276 * The intent URI of the app link for this channel. 2277 * 2278 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 2279 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 2280 * launched when the user clicks the corresponding app link for the current channel. 2281 * 2282 * <p>The app-linking allows channel input sources to provide activity links from their live 2283 * channel programming to another activity. This enables content providers to increase user 2284 * engagement by offering the viewer other content or actions. 2285 * 2286 * <p>Type: TEXT 2287 * @see #COLUMN_APP_LINK_COLOR 2288 * @see #COLUMN_APP_LINK_ICON_URI 2289 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2290 * @see #COLUMN_APP_LINK_TEXT 2291 */ 2292 public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri"; 2293 2294 /** 2295 * The internal ID used by individual TV input services. 2296 * 2297 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2298 * apps. 2299 * 2300 * <p>Can be empty. 2301 * 2302 * <p>Type: TEXT 2303 */ 2304 public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id"; 2305 2306 /** 2307 * Internal data used by individual TV input services. 2308 * 2309 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2310 * apps. 2311 * 2312 * <p>Type: BLOB 2313 */ 2314 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 2315 2316 /** 2317 * Internal integer flag used by individual TV input services. 2318 * 2319 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2320 * apps. 2321 * 2322 * <p>Type: INTEGER 2323 */ 2324 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 2325 2326 /** 2327 * Internal integer flag used by individual TV input services. 2328 * 2329 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2330 * apps. 2331 * 2332 * <p>Type: INTEGER 2333 */ 2334 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 2335 2336 /** 2337 * Internal integer flag used by individual TV input services. 2338 * 2339 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2340 * apps. 2341 * 2342 * <p>Type: INTEGER 2343 */ 2344 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 2345 2346 /** 2347 * Internal integer flag used by individual TV input services. 2348 * 2349 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2350 * apps. 2351 * 2352 * <p>Type: INTEGER 2353 */ 2354 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 2355 2356 /** 2357 * The version number of this row entry used by TV input services. 2358 * 2359 * <p>This is best used by sync adapters to identify the rows to update. The number can be 2360 * defined by individual TV input services. One may assign the same value as 2361 * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are 2362 * coming from a TV broadcast. 2363 * 2364 * <p>Type: INTEGER 2365 */ 2366 public static final String COLUMN_VERSION_NUMBER = "version_number"; 2367 2368 /** 2369 * The flag indicating whether this TV channel is transient or not. 2370 * 2371 * <p>A value of 1 indicates that the channel will be automatically removed by the system on 2372 * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not 2373 * specified, this value is set to 0 (not transient) by default. 2374 * 2375 * <p>Type: INTEGER (boolean) 2376 * @see PreviewPrograms#COLUMN_TRANSIENT 2377 * @see WatchNextPrograms#COLUMN_TRANSIENT 2378 */ 2379 public static final String COLUMN_TRANSIENT = "transient"; 2380 2381 private Channels() {} 2382 2383 /** 2384 * A sub-directory of a single TV channel that represents its primary logo. 2385 * 2386 * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw 2387 * channel URI. The resulting URI represents an image file, and should be interacted 2388 * using ContentResolver.openAssetFileDescriptor. 2389 * 2390 * <p>Note that this sub-directory also supports opening the logo as an asset file in write 2391 * mode. Callers can create or replace the primary logo associated with this channel by 2392 * opening the asset file and writing the full-size photo contents into it. (Make sure there 2393 * is no padding around the logo image.) When the file is closed, the image will be parsed, 2394 * sized down if necessary, and stored. 2395 * 2396 * <p>Usage example: 2397 * <pre> 2398 * public void writeChannelLogo(long channelId, byte[] logo) { 2399 * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId); 2400 * try { 2401 * AssetFileDescriptor fd = 2402 * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw"); 2403 * OutputStream os = fd.createOutputStream(); 2404 * os.write(logo); 2405 * os.close(); 2406 * fd.close(); 2407 * } catch (IOException e) { 2408 * // Handle error cases. 2409 * } 2410 * } 2411 * </pre> 2412 */ 2413 public static final class Logo { 2414 2415 /** 2416 * The directory twig for this sub-table. 2417 */ 2418 public static final String CONTENT_DIRECTORY = "logo"; 2419 2420 private Logo() {} 2421 } 2422 } 2423 2424 /** 2425 * Column definitions for the TV programs table. 2426 * 2427 * <p>By default, the query results will be sorted by 2428 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order. 2429 */ 2430 public static final class Programs implements BaseTvColumns, ProgramColumns { 2431 2432 /** 2433 * The content:// style URI for this table. 2434 * 2435 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2436 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2437 */ 2438 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2439 + PATH_PROGRAM); 2440 2441 /** The MIME type of a directory of TV programs. */ 2442 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program"; 2443 2444 /** The MIME type of a single TV program. */ 2445 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program"; 2446 2447 /** 2448 * The ID of the TV channel that provides this TV program. 2449 * 2450 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2451 * 2452 * <p>This is a required field. 2453 * 2454 * <p>Type: INTEGER (long) 2455 */ 2456 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2457 2458 /** 2459 * The season number of this TV program for episodic TV shows. 2460 * 2461 * <p>Can be empty. 2462 * 2463 * <p>Type: INTEGER 2464 * 2465 * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead. 2466 */ 2467 @Deprecated 2468 public static final String COLUMN_SEASON_NUMBER = "season_number"; 2469 2470 /** 2471 * The episode number of this TV program for episodic TV shows. 2472 * 2473 * <p>Can be empty. 2474 * 2475 * <p>Type: INTEGER 2476 * 2477 * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead. 2478 */ 2479 @Deprecated 2480 public static final String COLUMN_EPISODE_NUMBER = "episode_number"; 2481 2482 /** 2483 * The start time of this TV program, in milliseconds since the epoch. 2484 * 2485 * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the 2486 * previous program in the same channel. In practice, start time will usually be the end 2487 * time of the previous program. 2488 * 2489 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2490 * 2491 * <p>Type: INTEGER (long) 2492 */ 2493 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 2494 2495 /** 2496 * The end time of this TV program, in milliseconds since the epoch. 2497 * 2498 * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the 2499 * next program in the same channel. In practice, end time will usually be the start time of 2500 * the next program. 2501 * 2502 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2503 * 2504 * <p>Type: INTEGER (long) 2505 */ 2506 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 2507 2508 /** 2509 * The comma-separated genre string of this TV program. 2510 * 2511 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2512 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2513 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2514 * {@link Genres#encode} to create a text that can be stored in this column. Use 2515 * {@link Genres#decode} to get the broadcast genre strings from the text stored in the 2516 * column. 2517 * 2518 * <p>Type: TEXT 2519 * @see Genres#encode 2520 * @see Genres#decode 2521 */ 2522 public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre"; 2523 2524 /** 2525 * The flag indicating whether recording of this program is prohibited. 2526 * 2527 * <p>A value of 1 indicates that recording of this program is prohibited and application 2528 * will not schedule any recording for this program. A value of 0 indicates that the 2529 * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by 2530 * default. 2531 * 2532 * <p>Type: INTEGER (boolean) 2533 */ 2534 public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited"; 2535 2536 private Programs() {} 2537 2538 /** Canonical genres for TV programs. */ 2539 public static final class Genres { 2540 /** @hide */ 2541 @StringDef({ 2542 FAMILY_KIDS, 2543 SPORTS, 2544 SHOPPING, 2545 MOVIES, 2546 COMEDY, 2547 TRAVEL, 2548 DRAMA, 2549 EDUCATION, 2550 ANIMAL_WILDLIFE, 2551 NEWS, 2552 GAMING, 2553 ARTS, 2554 ENTERTAINMENT, 2555 LIFE_STYLE, 2556 MUSIC, 2557 PREMIER, 2558 TECH_SCIENCE, 2559 }) 2560 @Retention(RetentionPolicy.SOURCE) 2561 public @interface Genre {} 2562 2563 /** The genre for Family/Kids. */ 2564 public static final String FAMILY_KIDS = "FAMILY_KIDS"; 2565 2566 /** The genre for Sports. */ 2567 public static final String SPORTS = "SPORTS"; 2568 2569 /** The genre for Shopping. */ 2570 public static final String SHOPPING = "SHOPPING"; 2571 2572 /** The genre for Movies. */ 2573 public static final String MOVIES = "MOVIES"; 2574 2575 /** The genre for Comedy. */ 2576 public static final String COMEDY = "COMEDY"; 2577 2578 /** The genre for Travel. */ 2579 public static final String TRAVEL = "TRAVEL"; 2580 2581 /** The genre for Drama. */ 2582 public static final String DRAMA = "DRAMA"; 2583 2584 /** The genre for Education. */ 2585 public static final String EDUCATION = "EDUCATION"; 2586 2587 /** The genre for Animal/Wildlife. */ 2588 public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE"; 2589 2590 /** The genre for News. */ 2591 public static final String NEWS = "NEWS"; 2592 2593 /** The genre for Gaming. */ 2594 public static final String GAMING = "GAMING"; 2595 2596 /** The genre for Arts. */ 2597 public static final String ARTS = "ARTS"; 2598 2599 /** The genre for Entertainment. */ 2600 public static final String ENTERTAINMENT = "ENTERTAINMENT"; 2601 2602 /** The genre for Life Style. */ 2603 public static final String LIFE_STYLE = "LIFE_STYLE"; 2604 2605 /** The genre for Music. */ 2606 public static final String MUSIC = "MUSIC"; 2607 2608 /** The genre for Premier. */ 2609 public static final String PREMIER = "PREMIER"; 2610 2611 /** The genre for Tech/Science. */ 2612 public static final String TECH_SCIENCE = "TECH_SCIENCE"; 2613 2614 private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>(); 2615 static { 2616 CANONICAL_GENRES.add(FAMILY_KIDS); 2617 CANONICAL_GENRES.add(SPORTS); 2618 CANONICAL_GENRES.add(SHOPPING); 2619 CANONICAL_GENRES.add(MOVIES); 2620 CANONICAL_GENRES.add(COMEDY); 2621 CANONICAL_GENRES.add(TRAVEL); 2622 CANONICAL_GENRES.add(DRAMA); 2623 CANONICAL_GENRES.add(EDUCATION); 2624 CANONICAL_GENRES.add(ANIMAL_WILDLIFE); 2625 CANONICAL_GENRES.add(NEWS); 2626 CANONICAL_GENRES.add(GAMING); 2627 CANONICAL_GENRES.add(ARTS); 2628 CANONICAL_GENRES.add(ENTERTAINMENT); 2629 CANONICAL_GENRES.add(LIFE_STYLE); 2630 CANONICAL_GENRES.add(MUSIC); 2631 CANONICAL_GENRES.add(PREMIER); 2632 CANONICAL_GENRES.add(TECH_SCIENCE); 2633 } 2634 2635 private static final char DOUBLE_QUOTE = '"'; 2636 private static final char COMMA = ','; 2637 private static final String DELIMITER = ","; 2638 2639 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 2640 2641 private Genres() {} 2642 2643 /** 2644 * Encodes genre strings to a text that can be put into the database. 2645 * 2646 * @param genres Genre strings. 2647 * @return an encoded genre string that can be inserted into the 2648 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2649 */ 2650 public static String encode(@NonNull @Genre String... genres) { 2651 if (genres == null) { 2652 // MNC and before will throw a NPE. 2653 return null; 2654 } 2655 StringBuilder sb = new StringBuilder(); 2656 String separator = ""; 2657 for (String genre : genres) { 2658 sb.append(separator).append(encodeToCsv(genre)); 2659 separator = DELIMITER; 2660 } 2661 return sb.toString(); 2662 } 2663 2664 private static String encodeToCsv(String genre) { 2665 StringBuilder sb = new StringBuilder(); 2666 int length = genre.length(); 2667 for (int i = 0; i < length; ++i) { 2668 char c = genre.charAt(i); 2669 switch (c) { 2670 case DOUBLE_QUOTE: 2671 sb.append(DOUBLE_QUOTE); 2672 break; 2673 case COMMA: 2674 sb.append(DOUBLE_QUOTE); 2675 break; 2676 } 2677 sb.append(c); 2678 } 2679 return sb.toString(); 2680 } 2681 2682 /** 2683 * Decodes the genre strings from the text stored in the database. 2684 * 2685 * @param genres The encoded genre string retrieved from the 2686 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2687 * @return genre strings. 2688 */ 2689 public static @Genre String[] decode(@NonNull String genres) { 2690 if (TextUtils.isEmpty(genres)) { 2691 // MNC and before will throw a NPE for {@code null} genres. 2692 return EMPTY_STRING_ARRAY; 2693 } 2694 if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) { 2695 return new String[] {genres.trim()}; 2696 } 2697 StringBuilder sb = new StringBuilder(); 2698 List<String> results = new ArrayList<>(); 2699 int length = genres.length(); 2700 boolean escape = false; 2701 for (int i = 0; i < length; ++i) { 2702 char c = genres.charAt(i); 2703 switch (c) { 2704 case DOUBLE_QUOTE: 2705 if (!escape) { 2706 escape = true; 2707 continue; 2708 } 2709 break; 2710 case COMMA: 2711 if (!escape) { 2712 String string = sb.toString().trim(); 2713 if (string.length() > 0) { 2714 results.add(string); 2715 } 2716 sb = new StringBuilder(); 2717 continue; 2718 } 2719 break; 2720 } 2721 sb.append(c); 2722 escape = false; 2723 } 2724 String string = sb.toString().trim(); 2725 if (string.length() > 0) { 2726 results.add(string); 2727 } 2728 return results.toArray(new String[results.size()]); 2729 } 2730 2731 /** 2732 * Returns whether a given text is a canonical genre defined in {@link Genres}. 2733 * 2734 * @param genre The name of genre to be checked. 2735 * @return {@code true} if the genre is canonical, otherwise {@code false}. 2736 */ 2737 public static boolean isCanonical(String genre) { 2738 return CANONICAL_GENRES.contains(genre); 2739 } 2740 } 2741 } 2742 2743 /** 2744 * Column definitions for the recorded TV programs table. 2745 * 2746 * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in 2747 * ascending order. 2748 */ 2749 public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns { 2750 2751 /** 2752 * The content:// style URI for this table. 2753 * 2754 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2755 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2756 */ 2757 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2758 + PATH_RECORDED_PROGRAM); 2759 2760 /** The MIME type of a directory of recorded TV programs. */ 2761 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program"; 2762 2763 /** The MIME type of a single recorded TV program. */ 2764 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program"; 2765 2766 /** 2767 * The ID of the TV channel that provides this recorded program. 2768 * 2769 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2770 * 2771 * <p>Type: INTEGER (long) 2772 */ 2773 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2774 2775 /** 2776 * The ID of the TV input service that is associated with this recorded program. 2777 * 2778 * <p>Use {@link #buildInputId} to build the ID. 2779 * 2780 * <p>This is a required field. 2781 * 2782 * <p>Type: TEXT 2783 */ 2784 public static final String COLUMN_INPUT_ID = "input_id"; 2785 2786 /** 2787 * The start time of the original TV program, in milliseconds since the epoch. 2788 * 2789 * <p>Type: INTEGER (long) 2790 * @see Programs#COLUMN_START_TIME_UTC_MILLIS 2791 */ 2792 public static final String COLUMN_START_TIME_UTC_MILLIS = 2793 Programs.COLUMN_START_TIME_UTC_MILLIS; 2794 2795 /** 2796 * The end time of the original TV program, in milliseconds since the epoch. 2797 * 2798 * <p>Type: INTEGER (long) 2799 * @see Programs#COLUMN_END_TIME_UTC_MILLIS 2800 */ 2801 public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS; 2802 2803 /** 2804 * The comma-separated genre string of this recorded TV program. 2805 * 2806 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2807 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2808 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2809 * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column. 2810 * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the 2811 * text stored in the column. 2812 * 2813 * <p>Type: TEXT 2814 * @see Programs#COLUMN_BROADCAST_GENRE 2815 */ 2816 public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE; 2817 2818 /** 2819 * The URI of the recording data for this recorded program. 2820 * 2821 * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this 2822 * information to manage recording storage. The URI should indicate a file or directory with 2823 * the scheme {@link android.content.ContentResolver#SCHEME_FILE}. 2824 * 2825 * <p>Type: TEXT 2826 * @see #COLUMN_RECORDING_DATA_BYTES 2827 */ 2828 public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri"; 2829 2830 /** 2831 * The data size (in bytes) for this recorded program. 2832 * 2833 * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this 2834 * information to manage recording storage. 2835 * 2836 * <p>Type: INTEGER (long) 2837 * @see #COLUMN_RECORDING_DATA_URI 2838 */ 2839 public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes"; 2840 2841 /** 2842 * The duration (in milliseconds) of this recorded program. 2843 * 2844 * <p>The actual duration of the recorded program can differ from the one calculated by 2845 * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program 2846 * recording can be interrupted in the middle for some reason, resulting in a partially 2847 * recorded program, which is still playable. 2848 * 2849 * <p>Type: INTEGER 2850 */ 2851 public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis"; 2852 2853 /** 2854 * The expiration time for this recorded program, in milliseconds since the epoch. 2855 * 2856 * <p>Recorded TV programs do not expire by default unless explicitly requested by the user 2857 * or the user allows applications to delete them in order to free up disk space for future 2858 * recording. However, some TV content can have expiration date set by the content provider 2859 * when recorded. This field is used to indicate such a restriction. 2860 * 2861 * <p>Can be empty. 2862 * 2863 * <p>Type: INTEGER (long) 2864 */ 2865 public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = 2866 "recording_expire_time_utc_millis"; 2867 2868 private RecordedPrograms() {} 2869 } 2870 2871 /** 2872 * Column definitions for the preview TV programs table. 2873 */ 2874 public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns, 2875 PreviewProgramColumns { 2876 2877 /** 2878 * The content:// style URI for this table. 2879 * 2880 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2881 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2882 */ 2883 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2884 + PATH_PREVIEW_PROGRAM); 2885 2886 /** The MIME type of a directory of preview TV programs. */ 2887 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program"; 2888 2889 /** The MIME type of a single preview TV program. */ 2890 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program"; 2891 2892 /** 2893 * The ID of the TV channel that provides this TV program. 2894 * 2895 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2896 * fail. 2897 * 2898 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2899 * 2900 * <p>This is a required field. 2901 * 2902 * <p>Type: INTEGER (long) 2903 */ 2904 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2905 2906 /** 2907 * The weight of the preview program within the channel. 2908 * 2909 * <p>The UI may choose to show this item in a different position in the channel row. 2910 * A larger weight value means the program is more important than other programs having 2911 * smaller weight values. The value is relevant for the preview programs in the same 2912 * channel. This is only relevant to {@link Channels#TYPE_PREVIEW}. 2913 * 2914 * <p>Can be empty. 2915 * 2916 * <p>Type: INTEGER 2917 */ 2918 public static final String COLUMN_WEIGHT = "weight"; 2919 2920 private PreviewPrograms() {} 2921 } 2922 2923 /** 2924 * Column definitions for the "watch next" TV programs table. 2925 */ 2926 public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns, 2927 PreviewProgramColumns { 2928 2929 /** 2930 * The content:// style URI for this table. 2931 * 2932 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2933 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2934 */ 2935 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2936 + PATH_WATCH_NEXT_PROGRAM); 2937 2938 /** The MIME type of a directory of "watch next" TV programs. */ 2939 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program"; 2940 2941 /** The MIME type of a single preview TV program. */ 2942 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program"; 2943 2944 /** @hide */ 2945 @IntDef({ 2946 WATCH_NEXT_TYPE_CONTINUE, 2947 WATCH_NEXT_TYPE_NEXT, 2948 WATCH_NEXT_TYPE_NEW, 2949 WATCH_NEXT_TYPE_WATCHLIST, 2950 }) 2951 @Retention(RetentionPolicy.SOURCE) 2952 public @interface WatchNextType {} 2953 2954 /** 2955 * The watch next type for CONTINUE. Use this type when the user has already watched more 2956 * than 1 minute of this content. 2957 * 2958 * @see #COLUMN_WATCH_NEXT_TYPE 2959 */ 2960 public static final int WATCH_NEXT_TYPE_CONTINUE = 0; 2961 2962 /** 2963 * The watch next type for NEXT. Use this type when the user has watched one or more 2964 * complete episodes from some episodic content, but there remains more than one episode 2965 * remaining or there is one last episode remaining, but it is not “new” in that it was 2966 * released before the user started watching the show. 2967 * 2968 * @see #COLUMN_WATCH_NEXT_TYPE 2969 */ 2970 public static final int WATCH_NEXT_TYPE_NEXT = 1; 2971 2972 /** 2973 * The watch next type for NEW. Use this type when the user had watched all of the available 2974 * episodes from some episodic content, but a new episode became available since the user 2975 * started watching the first episode and now there is exactly one unwatched episode. This 2976 * could also work for recorded events in a series e.g. soccer matches or football games. 2977 * 2978 * @see #COLUMN_WATCH_NEXT_TYPE 2979 */ 2980 public static final int WATCH_NEXT_TYPE_NEW = 2; 2981 2982 /** 2983 * The watch next type for WATCHLIST. Use this type when the user has elected to explicitly 2984 * add a movie, event or series to a “watchlist” as a manual way of curating what they 2985 * want to watch next. 2986 * 2987 * @see #COLUMN_WATCH_NEXT_TYPE 2988 */ 2989 public static final int WATCH_NEXT_TYPE_WATCHLIST = 3; 2990 2991 /** 2992 * The "watch next" type of this program content. 2993 * 2994 * <p>The value should match one of the followings: 2995 * {@link #WATCH_NEXT_TYPE_CONTINUE}, 2996 * {@link #WATCH_NEXT_TYPE_NEXT}, 2997 * {@link #WATCH_NEXT_TYPE_NEW}, and 2998 * {@link #WATCH_NEXT_TYPE_WATCHLIST}. 2999 * 3000 * <p>This is a required field. 3001 * 3002 * <p>Type: INTEGER 3003 */ 3004 public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type"; 3005 3006 /** 3007 * The last UTC time that the user engaged in this TV program, in milliseconds since the 3008 * epoch. This is a hint for the application that is used for ordering of "watch next" 3009 * programs. 3010 * 3011 * <p>The meaning of the value varies depending on the {@link #COLUMN_WATCH_NEXT_TYPE}: 3012 * <ul> 3013 * <li>{@link #WATCH_NEXT_TYPE_CONTINUE}: the date that the user was last watching the 3014 * content.</li> 3015 * <li>{@link #WATCH_NEXT_TYPE_NEXT}: the date of the last episode watched.</li> 3016 * <li>{@link #WATCH_NEXT_TYPE_NEW}: the release date of the new episode.</li> 3017 * <li>{@link #WATCH_NEXT_TYPE_WATCHLIST}: the date the item was added to the Watchlist. 3018 * </li> 3019 * </ul> 3020 * 3021 * <p>This is a required field. 3022 * 3023 * <p>Type: INTEGER (long) 3024 */ 3025 public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = 3026 "last_engagement_time_utc_millis"; 3027 3028 private WatchNextPrograms() {} 3029 } 3030 3031 /** 3032 * Column definitions for the TV programs that the user watched. Applications do not have access 3033 * to this table. 3034 * 3035 * <p>By default, the query results will be sorted by 3036 * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order. 3037 * @hide 3038 */ 3039 @SystemApi 3040 public static final class WatchedPrograms implements BaseTvColumns { 3041 3042 /** The content:// style URI for this table. */ 3043 public static final Uri CONTENT_URI = 3044 Uri.parse("content://" + AUTHORITY + "/watched_program"); 3045 3046 /** The MIME type of a directory of watched programs. */ 3047 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program"; 3048 3049 /** The MIME type of a single item in this table. */ 3050 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program"; 3051 3052 /** 3053 * The UTC time that the user started watching this TV program, in milliseconds since the 3054 * epoch. 3055 * 3056 * <p>Type: INTEGER (long) 3057 */ 3058 public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS = 3059 "watch_start_time_utc_millis"; 3060 3061 /** 3062 * The UTC time that the user stopped watching this TV program, in milliseconds since the 3063 * epoch. 3064 * 3065 * <p>Type: INTEGER (long) 3066 */ 3067 public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis"; 3068 3069 /** 3070 * The ID of the TV channel that provides this TV program. 3071 * 3072 * <p>This is a required field. 3073 * 3074 * <p>Type: INTEGER (long) 3075 */ 3076 public static final String COLUMN_CHANNEL_ID = "channel_id"; 3077 3078 /** 3079 * The title of this TV program. 3080 * 3081 * <p>Type: TEXT 3082 */ 3083 public static final String COLUMN_TITLE = "title"; 3084 3085 /** 3086 * The start time of this TV program, in milliseconds since the epoch. 3087 * 3088 * <p>Type: INTEGER (long) 3089 */ 3090 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 3091 3092 /** 3093 * The end time of this TV program, in milliseconds since the epoch. 3094 * 3095 * <p>Type: INTEGER (long) 3096 */ 3097 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 3098 3099 /** 3100 * The description of this TV program. 3101 * 3102 * <p>Type: TEXT 3103 */ 3104 public static final String COLUMN_DESCRIPTION = "description"; 3105 3106 /** 3107 * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle) 3108 * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that 3109 * provides this TV program. (Used internally.) 3110 * 3111 * <p>This column contains an encoded string that represents comma-separated key-value pairs of 3112 * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape 3113 * character for '%', '=', and ','. 3114 * 3115 * <p>Type: TEXT 3116 */ 3117 public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params"; 3118 3119 /** 3120 * The session token of this TV program. (Used internally.) 3121 * 3122 * <p>This contains a String representation of {@link IBinder} for 3123 * {@link TvInputService.Session} that provides the current TV program. It is used 3124 * internally to distinguish watched programs entries from different TV input sessions. 3125 * 3126 * <p>Type: TEXT 3127 */ 3128 public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token"; 3129 3130 private WatchedPrograms() {} 3131 } 3132} 3133