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 1663 /** Column definitions for the TV channels table. */ 1664 public static final class Channels implements BaseTvColumns { 1665 1666 /** 1667 * The content:// style URI for this table. 1668 * 1669 * <p>SQL selection is not supported for {@link ContentResolver#query}, 1670 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 1671 */ 1672 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 1673 + PATH_CHANNEL); 1674 1675 /** The MIME type of a directory of TV channels. */ 1676 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel"; 1677 1678 /** The MIME type of a single TV channel. */ 1679 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel"; 1680 1681 /** @hide */ 1682 @StringDef(prefix = { "TYPE_" }, value = { 1683 TYPE_OTHER, 1684 TYPE_NTSC, 1685 TYPE_PAL, 1686 TYPE_SECAM, 1687 TYPE_DVB_T, 1688 TYPE_DVB_T2, 1689 TYPE_DVB_S, 1690 TYPE_DVB_S2, 1691 TYPE_DVB_C, 1692 TYPE_DVB_C2, 1693 TYPE_DVB_H, 1694 TYPE_DVB_SH, 1695 TYPE_ATSC_T, 1696 TYPE_ATSC_C, 1697 TYPE_ATSC_M_H, 1698 TYPE_ATSC3_T, 1699 TYPE_ISDB_T, 1700 TYPE_ISDB_TB, 1701 TYPE_ISDB_S, 1702 TYPE_ISDB_S3, 1703 TYPE_ISDB_C, 1704 TYPE_1SEG, 1705 TYPE_DTMB, 1706 TYPE_CMMB, 1707 TYPE_T_DMB, 1708 TYPE_S_DMB, 1709 TYPE_PREVIEW, 1710 }) 1711 @Retention(RetentionPolicy.SOURCE) 1712 public @interface Type {} 1713 1714 /** 1715 * A generic channel type. 1716 * 1717 * Use this if the current channel is streaming-based or its broadcast system type does not 1718 * fit under any other types. This is the default channel type. 1719 * 1720 * @see #COLUMN_TYPE 1721 */ 1722 public static final String TYPE_OTHER = "TYPE_OTHER"; 1723 1724 /** 1725 * The channel type for NTSC. 1726 * 1727 * @see #COLUMN_TYPE 1728 */ 1729 public static final String TYPE_NTSC = "TYPE_NTSC"; 1730 1731 /** 1732 * The channel type for PAL. 1733 * 1734 * @see #COLUMN_TYPE 1735 */ 1736 public static final String TYPE_PAL = "TYPE_PAL"; 1737 1738 /** 1739 * The channel type for SECAM. 1740 * 1741 * @see #COLUMN_TYPE 1742 */ 1743 public static final String TYPE_SECAM = "TYPE_SECAM"; 1744 1745 /** 1746 * The channel type for DVB-T (terrestrial). 1747 * 1748 * @see #COLUMN_TYPE 1749 */ 1750 public static final String TYPE_DVB_T = "TYPE_DVB_T"; 1751 1752 /** 1753 * The channel type for DVB-T2 (terrestrial). 1754 * 1755 * @see #COLUMN_TYPE 1756 */ 1757 public static final String TYPE_DVB_T2 = "TYPE_DVB_T2"; 1758 1759 /** 1760 * The channel type for DVB-S (satellite). 1761 * 1762 * @see #COLUMN_TYPE 1763 */ 1764 public static final String TYPE_DVB_S = "TYPE_DVB_S"; 1765 1766 /** 1767 * The channel type for DVB-S2 (satellite). 1768 * 1769 * @see #COLUMN_TYPE 1770 */ 1771 public static final String TYPE_DVB_S2 = "TYPE_DVB_S2"; 1772 1773 /** 1774 * The channel type for DVB-C (cable). 1775 * 1776 * @see #COLUMN_TYPE 1777 */ 1778 public static final String TYPE_DVB_C = "TYPE_DVB_C"; 1779 1780 /** 1781 * The channel type for DVB-C2 (cable). 1782 * 1783 * @see #COLUMN_TYPE 1784 */ 1785 public static final String TYPE_DVB_C2 = "TYPE_DVB_C2"; 1786 1787 /** 1788 * The channel type for DVB-H (handheld). 1789 * 1790 * @see #COLUMN_TYPE 1791 */ 1792 public static final String TYPE_DVB_H = "TYPE_DVB_H"; 1793 1794 /** 1795 * The channel type for DVB-SH (satellite). 1796 * 1797 * @see #COLUMN_TYPE 1798 */ 1799 public static final String TYPE_DVB_SH = "TYPE_DVB_SH"; 1800 1801 /** 1802 * The channel type for ATSC (terrestrial). 1803 * 1804 * @see #COLUMN_TYPE 1805 */ 1806 public static final String TYPE_ATSC_T = "TYPE_ATSC_T"; 1807 1808 /** 1809 * The channel type for ATSC (cable). 1810 * 1811 * @see #COLUMN_TYPE 1812 */ 1813 public static final String TYPE_ATSC_C = "TYPE_ATSC_C"; 1814 1815 /** 1816 * The channel type for ATSC-M/H (mobile/handheld). 1817 * 1818 * @see #COLUMN_TYPE 1819 */ 1820 public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H"; 1821 1822 /** 1823 * The channel type for ATSC3.0 (terrestrial). 1824 * 1825 * @see #COLUMN_TYPE 1826 */ 1827 public static final String TYPE_ATSC3_T = "TYPE_ATSC3_T"; 1828 1829 /** 1830 * The channel type for ISDB-T (terrestrial). 1831 * 1832 * @see #COLUMN_TYPE 1833 */ 1834 public static final String TYPE_ISDB_T = "TYPE_ISDB_T"; 1835 1836 /** 1837 * The channel type for ISDB-Tb (Brazil). 1838 * 1839 * @see #COLUMN_TYPE 1840 */ 1841 public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB"; 1842 1843 /** 1844 * The channel type for ISDB-S (satellite). 1845 * 1846 * @see #COLUMN_TYPE 1847 */ 1848 public static final String TYPE_ISDB_S = "TYPE_ISDB_S"; 1849 1850 /** 1851 * The channel type for ISDB-S3 (satellite). 1852 * 1853 * @see #COLUMN_TYPE 1854 */ 1855 public static final String TYPE_ISDB_S3 = "TYPE_ISDB_S3"; 1856 1857 /** 1858 * The channel type for ISDB-C (cable). 1859 * 1860 * @see #COLUMN_TYPE 1861 */ 1862 public static final String TYPE_ISDB_C = "TYPE_ISDB_C"; 1863 1864 /** 1865 * The channel type for 1seg (handheld). 1866 * 1867 * @see #COLUMN_TYPE 1868 */ 1869 public static final String TYPE_1SEG = "TYPE_1SEG"; 1870 1871 /** 1872 * The channel type for DTMB (terrestrial). 1873 * 1874 * @see #COLUMN_TYPE 1875 */ 1876 public static final String TYPE_DTMB = "TYPE_DTMB"; 1877 1878 /** 1879 * The channel type for CMMB (handheld). 1880 * 1881 * @see #COLUMN_TYPE 1882 */ 1883 public static final String TYPE_CMMB = "TYPE_CMMB"; 1884 1885 /** 1886 * The channel type for T-DMB (terrestrial). 1887 * 1888 * @see #COLUMN_TYPE 1889 */ 1890 public static final String TYPE_T_DMB = "TYPE_T_DMB"; 1891 1892 /** 1893 * The channel type for S-DMB (satellite). 1894 * 1895 * @see #COLUMN_TYPE 1896 */ 1897 public static final String TYPE_S_DMB = "TYPE_S_DMB"; 1898 1899 /** 1900 * The channel type for preview videos. 1901 * 1902 * <P>Unlike other broadcast TV channel types, the programs in the preview channel usually 1903 * are promotional videos. The UI may treat the preview channels differently from the other 1904 * broadcast channels. 1905 * 1906 * @see #COLUMN_TYPE 1907 */ 1908 public static final String TYPE_PREVIEW = "TYPE_PREVIEW"; 1909 1910 /** @hide */ 1911 @StringDef(prefix = { "SERVICE_TYPE_" }, value = { 1912 SERVICE_TYPE_OTHER, 1913 SERVICE_TYPE_AUDIO_VIDEO, 1914 SERVICE_TYPE_AUDIO, 1915 }) 1916 @Retention(RetentionPolicy.SOURCE) 1917 public @interface ServiceType {} 1918 1919 /** A generic service type. */ 1920 public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER"; 1921 1922 /** The service type for regular TV channels that have both audio and video. */ 1923 public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO"; 1924 1925 /** The service type for radio channels that have audio only. */ 1926 public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO"; 1927 1928 /** @hide */ 1929 @StringDef(prefix = { "VIDEO_FORMAT_" }, value = { 1930 VIDEO_FORMAT_240P, 1931 VIDEO_FORMAT_360P, 1932 VIDEO_FORMAT_480I, 1933 VIDEO_FORMAT_576I, 1934 VIDEO_FORMAT_576P, 1935 VIDEO_FORMAT_720P, 1936 VIDEO_FORMAT_1080I, 1937 VIDEO_FORMAT_1080P, 1938 VIDEO_FORMAT_2160P, 1939 VIDEO_FORMAT_4320P, 1940 }) 1941 @Retention(RetentionPolicy.SOURCE) 1942 public @interface VideoFormat {} 1943 1944 /** The video format for 240p. */ 1945 public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P"; 1946 1947 /** The video format for 360p. */ 1948 public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P"; 1949 1950 /** The video format for 480i. */ 1951 public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I"; 1952 1953 /** The video format for 480p. */ 1954 public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P"; 1955 1956 /** The video format for 576i. */ 1957 public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I"; 1958 1959 /** The video format for 576p. */ 1960 public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P"; 1961 1962 /** The video format for 720p. */ 1963 public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P"; 1964 1965 /** The video format for 1080i. */ 1966 public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I"; 1967 1968 /** The video format for 1080p. */ 1969 public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P"; 1970 1971 /** The video format for 2160p. */ 1972 public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P"; 1973 1974 /** The video format for 4320p. */ 1975 public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P"; 1976 1977 /** @hide */ 1978 @StringDef(prefix = { "VIDEO_RESOLUTION_" }, value = { 1979 VIDEO_RESOLUTION_SD, 1980 VIDEO_RESOLUTION_ED, 1981 VIDEO_RESOLUTION_HD, 1982 VIDEO_RESOLUTION_FHD, 1983 VIDEO_RESOLUTION_UHD, 1984 }) 1985 @Retention(RetentionPolicy.SOURCE) 1986 public @interface VideoResolution {} 1987 1988 /** The video resolution for standard-definition. */ 1989 public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD"; 1990 1991 /** The video resolution for enhanced-definition. */ 1992 public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED"; 1993 1994 /** The video resolution for high-definition. */ 1995 public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD"; 1996 1997 /** The video resolution for full high-definition. */ 1998 public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD"; 1999 2000 /** The video resolution for ultra high-definition. */ 2001 public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD"; 2002 2003 private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>(); 2004 2005 static { VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD)2006 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED)2007 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD)2008 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED)2009 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD)2010 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD)2011 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD)2012 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD)2013 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD)2014 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD); 2015 } 2016 2017 /** 2018 * Returns the video resolution (definition) for a given video format. 2019 * 2020 * @param videoFormat The video format defined in {@link Channels}. 2021 * @return the corresponding video resolution string. {@code null} if the resolution string 2022 * is not defined for the given video format. 2023 * @see #COLUMN_VIDEO_FORMAT 2024 */ 2025 @Nullable getVideoResolution(@ideoFormat String videoFormat)2026 public static final String getVideoResolution(@VideoFormat String videoFormat) { 2027 return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat); 2028 } 2029 2030 /** 2031 * The ID of the TV input service that provides this TV channel. 2032 * 2033 * <p>Use {@link #buildInputId} to build the ID. 2034 * 2035 * <p>This is a required field. 2036 * 2037 * <p>Type: TEXT 2038 */ 2039 public static final String COLUMN_INPUT_ID = "input_id"; 2040 2041 /** 2042 * The broadcast system type of this TV channel. 2043 * 2044 * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current 2045 * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the 2046 * default channel type. The value should match one of the followings: 2047 * {@link #TYPE_1SEG}, 2048 * {@link #TYPE_ATSC_C}, 2049 * {@link #TYPE_ATSC_M_H}, 2050 * {@link #TYPE_ATSC_T}, 2051 * {@link #TYPE_ATSC3_T}, 2052 * {@link #TYPE_CMMB}, 2053 * {@link #TYPE_DTMB}, 2054 * {@link #TYPE_DVB_C}, 2055 * {@link #TYPE_DVB_C2}, 2056 * {@link #TYPE_DVB_H}, 2057 * {@link #TYPE_DVB_S}, 2058 * {@link #TYPE_DVB_S2}, 2059 * {@link #TYPE_DVB_SH}, 2060 * {@link #TYPE_DVB_T}, 2061 * {@link #TYPE_DVB_T2}, 2062 * {@link #TYPE_ISDB_C}, 2063 * {@link #TYPE_ISDB_S}, 2064 * {@link #TYPE_ISDB_S3}, 2065 * {@link #TYPE_ISDB_T}, 2066 * {@link #TYPE_ISDB_TB}, 2067 * {@link #TYPE_NTSC}, 2068 * {@link #TYPE_OTHER}, 2069 * {@link #TYPE_PAL}, 2070 * {@link #TYPE_SECAM}, 2071 * {@link #TYPE_S_DMB}, 2072 * {@link #TYPE_T_DMB}, and 2073 * {@link #TYPE_PREVIEW}. 2074 * 2075 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2076 * fail. 2077 * 2078 * <p>This is a required field. 2079 * 2080 * <p>Type: TEXT 2081 */ 2082 public static final String COLUMN_TYPE = "type"; 2083 2084 /** 2085 * The predefined service type of this TV channel. 2086 * 2087 * <p>This is primarily used to indicate whether the current channel is a regular TV channel 2088 * or a radio-like channel. Use the same coding for {@code service_type} in the underlying 2089 * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB 2090 * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER}, 2091 * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO} 2092 * 2093 * <p>This is a required field. 2094 * 2095 * <p>Type: TEXT 2096 */ 2097 public static final String COLUMN_SERVICE_TYPE = "service_type"; 2098 2099 /** 2100 * The original network ID of this TV channel. 2101 * 2102 * <p>It is used to identify the originating delivery system, if applicable. Use the same 2103 * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10. 2104 * 2105 * <p>This is a required field only if the underlying broadcast standard defines the same 2106 * name field. Otherwise, leave empty. 2107 * 2108 * <p>Type: INTEGER 2109 */ 2110 public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; 2111 2112 /** 2113 * The transport stream ID of this channel. 2114 * 2115 * <p>It is used to identify the Transport Stream that contains the current channel from any 2116 * other multiplex within a network, if applicable. Use the same coding for 2117 * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via 2118 * the MPEG Transport Stream. 2119 * 2120 * <p>This is a required field only if the current channel is transmitted via the MPEG 2121 * Transport Stream. Leave empty otherwise. 2122 * 2123 * <p>Type: INTEGER 2124 */ 2125 public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; 2126 2127 /** 2128 * The service ID of this channel. 2129 * 2130 * <p>It is used to identify the current service, or channel from any other services within 2131 * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in 2132 * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1. 2133 * 2134 * <p>This is a required field only if the underlying broadcast standard defines the same 2135 * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave 2136 * empty otherwise. 2137 * 2138 * <p>Type: INTEGER 2139 */ 2140 public static final String COLUMN_SERVICE_ID = "service_id"; 2141 2142 /** 2143 * The channel number that is displayed to the user. 2144 * 2145 * <p>The format can vary depending on broadcast standard and product specification. 2146 * 2147 * <p>Type: TEXT 2148 */ 2149 public static final String COLUMN_DISPLAY_NUMBER = "display_number"; 2150 2151 /** 2152 * The channel name that is displayed to the user. 2153 * 2154 * <p>A call sign is a good candidate to use for this purpose but any name that helps the 2155 * user recognize the current channel will be enough. Can also be empty depending on 2156 * broadcast standard. 2157 * 2158 * <p> Type: TEXT 2159 */ 2160 public static final String COLUMN_DISPLAY_NAME = "display_name"; 2161 2162 /** 2163 * The network affiliation for this TV channel. 2164 * 2165 * <p>This is used to identify a channel that is commonly called by its network affiliation 2166 * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the 2167 * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable. 2168 * 2169 * <p>Type: TEXT 2170 */ 2171 public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation"; 2172 2173 /** 2174 * The description of this TV channel. 2175 * 2176 * <p>Can be empty initially. 2177 * 2178 * <p>Type: TEXT 2179 */ 2180 public static final String COLUMN_DESCRIPTION = "description"; 2181 2182 /** 2183 * The typical video format for programs from this TV channel. 2184 * 2185 * <p>This is primarily used to filter out channels based on video format by applications. 2186 * The value should match one of the followings: {@link #VIDEO_FORMAT_240P}, 2187 * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P}, 2188 * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P}, 2189 * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P}, 2190 * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a 2191 * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and 2192 * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution. 2193 * 2194 * <p>Type: TEXT 2195 * 2196 * @see #getVideoResolution 2197 */ 2198 public static final String COLUMN_VIDEO_FORMAT = "video_format"; 2199 2200 /** 2201 * The flag indicating whether this TV channel is browsable or not. 2202 * 2203 * <p>This column can only be set by applications having proper system permission. For 2204 * other applications, this is a read-only column. 2205 * 2206 * <p>A value of 1 indicates the channel is included in the channel list that applications 2207 * use to browse channels, a value of 0 indicates the channel is not included in the list. 2208 * If not specified, this value is set to 0 (not browsable) by default. 2209 * 2210 * <p>Type: INTEGER (boolean) 2211 */ 2212 public static final String COLUMN_BROWSABLE = "browsable"; 2213 2214 /** 2215 * The flag indicating whether this TV channel is searchable or not. 2216 * 2217 * <p>The columns of searchable channels can be read by other applications that have proper 2218 * permission. Care must be taken not to open sensitive data. 2219 * 2220 * <p>A value of 1 indicates that the channel is searchable and its columns can be read by 2221 * other applications, a value of 0 indicates that the channel is hidden and its columns can 2222 * be read only by the package that owns the channel and the system. If not specified, this 2223 * value is set to 1 (searchable) by default. 2224 * 2225 * <p>Type: INTEGER (boolean) 2226 */ 2227 public static final String COLUMN_SEARCHABLE = "searchable"; 2228 2229 /** 2230 * The flag indicating whether this TV channel is locked or not. 2231 * 2232 * <p>This is primarily used for alternative parental control to prevent unauthorized users 2233 * from watching the current channel regardless of the content rating. A value of 1 2234 * indicates the channel is locked and the user is required to enter passcode to unlock it 2235 * in order to watch the current program from the channel, a value of 0 indicates the 2236 * channel is not locked thus the user is not prompted to enter passcode If not specified, 2237 * this value is set to 0 (not locked) by default. 2238 * 2239 * <p>This column can only be set by applications having proper system permission to 2240 * modify parental control settings. For other applications, this is a read-only column. 2241 2242 * <p>Type: INTEGER (boolean) 2243 */ 2244 public static final String COLUMN_LOCKED = "locked"; 2245 2246 /** 2247 * The URI for the app badge icon of the app link template for this channel. 2248 * 2249 * <p>This small icon is overlaid at the bottom of the poster art specified by 2250 * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of 2251 * the following formats: 2252 * 2253 * <ul> 2254 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2255 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2256 * </li> 2257 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2258 * </ul> 2259 * 2260 * <p>The app-linking allows channel input sources to provide activity links from their live 2261 * channel programming to another activity. This enables content providers to increase user 2262 * engagement by offering the viewer other content or actions. 2263 * 2264 * <p>Type: TEXT 2265 * @see #COLUMN_APP_LINK_COLOR 2266 * @see #COLUMN_APP_LINK_INTENT_URI 2267 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2268 * @see #COLUMN_APP_LINK_TEXT 2269 */ 2270 public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri"; 2271 2272 /** 2273 * The URI for the poster art used as the background of the app link template for this 2274 * channel. 2275 * 2276 * <p>The data in the column must be a URL, or a URI in one of the following formats: 2277 * 2278 * <ul> 2279 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2280 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2281 * </li> 2282 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2283 * </ul> 2284 * 2285 * <p>The app-linking allows channel input sources to provide activity links from their live 2286 * channel programming to another activity. This enables content providers to increase user 2287 * engagement by offering the viewer other content or actions. 2288 * 2289 * <p>Type: TEXT 2290 * @see #COLUMN_APP_LINK_COLOR 2291 * @see #COLUMN_APP_LINK_ICON_URI 2292 * @see #COLUMN_APP_LINK_INTENT_URI 2293 * @see #COLUMN_APP_LINK_TEXT 2294 */ 2295 public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri"; 2296 2297 /** 2298 * The link text of the app link template for this channel. 2299 * 2300 * <p>This provides a short description of the action that happens when the corresponding 2301 * app link is clicked. 2302 * 2303 * <p>The app-linking allows channel input sources to provide activity links from their live 2304 * channel programming to another activity. This enables content providers to increase user 2305 * engagement by offering the viewer other content or actions. 2306 * 2307 * <p>Type: TEXT 2308 * @see #COLUMN_APP_LINK_COLOR 2309 * @see #COLUMN_APP_LINK_ICON_URI 2310 * @see #COLUMN_APP_LINK_INTENT_URI 2311 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2312 */ 2313 public static final String COLUMN_APP_LINK_TEXT = "app_link_text"; 2314 2315 /** 2316 * The accent color of the app link template for this channel. This is primarily used for 2317 * the background color of the text box in the template. 2318 * 2319 * <p>The app-linking allows channel input sources to provide activity links from their live 2320 * channel programming to another activity. This enables content providers to increase user 2321 * engagement by offering the viewer other content or actions. 2322 * 2323 * <p>Type: INTEGER (color value) 2324 * @see #COLUMN_APP_LINK_ICON_URI 2325 * @see #COLUMN_APP_LINK_INTENT_URI 2326 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2327 * @see #COLUMN_APP_LINK_TEXT 2328 */ 2329 public static final String COLUMN_APP_LINK_COLOR = "app_link_color"; 2330 2331 /** 2332 * The intent URI of the app link for this channel. 2333 * 2334 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 2335 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 2336 * launched when the user clicks the corresponding app link for the current channel. 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: TEXT 2343 * @see #COLUMN_APP_LINK_COLOR 2344 * @see #COLUMN_APP_LINK_ICON_URI 2345 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2346 * @see #COLUMN_APP_LINK_TEXT 2347 */ 2348 public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri"; 2349 2350 /** 2351 * The internal ID used by individual TV input services. 2352 * 2353 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2354 * apps. 2355 * 2356 * <p>Can be empty. 2357 * 2358 * <p>Type: TEXT 2359 */ 2360 public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id"; 2361 2362 /** 2363 * Internal data used by individual TV input services. 2364 * 2365 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2366 * apps. 2367 * 2368 * <p>Type: BLOB 2369 */ 2370 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 2371 2372 /** 2373 * Internal integer flag used by individual TV input services. 2374 * 2375 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2376 * apps. 2377 * 2378 * <p>Type: INTEGER 2379 */ 2380 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 2381 2382 /** 2383 * Internal integer flag used by individual TV input services. 2384 * 2385 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2386 * apps. 2387 * 2388 * <p>Type: INTEGER 2389 */ 2390 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 2391 2392 /** 2393 * Internal integer flag used by individual TV input services. 2394 * 2395 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2396 * apps. 2397 * 2398 * <p>Type: INTEGER 2399 */ 2400 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 2401 2402 /** 2403 * Internal integer flag used by individual TV input services. 2404 * 2405 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2406 * apps. 2407 * 2408 * <p>Type: INTEGER 2409 */ 2410 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 2411 2412 /** 2413 * The version number of this row entry used by TV input services. 2414 * 2415 * <p>This is best used by sync adapters to identify the rows to update. The number can be 2416 * defined by individual TV input services. One may assign the same value as 2417 * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are 2418 * coming from a TV broadcast. 2419 * 2420 * <p>Type: INTEGER 2421 */ 2422 public static final String COLUMN_VERSION_NUMBER = "version_number"; 2423 2424 /** 2425 * The flag indicating whether this TV channel is transient or not. 2426 * 2427 * <p>A value of 1 indicates that the channel will be automatically removed by the system on 2428 * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not 2429 * specified, this value is set to 0 (not transient) by default. 2430 * 2431 * <p>Type: INTEGER (boolean) 2432 * @see PreviewPrograms#COLUMN_TRANSIENT 2433 * @see WatchNextPrograms#COLUMN_TRANSIENT 2434 */ 2435 public static final String COLUMN_TRANSIENT = "transient"; 2436 2437 /** 2438 * The global content ID of this TV channel, as a URI. 2439 * 2440 * <p>A globally unique URI that identifies this TV channel, if applicable. Suitable URIs 2441 * include 2442 * <ul> 2443 * <li>{@code globalServiceId} from ATSC A/331. ex {@code https://doi.org/10.5239/7E4E-B472} 2444 * <li>Other broadcast ID provider. ex {@code http://example.com/tv_channel/1234} 2445 * </ul> 2446 * 2447 * <p>Can be empty. 2448 * 2449 * <p>Type: TEXT 2450 */ 2451 public static final String COLUMN_GLOBAL_CONTENT_ID = "global_content_id"; 2452 Channels()2453 private Channels() {} 2454 2455 /** 2456 * A sub-directory of a single TV channel that represents its primary logo. 2457 * 2458 * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw 2459 * channel URI. The resulting URI represents an image file, and should be interacted 2460 * using ContentResolver.openAssetFileDescriptor. 2461 * 2462 * <p>Note that this sub-directory also supports opening the logo as an asset file in write 2463 * mode. Callers can create or replace the primary logo associated with this channel by 2464 * opening the asset file and writing the full-size photo contents into it. (Make sure there 2465 * is no padding around the logo image.) When the file is closed, the image will be parsed, 2466 * sized down if necessary, and stored. 2467 * 2468 * <p>Usage example: 2469 * <pre> 2470 * public void writeChannelLogo(long channelId, byte[] logo) { 2471 * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId); 2472 * try { 2473 * AssetFileDescriptor fd = 2474 * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw"); 2475 * OutputStream os = fd.createOutputStream(); 2476 * os.write(logo); 2477 * os.close(); 2478 * fd.close(); 2479 * } catch (IOException e) { 2480 * // Handle error cases. 2481 * } 2482 * } 2483 * </pre> 2484 */ 2485 public static final class Logo { 2486 2487 /** 2488 * The directory twig for this sub-table. 2489 */ 2490 public static final String CONTENT_DIRECTORY = "logo"; 2491 Logo()2492 private Logo() {} 2493 } 2494 } 2495 2496 /** 2497 * Column definitions for the TV programs table. 2498 * 2499 * <p>By default, the query results will be sorted by 2500 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order. 2501 */ 2502 public static final class Programs implements BaseTvColumns, ProgramColumns { 2503 2504 /** 2505 * The content:// style URI for this table. 2506 * 2507 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2508 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2509 */ 2510 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2511 + PATH_PROGRAM); 2512 2513 /** The MIME type of a directory of TV programs. */ 2514 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program"; 2515 2516 /** The MIME type of a single TV program. */ 2517 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program"; 2518 2519 /** 2520 * The ID of the TV channel that provides this TV program. 2521 * 2522 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2523 * 2524 * <p>This is a required field. 2525 * 2526 * <p>Type: INTEGER (long) 2527 */ 2528 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2529 2530 /** 2531 * The season number of this TV program for episodic TV shows. 2532 * 2533 * <p>Can be empty. 2534 * 2535 * <p>Type: INTEGER 2536 * 2537 * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead. 2538 */ 2539 @Deprecated 2540 public static final String COLUMN_SEASON_NUMBER = "season_number"; 2541 2542 /** 2543 * The episode number of this TV program for episodic TV shows. 2544 * 2545 * <p>Can be empty. 2546 * 2547 * <p>Type: INTEGER 2548 * 2549 * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead. 2550 */ 2551 @Deprecated 2552 public static final String COLUMN_EPISODE_NUMBER = "episode_number"; 2553 2554 /** 2555 * The start time of this TV program, in milliseconds since the epoch. 2556 * 2557 * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the 2558 * previous program in the same channel. In practice, start time will usually be the end 2559 * time of the previous program. 2560 * 2561 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2562 * 2563 * <p>Type: INTEGER (long) 2564 */ 2565 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 2566 2567 /** 2568 * The end time of this TV program, in milliseconds since the epoch. 2569 * 2570 * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the 2571 * next program in the same channel. In practice, end time will usually be the start time of 2572 * the next program. 2573 * 2574 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2575 * 2576 * <p>Type: INTEGER (long) 2577 */ 2578 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 2579 2580 /** 2581 * The comma-separated genre string of this TV program. 2582 * 2583 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2584 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2585 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2586 * {@link Genres#encode} to create a text that can be stored in this column. Use 2587 * {@link Genres#decode} to get the broadcast genre strings from the text stored in the 2588 * column. 2589 * 2590 * <p>Type: TEXT 2591 * @see Genres#encode 2592 * @see Genres#decode 2593 */ 2594 public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre"; 2595 2596 /** 2597 * The flag indicating whether recording of this program is prohibited. 2598 * 2599 * <p>A value of 1 indicates that recording of this program is prohibited and application 2600 * will not schedule any recording for this program. A value of 0 indicates that the 2601 * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by 2602 * default. 2603 * 2604 * <p>Type: INTEGER (boolean) 2605 */ 2606 public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited"; 2607 2608 /** 2609 * The event ID of this TV program. 2610 * 2611 * <p>It is used to identify the current TV program in the same channel, if applicable. 2612 * Use the same coding for {@code event_id} in the underlying broadcast standard if it 2613 * is defined there (e.g. ATSC A/65, ETSI EN 300 468 and ARIB STD-B10). 2614 * 2615 * <p>This is a required field only if the underlying broadcast standard defines the same 2616 * name field. Otherwise, leave empty. 2617 * 2618 * <p>Type: INTEGER 2619 */ 2620 public static final String COLUMN_EVENT_ID = "event_id"; 2621 2622 /** 2623 * The global content ID of this TV program, as a URI. 2624 * 2625 * <p>A globally unique ID that identifies this TV program, if applicable. Suitable URIs 2626 * include 2627 * <ul> 2628 * <li>{@code crid://<CRIDauthority>/<data>} from ETSI TS 102 323 2629 * <li>{@code globalContentId} from ATSC A/332 2630 * <li>Other broadcast ID provider. ex {@code http://example.com/tv_program/1234} 2631 * </ul> 2632 * 2633 * <p>Can be empty. 2634 * 2635 * <p>Type: TEXT 2636 */ 2637 public static final String COLUMN_GLOBAL_CONTENT_ID = "global_content_id"; 2638 Programs()2639 private Programs() {} 2640 2641 /** Canonical genres for TV programs. */ 2642 public static final class Genres { 2643 /** @hide */ 2644 @StringDef({ 2645 FAMILY_KIDS, 2646 SPORTS, 2647 SHOPPING, 2648 MOVIES, 2649 COMEDY, 2650 TRAVEL, 2651 DRAMA, 2652 EDUCATION, 2653 ANIMAL_WILDLIFE, 2654 NEWS, 2655 GAMING, 2656 ARTS, 2657 ENTERTAINMENT, 2658 LIFE_STYLE, 2659 MUSIC, 2660 PREMIER, 2661 TECH_SCIENCE, 2662 }) 2663 @Retention(RetentionPolicy.SOURCE) 2664 public @interface Genre {} 2665 2666 /** The genre for Family/Kids. */ 2667 public static final String FAMILY_KIDS = "FAMILY_KIDS"; 2668 2669 /** The genre for Sports. */ 2670 public static final String SPORTS = "SPORTS"; 2671 2672 /** The genre for Shopping. */ 2673 public static final String SHOPPING = "SHOPPING"; 2674 2675 /** The genre for Movies. */ 2676 public static final String MOVIES = "MOVIES"; 2677 2678 /** The genre for Comedy. */ 2679 public static final String COMEDY = "COMEDY"; 2680 2681 /** The genre for Travel. */ 2682 public static final String TRAVEL = "TRAVEL"; 2683 2684 /** The genre for Drama. */ 2685 public static final String DRAMA = "DRAMA"; 2686 2687 /** The genre for Education. */ 2688 public static final String EDUCATION = "EDUCATION"; 2689 2690 /** The genre for Animal/Wildlife. */ 2691 public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE"; 2692 2693 /** The genre for News. */ 2694 public static final String NEWS = "NEWS"; 2695 2696 /** The genre for Gaming. */ 2697 public static final String GAMING = "GAMING"; 2698 2699 /** The genre for Arts. */ 2700 public static final String ARTS = "ARTS"; 2701 2702 /** The genre for Entertainment. */ 2703 public static final String ENTERTAINMENT = "ENTERTAINMENT"; 2704 2705 /** The genre for Life Style. */ 2706 public static final String LIFE_STYLE = "LIFE_STYLE"; 2707 2708 /** The genre for Music. */ 2709 public static final String MUSIC = "MUSIC"; 2710 2711 /** The genre for Premier. */ 2712 public static final String PREMIER = "PREMIER"; 2713 2714 /** The genre for Tech/Science. */ 2715 public static final String TECH_SCIENCE = "TECH_SCIENCE"; 2716 2717 private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>(); 2718 static { 2719 CANONICAL_GENRES.add(FAMILY_KIDS); 2720 CANONICAL_GENRES.add(SPORTS); 2721 CANONICAL_GENRES.add(SHOPPING); 2722 CANONICAL_GENRES.add(MOVIES); 2723 CANONICAL_GENRES.add(COMEDY); 2724 CANONICAL_GENRES.add(TRAVEL); 2725 CANONICAL_GENRES.add(DRAMA); 2726 CANONICAL_GENRES.add(EDUCATION); 2727 CANONICAL_GENRES.add(ANIMAL_WILDLIFE); 2728 CANONICAL_GENRES.add(NEWS); 2729 CANONICAL_GENRES.add(GAMING); 2730 CANONICAL_GENRES.add(ARTS); 2731 CANONICAL_GENRES.add(ENTERTAINMENT); 2732 CANONICAL_GENRES.add(LIFE_STYLE); 2733 CANONICAL_GENRES.add(MUSIC); 2734 CANONICAL_GENRES.add(PREMIER); 2735 CANONICAL_GENRES.add(TECH_SCIENCE); 2736 } 2737 2738 private static final char DOUBLE_QUOTE = '"'; 2739 private static final char COMMA = ','; 2740 private static final String DELIMITER = ","; 2741 2742 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 2743 Genres()2744 private Genres() {} 2745 2746 /** 2747 * Encodes genre strings to a text that can be put into the database. 2748 * 2749 * @param genres Genre strings. 2750 * @return an encoded genre string that can be inserted into the 2751 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2752 */ encode(@onNull @enre String... genres)2753 public static String encode(@NonNull @Genre String... genres) { 2754 if (genres == null) { 2755 // MNC and before will throw a NPE. 2756 return null; 2757 } 2758 StringBuilder sb = new StringBuilder(); 2759 String separator = ""; 2760 for (String genre : genres) { 2761 sb.append(separator).append(encodeToCsv(genre)); 2762 separator = DELIMITER; 2763 } 2764 return sb.toString(); 2765 } 2766 encodeToCsv(String genre)2767 private static String encodeToCsv(String genre) { 2768 StringBuilder sb = new StringBuilder(); 2769 int length = genre.length(); 2770 for (int i = 0; i < length; ++i) { 2771 char c = genre.charAt(i); 2772 switch (c) { 2773 case DOUBLE_QUOTE: 2774 sb.append(DOUBLE_QUOTE); 2775 break; 2776 case COMMA: 2777 sb.append(DOUBLE_QUOTE); 2778 break; 2779 } 2780 sb.append(c); 2781 } 2782 return sb.toString(); 2783 } 2784 2785 /** 2786 * Decodes the genre strings from the text stored in the database. 2787 * 2788 * @param genres The encoded genre string retrieved from the 2789 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2790 * @return genre strings. 2791 */ decode(@onNull String genres)2792 public static @Genre String[] decode(@NonNull String genres) { 2793 if (TextUtils.isEmpty(genres)) { 2794 // MNC and before will throw a NPE for {@code null} genres. 2795 return EMPTY_STRING_ARRAY; 2796 } 2797 if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) { 2798 return new String[] {genres.trim()}; 2799 } 2800 StringBuilder sb = new StringBuilder(); 2801 List<String> results = new ArrayList<>(); 2802 int length = genres.length(); 2803 boolean escape = false; 2804 for (int i = 0; i < length; ++i) { 2805 char c = genres.charAt(i); 2806 switch (c) { 2807 case DOUBLE_QUOTE: 2808 if (!escape) { 2809 escape = true; 2810 continue; 2811 } 2812 break; 2813 case COMMA: 2814 if (!escape) { 2815 String string = sb.toString().trim(); 2816 if (string.length() > 0) { 2817 results.add(string); 2818 } 2819 sb = new StringBuilder(); 2820 continue; 2821 } 2822 break; 2823 } 2824 sb.append(c); 2825 escape = false; 2826 } 2827 String string = sb.toString().trim(); 2828 if (string.length() > 0) { 2829 results.add(string); 2830 } 2831 return results.toArray(new String[results.size()]); 2832 } 2833 2834 /** 2835 * Returns whether a given text is a canonical genre defined in {@link Genres}. 2836 * 2837 * @param genre The name of genre to be checked. 2838 * @return {@code true} if the genre is canonical, otherwise {@code false}. 2839 */ isCanonical(String genre)2840 public static boolean isCanonical(String genre) { 2841 return CANONICAL_GENRES.contains(genre); 2842 } 2843 } 2844 } 2845 2846 /** 2847 * Column definitions for the recorded TV programs table. 2848 * 2849 * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in 2850 * ascending order. 2851 */ 2852 public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns { 2853 2854 /** 2855 * The content:// style URI for this table. 2856 * 2857 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2858 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2859 */ 2860 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2861 + PATH_RECORDED_PROGRAM); 2862 2863 /** The MIME type of a directory of recorded TV programs. */ 2864 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program"; 2865 2866 /** The MIME type of a single recorded TV program. */ 2867 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program"; 2868 2869 /** 2870 * The ID of the TV channel that provides this recorded program. 2871 * 2872 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2873 * 2874 * <p>Type: INTEGER (long) 2875 */ 2876 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2877 2878 /** 2879 * The ID of the TV input service that is associated with this recorded program. 2880 * 2881 * <p>Use {@link #buildInputId} to build the ID. 2882 * 2883 * <p>This is a required field. 2884 * 2885 * <p>Type: TEXT 2886 */ 2887 public static final String COLUMN_INPUT_ID = "input_id"; 2888 2889 /** 2890 * The start time of the original TV program, in milliseconds since the epoch. 2891 * 2892 * <p>Type: INTEGER (long) 2893 * @see Programs#COLUMN_START_TIME_UTC_MILLIS 2894 */ 2895 public static final String COLUMN_START_TIME_UTC_MILLIS = 2896 Programs.COLUMN_START_TIME_UTC_MILLIS; 2897 2898 /** 2899 * The end time of the original TV program, in milliseconds since the epoch. 2900 * 2901 * <p>Type: INTEGER (long) 2902 * @see Programs#COLUMN_END_TIME_UTC_MILLIS 2903 */ 2904 public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS; 2905 2906 /** 2907 * The comma-separated genre string of this recorded TV program. 2908 * 2909 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2910 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2911 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2912 * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column. 2913 * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the 2914 * text stored in the column. 2915 * 2916 * <p>Type: TEXT 2917 * @see Programs#COLUMN_BROADCAST_GENRE 2918 */ 2919 public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE; 2920 2921 /** 2922 * The URI of the recording data for this recorded program. 2923 * 2924 * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this 2925 * information to manage recording storage. The URI should indicate a file or directory with 2926 * the scheme {@link android.content.ContentResolver#SCHEME_FILE}. 2927 * 2928 * <p>Type: TEXT 2929 * @see #COLUMN_RECORDING_DATA_BYTES 2930 */ 2931 public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri"; 2932 2933 /** 2934 * The data size (in bytes) for this recorded program. 2935 * 2936 * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this 2937 * information to manage recording storage. 2938 * 2939 * <p>Type: INTEGER (long) 2940 * @see #COLUMN_RECORDING_DATA_URI 2941 */ 2942 public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes"; 2943 2944 /** 2945 * The duration (in milliseconds) of this recorded program. 2946 * 2947 * <p>The actual duration of the recorded program can differ from the one calculated by 2948 * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program 2949 * recording can be interrupted in the middle for some reason, resulting in a partially 2950 * recorded program, which is still playable. 2951 * 2952 * <p>Type: INTEGER 2953 */ 2954 public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis"; 2955 2956 /** 2957 * The expiration time for this recorded program, in milliseconds since the epoch. 2958 * 2959 * <p>Recorded TV programs do not expire by default unless explicitly requested by the user 2960 * or the user allows applications to delete them in order to free up disk space for future 2961 * recording. However, some TV content can have expiration date set by the content provider 2962 * when recorded. This field is used to indicate such a restriction. 2963 * 2964 * <p>Can be empty. 2965 * 2966 * <p>Type: INTEGER (long) 2967 */ 2968 public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = 2969 "recording_expire_time_utc_millis"; 2970 RecordedPrograms()2971 private RecordedPrograms() {} 2972 } 2973 2974 /** 2975 * Column definitions for the preview TV programs table. 2976 */ 2977 public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns, 2978 PreviewProgramColumns { 2979 2980 /** 2981 * The content:// style URI for this table. 2982 * 2983 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2984 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2985 */ 2986 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2987 + PATH_PREVIEW_PROGRAM); 2988 2989 /** The MIME type of a directory of preview TV programs. */ 2990 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program"; 2991 2992 /** The MIME type of a single preview TV program. */ 2993 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program"; 2994 2995 /** 2996 * The ID of the TV channel that provides this TV program. 2997 * 2998 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2999 * fail. 3000 * 3001 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 3002 * 3003 * <p>This is a required field. 3004 * 3005 * <p>Type: INTEGER (long) 3006 */ 3007 public static final String COLUMN_CHANNEL_ID = "channel_id"; 3008 3009 /** 3010 * The weight of the preview program within the channel. 3011 * 3012 * <p>The UI may choose to show this item in a different position in the channel row. 3013 * A larger weight value means the program is more important than other programs having 3014 * smaller weight values. The value is relevant for the preview programs in the same 3015 * channel. This is only relevant to {@link Channels#TYPE_PREVIEW}. 3016 * 3017 * <p>Can be empty. 3018 * 3019 * <p>Type: INTEGER 3020 */ 3021 public static final String COLUMN_WEIGHT = "weight"; 3022 PreviewPrograms()3023 private PreviewPrograms() {} 3024 } 3025 3026 /** 3027 * Column definitions for the "watch next" TV programs table. 3028 */ 3029 public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns, 3030 PreviewProgramColumns { 3031 3032 /** 3033 * The content:// style URI for this table. 3034 * 3035 * <p>SQL selection is not supported for {@link ContentResolver#query}, 3036 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 3037 */ 3038 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 3039 + PATH_WATCH_NEXT_PROGRAM); 3040 3041 /** The MIME type of a directory of "watch next" TV programs. */ 3042 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program"; 3043 3044 /** The MIME type of a single preview TV program. */ 3045 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program"; 3046 3047 /** @hide */ 3048 @IntDef({ 3049 WATCH_NEXT_TYPE_CONTINUE, 3050 WATCH_NEXT_TYPE_NEXT, 3051 WATCH_NEXT_TYPE_NEW, 3052 WATCH_NEXT_TYPE_WATCHLIST, 3053 }) 3054 @Retention(RetentionPolicy.SOURCE) 3055 public @interface WatchNextType {} 3056 3057 /** 3058 * The watch next type for CONTINUE. Use this type when the user has already watched more 3059 * than 1 minute of this content. 3060 * 3061 * @see #COLUMN_WATCH_NEXT_TYPE 3062 */ 3063 public static final int WATCH_NEXT_TYPE_CONTINUE = 0; 3064 3065 /** 3066 * The watch next type for NEXT. Use this type when the user has watched one or more 3067 * complete episodes from some episodic content, but there remains more than one episode 3068 * remaining or there is one last episode remaining, but it is not “new” in that it was 3069 * released before the user started watching the show. 3070 * 3071 * @see #COLUMN_WATCH_NEXT_TYPE 3072 */ 3073 public static final int WATCH_NEXT_TYPE_NEXT = 1; 3074 3075 /** 3076 * The watch next type for NEW. Use this type when the user had watched all of the available 3077 * episodes from some episodic content, but a new episode became available since the user 3078 * started watching the first episode and now there is exactly one unwatched episode. This 3079 * could also work for recorded events in a series e.g. soccer matches or football games. 3080 * 3081 * @see #COLUMN_WATCH_NEXT_TYPE 3082 */ 3083 public static final int WATCH_NEXT_TYPE_NEW = 2; 3084 3085 /** 3086 * The watch next type for WATCHLIST. Use this type when the user has elected to explicitly 3087 * add a movie, event or series to a “watchlist” as a manual way of curating what they 3088 * want to watch next. 3089 * 3090 * @see #COLUMN_WATCH_NEXT_TYPE 3091 */ 3092 public static final int WATCH_NEXT_TYPE_WATCHLIST = 3; 3093 3094 /** 3095 * The "watch next" type of this program content. 3096 * 3097 * <p>The value should match one of the followings: 3098 * {@link #WATCH_NEXT_TYPE_CONTINUE}, 3099 * {@link #WATCH_NEXT_TYPE_NEXT}, 3100 * {@link #WATCH_NEXT_TYPE_NEW}, and 3101 * {@link #WATCH_NEXT_TYPE_WATCHLIST}. 3102 * 3103 * <p>This is a required field. 3104 * 3105 * <p>Type: INTEGER 3106 */ 3107 public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type"; 3108 3109 /** 3110 * The last UTC time that the user engaged in this TV program, in milliseconds since the 3111 * epoch. This is a hint for the application that is used for ordering of "watch next" 3112 * programs. 3113 * 3114 * <p>The meaning of the value varies depending on the {@link #COLUMN_WATCH_NEXT_TYPE}: 3115 * <ul> 3116 * <li>{@link #WATCH_NEXT_TYPE_CONTINUE}: the date that the user was last watching the 3117 * content.</li> 3118 * <li>{@link #WATCH_NEXT_TYPE_NEXT}: the date of the last episode watched.</li> 3119 * <li>{@link #WATCH_NEXT_TYPE_NEW}: the release date of the new episode.</li> 3120 * <li>{@link #WATCH_NEXT_TYPE_WATCHLIST}: the date the item was added to the Watchlist. 3121 * </li> 3122 * </ul> 3123 * 3124 * <p>This is a required field. 3125 * 3126 * <p>Type: INTEGER (long) 3127 */ 3128 public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = 3129 "last_engagement_time_utc_millis"; 3130 WatchNextPrograms()3131 private WatchNextPrograms() {} 3132 } 3133 3134 /** 3135 * Column definitions for the TV programs that the user watched. Applications do not have access 3136 * to this table. 3137 * 3138 * <p>By default, the query results will be sorted by 3139 * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order. 3140 * @hide 3141 */ 3142 @SystemApi 3143 public static final class WatchedPrograms implements BaseTvColumns { 3144 3145 /** The content:// style URI for this table. */ 3146 public static final Uri CONTENT_URI = 3147 Uri.parse("content://" + AUTHORITY + "/watched_program"); 3148 3149 /** The MIME type of a directory of watched programs. */ 3150 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program"; 3151 3152 /** The MIME type of a single item in this table. */ 3153 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program"; 3154 3155 /** 3156 * The UTC time that the user started watching this TV program, in milliseconds since the 3157 * epoch. 3158 * 3159 * <p>Type: INTEGER (long) 3160 */ 3161 public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS = 3162 "watch_start_time_utc_millis"; 3163 3164 /** 3165 * The UTC time that the user stopped watching this TV program, in milliseconds since the 3166 * epoch. 3167 * 3168 * <p>Type: INTEGER (long) 3169 */ 3170 public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis"; 3171 3172 /** 3173 * The ID of the TV channel that provides this TV program. 3174 * 3175 * <p>This is a required field. 3176 * 3177 * <p>Type: INTEGER (long) 3178 */ 3179 public static final String COLUMN_CHANNEL_ID = "channel_id"; 3180 3181 /** 3182 * The title of this TV program. 3183 * 3184 * <p>Type: TEXT 3185 */ 3186 public static final String COLUMN_TITLE = "title"; 3187 3188 /** 3189 * The start time of this TV program, in milliseconds since the epoch. 3190 * 3191 * <p>Type: INTEGER (long) 3192 */ 3193 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 3194 3195 /** 3196 * The end time of this TV program, in milliseconds since the epoch. 3197 * 3198 * <p>Type: INTEGER (long) 3199 */ 3200 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 3201 3202 /** 3203 * The description of this TV program. 3204 * 3205 * <p>Type: TEXT 3206 */ 3207 public static final String COLUMN_DESCRIPTION = "description"; 3208 3209 /** 3210 * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle) 3211 * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that 3212 * provides this TV program. (Used internally.) 3213 * 3214 * <p>This column contains an encoded string that represents comma-separated key-value pairs of 3215 * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape 3216 * character for '%', '=', and ','. 3217 * 3218 * <p>Type: TEXT 3219 */ 3220 public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params"; 3221 3222 /** 3223 * The session token of this TV program. (Used internally.) 3224 * 3225 * <p>This contains a String representation of {@link IBinder} for 3226 * {@link TvInputService.Session} that provides the current TV program. It is used 3227 * internally to distinguish watched programs entries from different TV input sessions. 3228 * 3229 * <p>Type: TEXT 3230 */ 3231 public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token"; 3232 WatchedPrograms()3233 private WatchedPrograms() {} 3234 } 3235 } 3236