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