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