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 /** 1115 * Common columns for the tables of preview programs. 1116 * @hide 1117 */ 1118 interface PreviewProgramColumns { 1119 1120 /** @hide */ 1121 @IntDef({ 1122 TYPE_MOVIE, 1123 TYPE_TV_SERIES, 1124 TYPE_TV_SEASON, 1125 TYPE_TV_EPISODE, 1126 TYPE_CLIP, 1127 TYPE_EVENT, 1128 TYPE_CHANNEL, 1129 TYPE_TRACK, 1130 TYPE_ALBUM, 1131 TYPE_ARTIST, 1132 TYPE_PLAYLIST, 1133 TYPE_STATION, 1134 }) 1135 @Retention(RetentionPolicy.SOURCE) 1136 public @interface Type {} 1137 1138 /** 1139 * The program type for movie. 1140 * 1141 * @see #COLUMN_TYPE 1142 */ 1143 int TYPE_MOVIE = 0; 1144 1145 /** 1146 * The program type for TV series. 1147 * 1148 * @see #COLUMN_TYPE 1149 */ 1150 int TYPE_TV_SERIES = 1; 1151 1152 /** 1153 * The program type for TV season. 1154 * 1155 * @see #COLUMN_TYPE 1156 */ 1157 int TYPE_TV_SEASON = 2; 1158 1159 /** 1160 * The program type for TV episode. 1161 * 1162 * @see #COLUMN_TYPE 1163 */ 1164 int TYPE_TV_EPISODE = 3; 1165 1166 /** 1167 * The program type for clip. 1168 * 1169 * @see #COLUMN_TYPE 1170 */ 1171 int TYPE_CLIP = 4; 1172 1173 /** 1174 * The program type for event. 1175 * 1176 * @see #COLUMN_TYPE 1177 */ 1178 int TYPE_EVENT = 5; 1179 1180 /** 1181 * The program type for channel. 1182 * 1183 * @see #COLUMN_TYPE 1184 */ 1185 int TYPE_CHANNEL = 6; 1186 1187 /** 1188 * The program type for track. 1189 * 1190 * @see #COLUMN_TYPE 1191 */ 1192 int TYPE_TRACK = 7; 1193 1194 /** 1195 * The program type for album. 1196 * 1197 * @see #COLUMN_TYPE 1198 */ 1199 int TYPE_ALBUM = 8; 1200 1201 /** 1202 * The program type for artist. 1203 * 1204 * @see #COLUMN_TYPE 1205 */ 1206 int TYPE_ARTIST = 9; 1207 1208 /** 1209 * The program type for playlist. 1210 * 1211 * @see #COLUMN_TYPE 1212 */ 1213 int TYPE_PLAYLIST = 10; 1214 1215 /** 1216 * The program type for station. 1217 * 1218 * @see #COLUMN_TYPE 1219 */ 1220 int TYPE_STATION = 11; 1221 1222 /** @hide */ 1223 @IntDef({ 1224 ASPECT_RATIO_16_9, 1225 ASPECT_RATIO_3_2, 1226 ASPECT_RATIO_1_1, 1227 ASPECT_RATIO_2_3, 1228 ASPECT_RATIO_4_3, 1229 }) 1230 @Retention(RetentionPolicy.SOURCE) 1231 public @interface AspectRatio {} 1232 1233 /** 1234 * The aspect ratio for 16:9. 1235 * 1236 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1237 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1238 */ 1239 int ASPECT_RATIO_16_9 = 0; 1240 1241 /** 1242 * The aspect ratio for 3:2. 1243 * 1244 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1245 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1246 */ 1247 int ASPECT_RATIO_3_2 = 1; 1248 1249 /** 1250 * The aspect ratio for 4:3. 1251 * 1252 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1253 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1254 */ 1255 int ASPECT_RATIO_4_3 = 2; 1256 1257 /** 1258 * The aspect ratio for 1:1. 1259 * 1260 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1261 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1262 */ 1263 int ASPECT_RATIO_1_1 = 3; 1264 1265 /** 1266 * The aspect ratio for 2:3. 1267 * 1268 * @see #COLUMN_POSTER_ART_ASPECT_RATIO 1269 * @see #COLUMN_THUMBNAIL_ASPECT_RATIO 1270 */ 1271 int ASPECT_RATIO_2_3 = 4; 1272 1273 /** @hide */ 1274 @IntDef({ 1275 AVAILABILITY_AVAILABLE, 1276 AVAILABILITY_FREE_WITH_SUBSCRIPTION, 1277 AVAILABILITY_PAID_CONTENT, 1278 }) 1279 @Retention(RetentionPolicy.SOURCE) 1280 public @interface Availability {} 1281 1282 /** 1283 * The availability for "available to this user". 1284 * 1285 * @see #COLUMN_AVAILABILITY 1286 */ 1287 int AVAILABILITY_AVAILABLE = 0; 1288 1289 /** 1290 * The availability for "free with subscription". 1291 * 1292 * @see #COLUMN_AVAILABILITY 1293 */ 1294 int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; 1295 1296 /** 1297 * The availability for "paid content, either to-own or rental 1298 * (user has not purchased/rented). 1299 * 1300 * @see #COLUMN_AVAILABILITY 1301 */ 1302 int AVAILABILITY_PAID_CONTENT = 2; 1303 1304 /** @hide */ 1305 @IntDef({ 1306 INTERACTION_TYPE_VIEWS, 1307 INTERACTION_TYPE_LISTENS, 1308 INTERACTION_TYPE_FOLLOWERS, 1309 INTERACTION_TYPE_FANS, 1310 INTERACTION_TYPE_LIKES, 1311 INTERACTION_TYPE_THUMBS, 1312 INTERACTION_TYPE_VIEWERS, 1313 }) 1314 @Retention(RetentionPolicy.SOURCE) 1315 public @interface InteractionType {} 1316 1317 /** 1318 * The interaction type for "views". 1319 * 1320 * @see #COLUMN_INTERACTION_TYPE 1321 */ 1322 int INTERACTION_TYPE_VIEWS = 0; 1323 1324 /** 1325 * The interaction type for "listens". 1326 * 1327 * @see #COLUMN_INTERACTION_TYPE 1328 */ 1329 int INTERACTION_TYPE_LISTENS = 1; 1330 1331 /** 1332 * The interaction type for "followers". 1333 * 1334 * @see #COLUMN_INTERACTION_TYPE 1335 */ 1336 int INTERACTION_TYPE_FOLLOWERS = 2; 1337 1338 /** 1339 * The interaction type for "fans". 1340 * 1341 * @see #COLUMN_INTERACTION_TYPE 1342 */ 1343 int INTERACTION_TYPE_FANS = 3; 1344 1345 /** 1346 * The interaction type for "likes". 1347 * 1348 * @see #COLUMN_INTERACTION_TYPE 1349 */ 1350 int INTERACTION_TYPE_LIKES = 4; 1351 1352 /** 1353 * The interaction type for "thumbs". 1354 * 1355 * @see #COLUMN_INTERACTION_TYPE 1356 */ 1357 int INTERACTION_TYPE_THUMBS = 5; 1358 1359 /** 1360 * The interaction type for "viewers". 1361 * 1362 * @see #COLUMN_INTERACTION_TYPE 1363 */ 1364 int INTERACTION_TYPE_VIEWERS = 6; 1365 1366 /** 1367 * The type of this program content. 1368 * 1369 * <p>The value should match one of the followings: 1370 * {@link #TYPE_MOVIE}, 1371 * {@link #TYPE_TV_SERIES}, 1372 * {@link #TYPE_TV_SEASON}, 1373 * {@link #TYPE_TV_EPISODE}, 1374 * {@link #TYPE_CLIP}, 1375 * {@link #TYPE_EVENT}, 1376 * {@link #TYPE_CHANNEL}, 1377 * {@link #TYPE_TRACK}, 1378 * {@link #TYPE_ALBUM}, 1379 * {@link #TYPE_ARTIST}, 1380 * {@link #TYPE_PLAYLIST}, and 1381 * {@link #TYPE_STATION}. 1382 * 1383 * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW} 1384 * channel. 1385 * 1386 * <p>Type: INTEGER 1387 */ 1388 String COLUMN_TYPE = "type"; 1389 1390 /** 1391 * The aspect ratio of the poster art for this TV program. 1392 * 1393 * <p>The value should match one of the followings: 1394 * {@link #ASPECT_RATIO_16_9}, 1395 * {@link #ASPECT_RATIO_3_2}, 1396 * {@link #ASPECT_RATIO_4_3}, 1397 * {@link #ASPECT_RATIO_1_1}, and 1398 * {@link #ASPECT_RATIO_2_3}. 1399 * 1400 * <p>Type: INTEGER 1401 */ 1402 String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio"; 1403 1404 /** 1405 * The aspect ratio of the thumbnail for this TV program. 1406 * 1407 * <p>The value should match one of the followings: 1408 * {@link #ASPECT_RATIO_16_9}, 1409 * {@link #ASPECT_RATIO_3_2}, 1410 * {@link #ASPECT_RATIO_4_3}, 1411 * {@link #ASPECT_RATIO_1_1}, and 1412 * {@link #ASPECT_RATIO_2_3}. 1413 * 1414 * <p>Type: INTEGER 1415 */ 1416 String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio"; 1417 1418 /** 1419 * The URI for the logo of this TV program. 1420 * 1421 * <p>This is a small badge shown on top of the poster art or thumbnail representing the 1422 * source of the content. 1423 * 1424 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1425 * 1426 * <ul> 1427 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1428 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1429 * </li> 1430 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1431 * </ul> 1432 * 1433 * <p>Can be empty. 1434 * 1435 * <p>Type: TEXT 1436 */ 1437 String COLUMN_LOGO_URI = "logo_uri"; 1438 1439 /** 1440 * The availability of this TV program. 1441 * 1442 * <p>The value should match one of the followings: 1443 * {@link #AVAILABILITY_AVAILABLE}, 1444 * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and 1445 * {@link #AVAILABILITY_PAID_CONTENT}. 1446 * 1447 * <p>Type: INTEGER 1448 */ 1449 String COLUMN_AVAILABILITY = "availability"; 1450 1451 /** 1452 * The starting price of this TV program. 1453 * 1454 * <p>This indicates the lowest regular acquisition cost of the content. It is only used 1455 * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}. 1456 * 1457 * <p>Type: TEXT 1458 * @see #COLUMN_OFFER_PRICE 1459 */ 1460 String COLUMN_STARTING_PRICE = "starting_price"; 1461 1462 /** 1463 * The offer price of this TV program. 1464 * 1465 * <p>This is the promotional cost of the content. It is only used if the availability of 1466 * the program is {@link #AVAILABILITY_PAID_CONTENT}. 1467 * 1468 * <p>Type: TEXT 1469 * @see #COLUMN_STARTING_PRICE 1470 */ 1471 String COLUMN_OFFER_PRICE = "offer_price"; 1472 1473 /** 1474 * The release date of this TV program. 1475 * 1476 * <p>The value should be in one of the following formats: 1477 * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601). 1478 * 1479 * <p>Type: TEXT 1480 */ 1481 String COLUMN_RELEASE_DATE = "release_date"; 1482 1483 /** 1484 * The count of the items included in this TV program. 1485 * 1486 * <p>This is only relevant if the program represents a collection of items such as series, 1487 * episodes, or music tracks. 1488 * 1489 * <p>Type: INTEGER 1490 */ 1491 String COLUMN_ITEM_COUNT = "item_count"; 1492 1493 /** 1494 * The flag indicating whether this TV program is live or not. 1495 * 1496 * <p>A value of 1 indicates that the content is airing and should be consumed now, a value 1497 * of 0 indicates that the content is off the air and does not need to be consumed at the 1498 * present time. If not specified, the value is set to 0 (not live) by default. 1499 * 1500 * <p>Type: INTEGER (boolean) 1501 */ 1502 String COLUMN_LIVE = "live"; 1503 1504 /** 1505 * The internal ID used by individual TV input services. 1506 * 1507 * <p>This is internal to the provider that inserted it, and should not be decoded by other 1508 * apps. 1509 * 1510 * <p>Can be empty. 1511 * 1512 * <p>Type: TEXT 1513 */ 1514 String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id"; 1515 1516 /** 1517 * The URI for the preview video. 1518 * 1519 * <p>The data in the column must be a URL, or a URI in one of the following formats: 1520 * 1521 * <ul> 1522 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 1523 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 1524 * </li> 1525 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 1526 * </ul> 1527 * 1528 * <p>Can be empty. 1529 * 1530 * <p>Type: TEXT 1531 */ 1532 String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri"; 1533 1534 /** 1535 * The last playback position (in milliseconds) of the original content of this preview 1536 * program. 1537 * 1538 * <p>Can be empty. 1539 * 1540 * <p>Type: INTEGER 1541 */ 1542 String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = 1543 "last_playback_position_millis"; 1544 1545 /** 1546 * The duration (in milliseconds) of the original content of this preview program. 1547 * 1548 * <p>Can be empty. 1549 * 1550 * <p>Type: INTEGER 1551 */ 1552 String COLUMN_DURATION_MILLIS = "duration_millis"; 1553 1554 /** 1555 * The intent URI which is launched when the preview program is selected. 1556 * 1557 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 1558 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 1559 * launched when the user selects the preview program item. 1560 * 1561 * <p>Can be empty. 1562 * 1563 * <p>Type: TEXT 1564 */ 1565 String COLUMN_INTENT_URI = "intent_uri"; 1566 1567 /** 1568 * The flag indicating whether this program is transient or not. 1569 * 1570 * <p>A value of 1 indicates that the channel will be automatically removed by the system on 1571 * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not 1572 * specified, this value is set to 0 (not transient) by default. 1573 * 1574 * <p>Type: INTEGER (boolean) 1575 * @see Channels#COLUMN_TRANSIENT 1576 */ 1577 String COLUMN_TRANSIENT = "transient"; 1578 1579 /** 1580 * The type of interaction for this TV program. 1581 * 1582 * <p> The value should match one of the followings: 1583 * {@link #INTERACTION_TYPE_VIEWS}, 1584 * {@link #INTERACTION_TYPE_LISTENS}, 1585 * {@link #INTERACTION_TYPE_FOLLOWERS}, 1586 * {@link #INTERACTION_TYPE_FANS}, 1587 * {@link #INTERACTION_TYPE_LIKES}, 1588 * {@link #INTERACTION_TYPE_THUMBS}, and 1589 * {@link #INTERACTION_TYPE_VIEWERS}. 1590 * 1591 * <p>Type: INTEGER 1592 * @see #COLUMN_INTERACTION_COUNT 1593 */ 1594 String COLUMN_INTERACTION_TYPE = "interaction_type"; 1595 1596 /** 1597 * The interaction count for this program. 1598 * 1599 * <p>This indicates the number of times interaction has happened. 1600 * 1601 * <p>Type: INTEGER (long) 1602 * @see #COLUMN_INTERACTION_TYPE 1603 */ 1604 String COLUMN_INTERACTION_COUNT = "interaction_count"; 1605 1606 /** 1607 * The author or artist of this content. 1608 * 1609 * <p>Type: TEXT 1610 */ 1611 String COLUMN_AUTHOR = "author"; 1612 1613 /** 1614 * The flag indicating whether this TV program is browsable or not. 1615 * 1616 * <p>This column can only be set by applications having proper system permission. For 1617 * other applications, this is a read-only column. 1618 * 1619 * <p>A value of 1 indicates that the program is browsable and can be shown to users in 1620 * the UI. A value of 0 indicates that the program should be hidden from users and the 1621 * application who changes this value to 0 should send 1622 * {@link #ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED} to the owner of the program 1623 * to notify this change. 1624 * 1625 * <p>This value is set to 1 (browsable) by default. 1626 * 1627 * <p>Type: INTEGER (boolean) 1628 */ 1629 String COLUMN_BROWSABLE = "browsable"; 1630 1631 /** 1632 * The content ID of this TV program. 1633 * 1634 * <p>A public ID of the content which allows the application to apply the same operation to 1635 * all the program copies in different channels. 1636 * 1637 * <p>Can be empty. 1638 * 1639 * <p>Type: TEXT 1640 */ 1641 String COLUMN_CONTENT_ID = "content_id"; 1642 1643 } 1644 1645 /** Column definitions for the TV channels table. */ 1646 public static final class Channels implements BaseTvColumns { 1647 1648 /** 1649 * The content:// style URI for this table. 1650 * 1651 * <p>SQL selection is not supported for {@link ContentResolver#query}, 1652 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 1653 */ 1654 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 1655 + PATH_CHANNEL); 1656 1657 /** The MIME type of a directory of TV channels. */ 1658 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel"; 1659 1660 /** The MIME type of a single TV channel. */ 1661 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel"; 1662 1663 /** @hide */ 1664 @StringDef(prefix = { "TYPE_" }, value = { 1665 TYPE_OTHER, 1666 TYPE_NTSC, 1667 TYPE_PAL, 1668 TYPE_SECAM, 1669 TYPE_DVB_T, 1670 TYPE_DVB_T2, 1671 TYPE_DVB_S, 1672 TYPE_DVB_S2, 1673 TYPE_DVB_C, 1674 TYPE_DVB_C2, 1675 TYPE_DVB_H, 1676 TYPE_DVB_SH, 1677 TYPE_ATSC_T, 1678 TYPE_ATSC_C, 1679 TYPE_ATSC_M_H, 1680 TYPE_ISDB_T, 1681 TYPE_ISDB_TB, 1682 TYPE_ISDB_S, 1683 TYPE_ISDB_S3, 1684 TYPE_ISDB_C, 1685 TYPE_1SEG, 1686 TYPE_DTMB, 1687 TYPE_CMMB, 1688 TYPE_T_DMB, 1689 TYPE_S_DMB, 1690 TYPE_PREVIEW, 1691 }) 1692 @Retention(RetentionPolicy.SOURCE) 1693 public @interface Type {} 1694 1695 /** 1696 * A generic channel type. 1697 * 1698 * Use this if the current channel is streaming-based or its broadcast system type does not 1699 * fit under any other types. This is the default channel type. 1700 * 1701 * @see #COLUMN_TYPE 1702 */ 1703 public static final String TYPE_OTHER = "TYPE_OTHER"; 1704 1705 /** 1706 * The channel type for NTSC. 1707 * 1708 * @see #COLUMN_TYPE 1709 */ 1710 public static final String TYPE_NTSC = "TYPE_NTSC"; 1711 1712 /** 1713 * The channel type for PAL. 1714 * 1715 * @see #COLUMN_TYPE 1716 */ 1717 public static final String TYPE_PAL = "TYPE_PAL"; 1718 1719 /** 1720 * The channel type for SECAM. 1721 * 1722 * @see #COLUMN_TYPE 1723 */ 1724 public static final String TYPE_SECAM = "TYPE_SECAM"; 1725 1726 /** 1727 * The channel type for DVB-T (terrestrial). 1728 * 1729 * @see #COLUMN_TYPE 1730 */ 1731 public static final String TYPE_DVB_T = "TYPE_DVB_T"; 1732 1733 /** 1734 * The channel type for DVB-T2 (terrestrial). 1735 * 1736 * @see #COLUMN_TYPE 1737 */ 1738 public static final String TYPE_DVB_T2 = "TYPE_DVB_T2"; 1739 1740 /** 1741 * The channel type for DVB-S (satellite). 1742 * 1743 * @see #COLUMN_TYPE 1744 */ 1745 public static final String TYPE_DVB_S = "TYPE_DVB_S"; 1746 1747 /** 1748 * The channel type for DVB-S2 (satellite). 1749 * 1750 * @see #COLUMN_TYPE 1751 */ 1752 public static final String TYPE_DVB_S2 = "TYPE_DVB_S2"; 1753 1754 /** 1755 * The channel type for DVB-C (cable). 1756 * 1757 * @see #COLUMN_TYPE 1758 */ 1759 public static final String TYPE_DVB_C = "TYPE_DVB_C"; 1760 1761 /** 1762 * The channel type for DVB-C2 (cable). 1763 * 1764 * @see #COLUMN_TYPE 1765 */ 1766 public static final String TYPE_DVB_C2 = "TYPE_DVB_C2"; 1767 1768 /** 1769 * The channel type for DVB-H (handheld). 1770 * 1771 * @see #COLUMN_TYPE 1772 */ 1773 public static final String TYPE_DVB_H = "TYPE_DVB_H"; 1774 1775 /** 1776 * The channel type for DVB-SH (satellite). 1777 * 1778 * @see #COLUMN_TYPE 1779 */ 1780 public static final String TYPE_DVB_SH = "TYPE_DVB_SH"; 1781 1782 /** 1783 * The channel type for ATSC (terrestrial). 1784 * 1785 * @see #COLUMN_TYPE 1786 */ 1787 public static final String TYPE_ATSC_T = "TYPE_ATSC_T"; 1788 1789 /** 1790 * The channel type for ATSC (cable). 1791 * 1792 * @see #COLUMN_TYPE 1793 */ 1794 public static final String TYPE_ATSC_C = "TYPE_ATSC_C"; 1795 1796 /** 1797 * The channel type for ATSC-M/H (mobile/handheld). 1798 * 1799 * @see #COLUMN_TYPE 1800 */ 1801 public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H"; 1802 1803 /** 1804 * The channel type for ISDB-T (terrestrial). 1805 * 1806 * @see #COLUMN_TYPE 1807 */ 1808 public static final String TYPE_ISDB_T = "TYPE_ISDB_T"; 1809 1810 /** 1811 * The channel type for ISDB-Tb (Brazil). 1812 * 1813 * @see #COLUMN_TYPE 1814 */ 1815 public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB"; 1816 1817 /** 1818 * The channel type for ISDB-S (satellite). 1819 * 1820 * @see #COLUMN_TYPE 1821 */ 1822 public static final String TYPE_ISDB_S = "TYPE_ISDB_S"; 1823 1824 /** 1825 * The channel type for ISDB-S3 (satellite). 1826 * 1827 * @see #COLUMN_TYPE 1828 */ 1829 public static final String TYPE_ISDB_S3 = "TYPE_ISDB_S3"; 1830 1831 /** 1832 * The channel type for ISDB-C (cable). 1833 * 1834 * @see #COLUMN_TYPE 1835 */ 1836 public static final String TYPE_ISDB_C = "TYPE_ISDB_C"; 1837 1838 /** 1839 * The channel type for 1seg (handheld). 1840 * 1841 * @see #COLUMN_TYPE 1842 */ 1843 public static final String TYPE_1SEG = "TYPE_1SEG"; 1844 1845 /** 1846 * The channel type for DTMB (terrestrial). 1847 * 1848 * @see #COLUMN_TYPE 1849 */ 1850 public static final String TYPE_DTMB = "TYPE_DTMB"; 1851 1852 /** 1853 * The channel type for CMMB (handheld). 1854 * 1855 * @see #COLUMN_TYPE 1856 */ 1857 public static final String TYPE_CMMB = "TYPE_CMMB"; 1858 1859 /** 1860 * The channel type for T-DMB (terrestrial). 1861 * 1862 * @see #COLUMN_TYPE 1863 */ 1864 public static final String TYPE_T_DMB = "TYPE_T_DMB"; 1865 1866 /** 1867 * The channel type for S-DMB (satellite). 1868 * 1869 * @see #COLUMN_TYPE 1870 */ 1871 public static final String TYPE_S_DMB = "TYPE_S_DMB"; 1872 1873 /** 1874 * The channel type for preview videos. 1875 * 1876 * <P>Unlike other broadcast TV channel types, the programs in the preview channel usually 1877 * are promotional videos. The UI may treat the preview channels differently from the other 1878 * broadcast channels. 1879 * 1880 * @see #COLUMN_TYPE 1881 */ 1882 public static final String TYPE_PREVIEW = "TYPE_PREVIEW"; 1883 1884 /** @hide */ 1885 @StringDef(prefix = { "SERVICE_TYPE_" }, value = { 1886 SERVICE_TYPE_OTHER, 1887 SERVICE_TYPE_AUDIO_VIDEO, 1888 SERVICE_TYPE_AUDIO, 1889 }) 1890 @Retention(RetentionPolicy.SOURCE) 1891 public @interface ServiceType {} 1892 1893 /** A generic service type. */ 1894 public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER"; 1895 1896 /** The service type for regular TV channels that have both audio and video. */ 1897 public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO"; 1898 1899 /** The service type for radio channels that have audio only. */ 1900 public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO"; 1901 1902 /** @hide */ 1903 @StringDef(prefix = { "VIDEO_FORMAT_" }, value = { 1904 VIDEO_FORMAT_240P, 1905 VIDEO_FORMAT_360P, 1906 VIDEO_FORMAT_480I, 1907 VIDEO_FORMAT_576I, 1908 VIDEO_FORMAT_576P, 1909 VIDEO_FORMAT_720P, 1910 VIDEO_FORMAT_1080I, 1911 VIDEO_FORMAT_1080P, 1912 VIDEO_FORMAT_2160P, 1913 VIDEO_FORMAT_4320P, 1914 }) 1915 @Retention(RetentionPolicy.SOURCE) 1916 public @interface VideoFormat {} 1917 1918 /** The video format for 240p. */ 1919 public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P"; 1920 1921 /** The video format for 360p. */ 1922 public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P"; 1923 1924 /** The video format for 480i. */ 1925 public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I"; 1926 1927 /** The video format for 480p. */ 1928 public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P"; 1929 1930 /** The video format for 576i. */ 1931 public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I"; 1932 1933 /** The video format for 576p. */ 1934 public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P"; 1935 1936 /** The video format for 720p. */ 1937 public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P"; 1938 1939 /** The video format for 1080i. */ 1940 public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I"; 1941 1942 /** The video format for 1080p. */ 1943 public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P"; 1944 1945 /** The video format for 2160p. */ 1946 public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P"; 1947 1948 /** The video format for 4320p. */ 1949 public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P"; 1950 1951 /** @hide */ 1952 @StringDef(prefix = { "VIDEO_RESOLUTION_" }, value = { 1953 VIDEO_RESOLUTION_SD, 1954 VIDEO_RESOLUTION_ED, 1955 VIDEO_RESOLUTION_HD, 1956 VIDEO_RESOLUTION_FHD, 1957 VIDEO_RESOLUTION_UHD, 1958 }) 1959 @Retention(RetentionPolicy.SOURCE) 1960 public @interface VideoResolution {} 1961 1962 /** The video resolution for standard-definition. */ 1963 public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD"; 1964 1965 /** The video resolution for enhanced-definition. */ 1966 public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED"; 1967 1968 /** The video resolution for high-definition. */ 1969 public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD"; 1970 1971 /** The video resolution for full high-definition. */ 1972 public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD"; 1973 1974 /** The video resolution for ultra high-definition. */ 1975 public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD"; 1976 1977 private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>(); 1978 1979 static { VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD)1980 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED)1981 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD)1982 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED)1983 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD)1984 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD)1985 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD)1986 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD)1987 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD); VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD)1988 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD); 1989 } 1990 1991 /** 1992 * Returns the video resolution (definition) for a given video format. 1993 * 1994 * @param videoFormat The video format defined in {@link Channels}. 1995 * @return the corresponding video resolution string. {@code null} if the resolution string 1996 * is not defined for the given video format. 1997 * @see #COLUMN_VIDEO_FORMAT 1998 */ 1999 @Nullable getVideoResolution(@ideoFormat String videoFormat)2000 public static final String getVideoResolution(@VideoFormat String videoFormat) { 2001 return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat); 2002 } 2003 2004 /** 2005 * The ID of the TV input service that provides this TV channel. 2006 * 2007 * <p>Use {@link #buildInputId} to build the ID. 2008 * 2009 * <p>This is a required field. 2010 * 2011 * <p>Type: TEXT 2012 */ 2013 public static final String COLUMN_INPUT_ID = "input_id"; 2014 2015 /** 2016 * The broadcast system type of this TV channel. 2017 * 2018 * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current 2019 * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the 2020 * default channel type. The value should match one of the followings: 2021 * {@link #TYPE_1SEG}, 2022 * {@link #TYPE_ATSC_C}, 2023 * {@link #TYPE_ATSC_M_H}, 2024 * {@link #TYPE_ATSC_T}, 2025 * {@link #TYPE_CMMB}, 2026 * {@link #TYPE_DTMB}, 2027 * {@link #TYPE_DVB_C}, 2028 * {@link #TYPE_DVB_C2}, 2029 * {@link #TYPE_DVB_H}, 2030 * {@link #TYPE_DVB_S}, 2031 * {@link #TYPE_DVB_S2}, 2032 * {@link #TYPE_DVB_SH}, 2033 * {@link #TYPE_DVB_T}, 2034 * {@link #TYPE_DVB_T2}, 2035 * {@link #TYPE_ISDB_C}, 2036 * {@link #TYPE_ISDB_S}, 2037 * {@link #TYPE_ISDB_S3}, 2038 * {@link #TYPE_ISDB_T}, 2039 * {@link #TYPE_ISDB_TB}, 2040 * {@link #TYPE_NTSC}, 2041 * {@link #TYPE_OTHER}, 2042 * {@link #TYPE_PAL}, 2043 * {@link #TYPE_SECAM}, 2044 * {@link #TYPE_S_DMB}, 2045 * {@link #TYPE_T_DMB}, and 2046 * {@link #TYPE_PREVIEW}. 2047 * 2048 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2049 * fail. 2050 * 2051 * <p>This is a required field. 2052 * 2053 * <p>Type: TEXT 2054 */ 2055 public static final String COLUMN_TYPE = "type"; 2056 2057 /** 2058 * The predefined service type of this TV channel. 2059 * 2060 * <p>This is primarily used to indicate whether the current channel is a regular TV channel 2061 * or a radio-like channel. Use the same coding for {@code service_type} in the underlying 2062 * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB 2063 * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER}, 2064 * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO} 2065 * 2066 * <p>This is a required field. 2067 * 2068 * <p>Type: TEXT 2069 */ 2070 public static final String COLUMN_SERVICE_TYPE = "service_type"; 2071 2072 /** 2073 * The original network ID of this TV channel. 2074 * 2075 * <p>It is used to identify the originating delivery system, if applicable. Use the same 2076 * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10. 2077 * 2078 * <p>This is a required field only if the underlying broadcast standard defines the same 2079 * name field. Otherwise, leave empty. 2080 * 2081 * <p>Type: INTEGER 2082 */ 2083 public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; 2084 2085 /** 2086 * The transport stream ID of this channel. 2087 * 2088 * <p>It is used to identify the Transport Stream that contains the current channel from any 2089 * other multiplex within a network, if applicable. Use the same coding for 2090 * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via 2091 * the MPEG Transport Stream. 2092 * 2093 * <p>This is a required field only if the current channel is transmitted via the MPEG 2094 * Transport Stream. Leave empty otherwise. 2095 * 2096 * <p>Type: INTEGER 2097 */ 2098 public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; 2099 2100 /** 2101 * The service ID of this channel. 2102 * 2103 * <p>It is used to identify the current service, or channel from any other services within 2104 * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in 2105 * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1. 2106 * 2107 * <p>This is a required field only if the underlying broadcast standard defines the same 2108 * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave 2109 * empty otherwise. 2110 * 2111 * <p>Type: INTEGER 2112 */ 2113 public static final String COLUMN_SERVICE_ID = "service_id"; 2114 2115 /** 2116 * The channel number that is displayed to the user. 2117 * 2118 * <p>The format can vary depending on broadcast standard and product specification. 2119 * 2120 * <p>Type: TEXT 2121 */ 2122 public static final String COLUMN_DISPLAY_NUMBER = "display_number"; 2123 2124 /** 2125 * The channel name that is displayed to the user. 2126 * 2127 * <p>A call sign is a good candidate to use for this purpose but any name that helps the 2128 * user recognize the current channel will be enough. Can also be empty depending on 2129 * broadcast standard. 2130 * 2131 * <p> Type: TEXT 2132 */ 2133 public static final String COLUMN_DISPLAY_NAME = "display_name"; 2134 2135 /** 2136 * The network affiliation for this TV channel. 2137 * 2138 * <p>This is used to identify a channel that is commonly called by its network affiliation 2139 * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the 2140 * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable. 2141 * 2142 * <p>Type: TEXT 2143 */ 2144 public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation"; 2145 2146 /** 2147 * The description of this TV channel. 2148 * 2149 * <p>Can be empty initially. 2150 * 2151 * <p>Type: TEXT 2152 */ 2153 public static final String COLUMN_DESCRIPTION = "description"; 2154 2155 /** 2156 * The typical video format for programs from this TV channel. 2157 * 2158 * <p>This is primarily used to filter out channels based on video format by applications. 2159 * The value should match one of the followings: {@link #VIDEO_FORMAT_240P}, 2160 * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P}, 2161 * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P}, 2162 * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P}, 2163 * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a 2164 * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and 2165 * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution. 2166 * 2167 * <p>Type: TEXT 2168 * 2169 * @see #getVideoResolution 2170 */ 2171 public static final String COLUMN_VIDEO_FORMAT = "video_format"; 2172 2173 /** 2174 * The flag indicating whether this TV channel is browsable or not. 2175 * 2176 * <p>This column can only be set by applications having proper system permission. For 2177 * other applications, this is a read-only column. 2178 * 2179 * <p>A value of 1 indicates the channel is included in the channel list that applications 2180 * use to browse channels, a value of 0 indicates the channel is not included in the list. 2181 * If not specified, this value is set to 0 (not browsable) by default. 2182 * 2183 * <p>Type: INTEGER (boolean) 2184 */ 2185 public static final String COLUMN_BROWSABLE = "browsable"; 2186 2187 /** 2188 * The flag indicating whether this TV channel is searchable or not. 2189 * 2190 * <p>The columns of searchable channels can be read by other applications that have proper 2191 * permission. Care must be taken not to open sensitive data. 2192 * 2193 * <p>A value of 1 indicates that the channel is searchable and its columns can be read by 2194 * other applications, a value of 0 indicates that the channel is hidden and its columns can 2195 * be read only by the package that owns the channel and the system. If not specified, this 2196 * value is set to 1 (searchable) by default. 2197 * 2198 * <p>Type: INTEGER (boolean) 2199 */ 2200 public static final String COLUMN_SEARCHABLE = "searchable"; 2201 2202 /** 2203 * The flag indicating whether this TV channel is locked or not. 2204 * 2205 * <p>This is primarily used for alternative parental control to prevent unauthorized users 2206 * from watching the current channel regardless of the content rating. A value of 1 2207 * indicates the channel is locked and the user is required to enter passcode to unlock it 2208 * in order to watch the current program from the channel, a value of 0 indicates the 2209 * channel is not locked thus the user is not prompted to enter passcode If not specified, 2210 * this value is set to 0 (not locked) by default. 2211 * 2212 * <p>This column can only be set by applications having proper system permission to 2213 * modify parental control settings. For other applications, this is a read-only column. 2214 2215 * <p>Type: INTEGER (boolean) 2216 */ 2217 public static final String COLUMN_LOCKED = "locked"; 2218 2219 /** 2220 * The URI for the app badge icon of the app link template for this channel. 2221 * 2222 * <p>This small icon is overlaid at the bottom of the poster art specified by 2223 * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of 2224 * the following formats: 2225 * 2226 * <ul> 2227 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2228 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2229 * </li> 2230 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2231 * </ul> 2232 * 2233 * <p>The app-linking allows channel input sources to provide activity links from their live 2234 * channel programming to another activity. This enables content providers to increase user 2235 * engagement by offering the viewer other content or actions. 2236 * 2237 * <p>Type: TEXT 2238 * @see #COLUMN_APP_LINK_COLOR 2239 * @see #COLUMN_APP_LINK_INTENT_URI 2240 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2241 * @see #COLUMN_APP_LINK_TEXT 2242 */ 2243 public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri"; 2244 2245 /** 2246 * The URI for the poster art used as the background of the app link template for this 2247 * channel. 2248 * 2249 * <p>The data in the column must be a URL, or a URI in one of the following formats: 2250 * 2251 * <ul> 2252 * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> 2253 * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) 2254 * </li> 2255 * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> 2256 * </ul> 2257 * 2258 * <p>The app-linking allows channel input sources to provide activity links from their live 2259 * channel programming to another activity. This enables content providers to increase user 2260 * engagement by offering the viewer other content or actions. 2261 * 2262 * <p>Type: TEXT 2263 * @see #COLUMN_APP_LINK_COLOR 2264 * @see #COLUMN_APP_LINK_ICON_URI 2265 * @see #COLUMN_APP_LINK_INTENT_URI 2266 * @see #COLUMN_APP_LINK_TEXT 2267 */ 2268 public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri"; 2269 2270 /** 2271 * The link text of the app link template for this channel. 2272 * 2273 * <p>This provides a short description of the action that happens when the corresponding 2274 * app link is clicked. 2275 * 2276 * <p>The app-linking allows channel input sources to provide activity links from their live 2277 * channel programming to another activity. This enables content providers to increase user 2278 * engagement by offering the viewer other content or actions. 2279 * 2280 * <p>Type: TEXT 2281 * @see #COLUMN_APP_LINK_COLOR 2282 * @see #COLUMN_APP_LINK_ICON_URI 2283 * @see #COLUMN_APP_LINK_INTENT_URI 2284 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2285 */ 2286 public static final String COLUMN_APP_LINK_TEXT = "app_link_text"; 2287 2288 /** 2289 * The accent color of the app link template for this channel. This is primarily used for 2290 * the background color of the text box in the template. 2291 * 2292 * <p>The app-linking allows channel input sources to provide activity links from their live 2293 * channel programming to another activity. This enables content providers to increase user 2294 * engagement by offering the viewer other content or actions. 2295 * 2296 * <p>Type: INTEGER (color value) 2297 * @see #COLUMN_APP_LINK_ICON_URI 2298 * @see #COLUMN_APP_LINK_INTENT_URI 2299 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2300 * @see #COLUMN_APP_LINK_TEXT 2301 */ 2302 public static final String COLUMN_APP_LINK_COLOR = "app_link_color"; 2303 2304 /** 2305 * The intent URI of the app link for this channel. 2306 * 2307 * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME} 2308 * and converted back to the original intent with {@link Intent#parseUri}. The intent is 2309 * launched when the user clicks the corresponding app link for the current channel. 2310 * 2311 * <p>The app-linking allows channel input sources to provide activity links from their live 2312 * channel programming to another activity. This enables content providers to increase user 2313 * engagement by offering the viewer other content or actions. 2314 * 2315 * <p>Type: TEXT 2316 * @see #COLUMN_APP_LINK_COLOR 2317 * @see #COLUMN_APP_LINK_ICON_URI 2318 * @see #COLUMN_APP_LINK_POSTER_ART_URI 2319 * @see #COLUMN_APP_LINK_TEXT 2320 */ 2321 public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri"; 2322 2323 /** 2324 * The internal ID used by individual TV input services. 2325 * 2326 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2327 * apps. 2328 * 2329 * <p>Can be empty. 2330 * 2331 * <p>Type: TEXT 2332 */ 2333 public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id"; 2334 2335 /** 2336 * Internal data used by individual TV input services. 2337 * 2338 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2339 * apps. 2340 * 2341 * <p>Type: BLOB 2342 */ 2343 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 2344 2345 /** 2346 * Internal integer flag used by individual TV input services. 2347 * 2348 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2349 * apps. 2350 * 2351 * <p>Type: INTEGER 2352 */ 2353 public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1"; 2354 2355 /** 2356 * Internal integer flag used by individual TV input services. 2357 * 2358 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2359 * apps. 2360 * 2361 * <p>Type: INTEGER 2362 */ 2363 public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2"; 2364 2365 /** 2366 * Internal integer flag used by individual TV input services. 2367 * 2368 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2369 * apps. 2370 * 2371 * <p>Type: INTEGER 2372 */ 2373 public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3"; 2374 2375 /** 2376 * Internal integer flag used by individual TV input services. 2377 * 2378 * <p>This is internal to the provider that inserted it, and should not be decoded by other 2379 * apps. 2380 * 2381 * <p>Type: INTEGER 2382 */ 2383 public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4"; 2384 2385 /** 2386 * The version number of this row entry used by TV input services. 2387 * 2388 * <p>This is best used by sync adapters to identify the rows to update. The number can be 2389 * defined by individual TV input services. One may assign the same value as 2390 * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are 2391 * coming from a TV broadcast. 2392 * 2393 * <p>Type: INTEGER 2394 */ 2395 public static final String COLUMN_VERSION_NUMBER = "version_number"; 2396 2397 /** 2398 * The flag indicating whether this TV channel is transient or not. 2399 * 2400 * <p>A value of 1 indicates that the channel will be automatically removed by the system on 2401 * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not 2402 * specified, this value is set to 0 (not transient) by default. 2403 * 2404 * <p>Type: INTEGER (boolean) 2405 * @see PreviewPrograms#COLUMN_TRANSIENT 2406 * @see WatchNextPrograms#COLUMN_TRANSIENT 2407 */ 2408 public static final String COLUMN_TRANSIENT = "transient"; 2409 Channels()2410 private Channels() {} 2411 2412 /** 2413 * A sub-directory of a single TV channel that represents its primary logo. 2414 * 2415 * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw 2416 * channel URI. The resulting URI represents an image file, and should be interacted 2417 * using ContentResolver.openAssetFileDescriptor. 2418 * 2419 * <p>Note that this sub-directory also supports opening the logo as an asset file in write 2420 * mode. Callers can create or replace the primary logo associated with this channel by 2421 * opening the asset file and writing the full-size photo contents into it. (Make sure there 2422 * is no padding around the logo image.) When the file is closed, the image will be parsed, 2423 * sized down if necessary, and stored. 2424 * 2425 * <p>Usage example: 2426 * <pre> 2427 * public void writeChannelLogo(long channelId, byte[] logo) { 2428 * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId); 2429 * try { 2430 * AssetFileDescriptor fd = 2431 * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw"); 2432 * OutputStream os = fd.createOutputStream(); 2433 * os.write(logo); 2434 * os.close(); 2435 * fd.close(); 2436 * } catch (IOException e) { 2437 * // Handle error cases. 2438 * } 2439 * } 2440 * </pre> 2441 */ 2442 public static final class Logo { 2443 2444 /** 2445 * The directory twig for this sub-table. 2446 */ 2447 public static final String CONTENT_DIRECTORY = "logo"; 2448 Logo()2449 private Logo() {} 2450 } 2451 } 2452 2453 /** 2454 * Column definitions for the TV programs table. 2455 * 2456 * <p>By default, the query results will be sorted by 2457 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order. 2458 */ 2459 public static final class Programs implements BaseTvColumns, ProgramColumns { 2460 2461 /** 2462 * The content:// style URI for this table. 2463 * 2464 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2465 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2466 */ 2467 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2468 + PATH_PROGRAM); 2469 2470 /** The MIME type of a directory of TV programs. */ 2471 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program"; 2472 2473 /** The MIME type of a single TV program. */ 2474 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program"; 2475 2476 /** 2477 * The ID of the TV channel that provides this TV program. 2478 * 2479 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2480 * 2481 * <p>This is a required field. 2482 * 2483 * <p>Type: INTEGER (long) 2484 */ 2485 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2486 2487 /** 2488 * The season number of this TV program for episodic TV shows. 2489 * 2490 * <p>Can be empty. 2491 * 2492 * <p>Type: INTEGER 2493 * 2494 * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead. 2495 */ 2496 @Deprecated 2497 public static final String COLUMN_SEASON_NUMBER = "season_number"; 2498 2499 /** 2500 * The episode number of this TV program for episodic TV shows. 2501 * 2502 * <p>Can be empty. 2503 * 2504 * <p>Type: INTEGER 2505 * 2506 * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead. 2507 */ 2508 @Deprecated 2509 public static final String COLUMN_EPISODE_NUMBER = "episode_number"; 2510 2511 /** 2512 * The start time of this TV program, in milliseconds since the epoch. 2513 * 2514 * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the 2515 * previous program in the same channel. In practice, start time will usually be the end 2516 * time of the previous program. 2517 * 2518 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2519 * 2520 * <p>Type: INTEGER (long) 2521 */ 2522 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 2523 2524 /** 2525 * The end time of this TV program, in milliseconds since the epoch. 2526 * 2527 * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the 2528 * next program in the same channel. In practice, end time will usually be the start time of 2529 * the next program. 2530 * 2531 * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel. 2532 * 2533 * <p>Type: INTEGER (long) 2534 */ 2535 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 2536 2537 /** 2538 * The comma-separated genre string of this TV program. 2539 * 2540 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2541 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2542 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2543 * {@link Genres#encode} to create a text that can be stored in this column. Use 2544 * {@link Genres#decode} to get the broadcast genre strings from the text stored in the 2545 * column. 2546 * 2547 * <p>Type: TEXT 2548 * @see Genres#encode 2549 * @see Genres#decode 2550 */ 2551 public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre"; 2552 2553 /** 2554 * The flag indicating whether recording of this program is prohibited. 2555 * 2556 * <p>A value of 1 indicates that recording of this program is prohibited and application 2557 * will not schedule any recording for this program. A value of 0 indicates that the 2558 * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by 2559 * default. 2560 * 2561 * <p>Type: INTEGER (boolean) 2562 */ 2563 public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited"; 2564 Programs()2565 private Programs() {} 2566 2567 /** Canonical genres for TV programs. */ 2568 public static final class Genres { 2569 /** @hide */ 2570 @StringDef({ 2571 FAMILY_KIDS, 2572 SPORTS, 2573 SHOPPING, 2574 MOVIES, 2575 COMEDY, 2576 TRAVEL, 2577 DRAMA, 2578 EDUCATION, 2579 ANIMAL_WILDLIFE, 2580 NEWS, 2581 GAMING, 2582 ARTS, 2583 ENTERTAINMENT, 2584 LIFE_STYLE, 2585 MUSIC, 2586 PREMIER, 2587 TECH_SCIENCE, 2588 }) 2589 @Retention(RetentionPolicy.SOURCE) 2590 public @interface Genre {} 2591 2592 /** The genre for Family/Kids. */ 2593 public static final String FAMILY_KIDS = "FAMILY_KIDS"; 2594 2595 /** The genre for Sports. */ 2596 public static final String SPORTS = "SPORTS"; 2597 2598 /** The genre for Shopping. */ 2599 public static final String SHOPPING = "SHOPPING"; 2600 2601 /** The genre for Movies. */ 2602 public static final String MOVIES = "MOVIES"; 2603 2604 /** The genre for Comedy. */ 2605 public static final String COMEDY = "COMEDY"; 2606 2607 /** The genre for Travel. */ 2608 public static final String TRAVEL = "TRAVEL"; 2609 2610 /** The genre for Drama. */ 2611 public static final String DRAMA = "DRAMA"; 2612 2613 /** The genre for Education. */ 2614 public static final String EDUCATION = "EDUCATION"; 2615 2616 /** The genre for Animal/Wildlife. */ 2617 public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE"; 2618 2619 /** The genre for News. */ 2620 public static final String NEWS = "NEWS"; 2621 2622 /** The genre for Gaming. */ 2623 public static final String GAMING = "GAMING"; 2624 2625 /** The genre for Arts. */ 2626 public static final String ARTS = "ARTS"; 2627 2628 /** The genre for Entertainment. */ 2629 public static final String ENTERTAINMENT = "ENTERTAINMENT"; 2630 2631 /** The genre for Life Style. */ 2632 public static final String LIFE_STYLE = "LIFE_STYLE"; 2633 2634 /** The genre for Music. */ 2635 public static final String MUSIC = "MUSIC"; 2636 2637 /** The genre for Premier. */ 2638 public static final String PREMIER = "PREMIER"; 2639 2640 /** The genre for Tech/Science. */ 2641 public static final String TECH_SCIENCE = "TECH_SCIENCE"; 2642 2643 private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>(); 2644 static { 2645 CANONICAL_GENRES.add(FAMILY_KIDS); 2646 CANONICAL_GENRES.add(SPORTS); 2647 CANONICAL_GENRES.add(SHOPPING); 2648 CANONICAL_GENRES.add(MOVIES); 2649 CANONICAL_GENRES.add(COMEDY); 2650 CANONICAL_GENRES.add(TRAVEL); 2651 CANONICAL_GENRES.add(DRAMA); 2652 CANONICAL_GENRES.add(EDUCATION); 2653 CANONICAL_GENRES.add(ANIMAL_WILDLIFE); 2654 CANONICAL_GENRES.add(NEWS); 2655 CANONICAL_GENRES.add(GAMING); 2656 CANONICAL_GENRES.add(ARTS); 2657 CANONICAL_GENRES.add(ENTERTAINMENT); 2658 CANONICAL_GENRES.add(LIFE_STYLE); 2659 CANONICAL_GENRES.add(MUSIC); 2660 CANONICAL_GENRES.add(PREMIER); 2661 CANONICAL_GENRES.add(TECH_SCIENCE); 2662 } 2663 2664 private static final char DOUBLE_QUOTE = '"'; 2665 private static final char COMMA = ','; 2666 private static final String DELIMITER = ","; 2667 2668 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 2669 Genres()2670 private Genres() {} 2671 2672 /** 2673 * Encodes genre strings to a text that can be put into the database. 2674 * 2675 * @param genres Genre strings. 2676 * @return an encoded genre string that can be inserted into the 2677 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2678 */ encode(@onNull @enre String... genres)2679 public static String encode(@NonNull @Genre String... genres) { 2680 if (genres == null) { 2681 // MNC and before will throw a NPE. 2682 return null; 2683 } 2684 StringBuilder sb = new StringBuilder(); 2685 String separator = ""; 2686 for (String genre : genres) { 2687 sb.append(separator).append(encodeToCsv(genre)); 2688 separator = DELIMITER; 2689 } 2690 return sb.toString(); 2691 } 2692 encodeToCsv(String genre)2693 private static String encodeToCsv(String genre) { 2694 StringBuilder sb = new StringBuilder(); 2695 int length = genre.length(); 2696 for (int i = 0; i < length; ++i) { 2697 char c = genre.charAt(i); 2698 switch (c) { 2699 case DOUBLE_QUOTE: 2700 sb.append(DOUBLE_QUOTE); 2701 break; 2702 case COMMA: 2703 sb.append(DOUBLE_QUOTE); 2704 break; 2705 } 2706 sb.append(c); 2707 } 2708 return sb.toString(); 2709 } 2710 2711 /** 2712 * Decodes the genre strings from the text stored in the database. 2713 * 2714 * @param genres The encoded genre string retrieved from the 2715 * {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column. 2716 * @return genre strings. 2717 */ decode(@onNull String genres)2718 public static @Genre String[] decode(@NonNull String genres) { 2719 if (TextUtils.isEmpty(genres)) { 2720 // MNC and before will throw a NPE for {@code null} genres. 2721 return EMPTY_STRING_ARRAY; 2722 } 2723 if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) { 2724 return new String[] {genres.trim()}; 2725 } 2726 StringBuilder sb = new StringBuilder(); 2727 List<String> results = new ArrayList<>(); 2728 int length = genres.length(); 2729 boolean escape = false; 2730 for (int i = 0; i < length; ++i) { 2731 char c = genres.charAt(i); 2732 switch (c) { 2733 case DOUBLE_QUOTE: 2734 if (!escape) { 2735 escape = true; 2736 continue; 2737 } 2738 break; 2739 case COMMA: 2740 if (!escape) { 2741 String string = sb.toString().trim(); 2742 if (string.length() > 0) { 2743 results.add(string); 2744 } 2745 sb = new StringBuilder(); 2746 continue; 2747 } 2748 break; 2749 } 2750 sb.append(c); 2751 escape = false; 2752 } 2753 String string = sb.toString().trim(); 2754 if (string.length() > 0) { 2755 results.add(string); 2756 } 2757 return results.toArray(new String[results.size()]); 2758 } 2759 2760 /** 2761 * Returns whether a given text is a canonical genre defined in {@link Genres}. 2762 * 2763 * @param genre The name of genre to be checked. 2764 * @return {@code true} if the genre is canonical, otherwise {@code false}. 2765 */ isCanonical(String genre)2766 public static boolean isCanonical(String genre) { 2767 return CANONICAL_GENRES.contains(genre); 2768 } 2769 } 2770 } 2771 2772 /** 2773 * Column definitions for the recorded TV programs table. 2774 * 2775 * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in 2776 * ascending order. 2777 */ 2778 public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns { 2779 2780 /** 2781 * The content:// style URI for this table. 2782 * 2783 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2784 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2785 */ 2786 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2787 + PATH_RECORDED_PROGRAM); 2788 2789 /** The MIME type of a directory of recorded TV programs. */ 2790 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program"; 2791 2792 /** The MIME type of a single recorded TV program. */ 2793 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program"; 2794 2795 /** 2796 * The ID of the TV channel that provides this recorded program. 2797 * 2798 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2799 * 2800 * <p>Type: INTEGER (long) 2801 */ 2802 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2803 2804 /** 2805 * The ID of the TV input service that is associated with this recorded program. 2806 * 2807 * <p>Use {@link #buildInputId} to build the ID. 2808 * 2809 * <p>This is a required field. 2810 * 2811 * <p>Type: TEXT 2812 */ 2813 public static final String COLUMN_INPUT_ID = "input_id"; 2814 2815 /** 2816 * The start time of the original TV program, in milliseconds since the epoch. 2817 * 2818 * <p>Type: INTEGER (long) 2819 * @see Programs#COLUMN_START_TIME_UTC_MILLIS 2820 */ 2821 public static final String COLUMN_START_TIME_UTC_MILLIS = 2822 Programs.COLUMN_START_TIME_UTC_MILLIS; 2823 2824 /** 2825 * The end time of the original TV program, in milliseconds since the epoch. 2826 * 2827 * <p>Type: INTEGER (long) 2828 * @see Programs#COLUMN_END_TIME_UTC_MILLIS 2829 */ 2830 public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS; 2831 2832 /** 2833 * The comma-separated genre string of this recorded TV program. 2834 * 2835 * <p>Use the same language appeared in the underlying broadcast standard, if applicable. 2836 * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 2837 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use 2838 * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column. 2839 * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the 2840 * text stored in the column. 2841 * 2842 * <p>Type: TEXT 2843 * @see Programs#COLUMN_BROADCAST_GENRE 2844 */ 2845 public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE; 2846 2847 /** 2848 * The URI of the recording data for this recorded program. 2849 * 2850 * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this 2851 * information to manage recording storage. The URI should indicate a file or directory with 2852 * the scheme {@link android.content.ContentResolver#SCHEME_FILE}. 2853 * 2854 * <p>Type: TEXT 2855 * @see #COLUMN_RECORDING_DATA_BYTES 2856 */ 2857 public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri"; 2858 2859 /** 2860 * The data size (in bytes) for this recorded program. 2861 * 2862 * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this 2863 * information to manage recording storage. 2864 * 2865 * <p>Type: INTEGER (long) 2866 * @see #COLUMN_RECORDING_DATA_URI 2867 */ 2868 public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes"; 2869 2870 /** 2871 * The duration (in milliseconds) of this recorded program. 2872 * 2873 * <p>The actual duration of the recorded program can differ from the one calculated by 2874 * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program 2875 * recording can be interrupted in the middle for some reason, resulting in a partially 2876 * recorded program, which is still playable. 2877 * 2878 * <p>Type: INTEGER 2879 */ 2880 public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis"; 2881 2882 /** 2883 * The expiration time for this recorded program, in milliseconds since the epoch. 2884 * 2885 * <p>Recorded TV programs do not expire by default unless explicitly requested by the user 2886 * or the user allows applications to delete them in order to free up disk space for future 2887 * recording. However, some TV content can have expiration date set by the content provider 2888 * when recorded. This field is used to indicate such a restriction. 2889 * 2890 * <p>Can be empty. 2891 * 2892 * <p>Type: INTEGER (long) 2893 */ 2894 public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = 2895 "recording_expire_time_utc_millis"; 2896 RecordedPrograms()2897 private RecordedPrograms() {} 2898 } 2899 2900 /** 2901 * Column definitions for the preview TV programs table. 2902 */ 2903 public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns, 2904 PreviewProgramColumns { 2905 2906 /** 2907 * The content:// style URI for this table. 2908 * 2909 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2910 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2911 */ 2912 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2913 + PATH_PREVIEW_PROGRAM); 2914 2915 /** The MIME type of a directory of preview TV programs. */ 2916 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program"; 2917 2918 /** The MIME type of a single preview TV program. */ 2919 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program"; 2920 2921 /** 2922 * The ID of the TV channel that provides this TV program. 2923 * 2924 * <p>This value cannot be changed once it's set. Trying to modify it will make the update 2925 * fail. 2926 * 2927 * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 2928 * 2929 * <p>This is a required field. 2930 * 2931 * <p>Type: INTEGER (long) 2932 */ 2933 public static final String COLUMN_CHANNEL_ID = "channel_id"; 2934 2935 /** 2936 * The weight of the preview program within the channel. 2937 * 2938 * <p>The UI may choose to show this item in a different position in the channel row. 2939 * A larger weight value means the program is more important than other programs having 2940 * smaller weight values. The value is relevant for the preview programs in the same 2941 * channel. This is only relevant to {@link Channels#TYPE_PREVIEW}. 2942 * 2943 * <p>Can be empty. 2944 * 2945 * <p>Type: INTEGER 2946 */ 2947 public static final String COLUMN_WEIGHT = "weight"; 2948 PreviewPrograms()2949 private PreviewPrograms() {} 2950 } 2951 2952 /** 2953 * Column definitions for the "watch next" TV programs table. 2954 */ 2955 public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns, 2956 PreviewProgramColumns { 2957 2958 /** 2959 * The content:// style URI for this table. 2960 * 2961 * <p>SQL selection is not supported for {@link ContentResolver#query}, 2962 * {@link ContentResolver#update} and {@link ContentResolver#delete} operations. 2963 */ 2964 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 2965 + PATH_WATCH_NEXT_PROGRAM); 2966 2967 /** The MIME type of a directory of "watch next" TV programs. */ 2968 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program"; 2969 2970 /** The MIME type of a single preview TV program. */ 2971 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program"; 2972 2973 /** @hide */ 2974 @IntDef({ 2975 WATCH_NEXT_TYPE_CONTINUE, 2976 WATCH_NEXT_TYPE_NEXT, 2977 WATCH_NEXT_TYPE_NEW, 2978 WATCH_NEXT_TYPE_WATCHLIST, 2979 }) 2980 @Retention(RetentionPolicy.SOURCE) 2981 public @interface WatchNextType {} 2982 2983 /** 2984 * The watch next type for CONTINUE. Use this type when the user has already watched more 2985 * than 1 minute of this content. 2986 * 2987 * @see #COLUMN_WATCH_NEXT_TYPE 2988 */ 2989 public static final int WATCH_NEXT_TYPE_CONTINUE = 0; 2990 2991 /** 2992 * The watch next type for NEXT. Use this type when the user has watched one or more 2993 * complete episodes from some episodic content, but there remains more than one episode 2994 * remaining or there is one last episode remaining, but it is not “new” in that it was 2995 * released before the user started watching the show. 2996 * 2997 * @see #COLUMN_WATCH_NEXT_TYPE 2998 */ 2999 public static final int WATCH_NEXT_TYPE_NEXT = 1; 3000 3001 /** 3002 * The watch next type for NEW. Use this type when the user had watched all of the available 3003 * episodes from some episodic content, but a new episode became available since the user 3004 * started watching the first episode and now there is exactly one unwatched episode. This 3005 * could also work for recorded events in a series e.g. soccer matches or football games. 3006 * 3007 * @see #COLUMN_WATCH_NEXT_TYPE 3008 */ 3009 public static final int WATCH_NEXT_TYPE_NEW = 2; 3010 3011 /** 3012 * The watch next type for WATCHLIST. Use this type when the user has elected to explicitly 3013 * add a movie, event or series to a “watchlist” as a manual way of curating what they 3014 * want to watch next. 3015 * 3016 * @see #COLUMN_WATCH_NEXT_TYPE 3017 */ 3018 public static final int WATCH_NEXT_TYPE_WATCHLIST = 3; 3019 3020 /** 3021 * The "watch next" type of this program content. 3022 * 3023 * <p>The value should match one of the followings: 3024 * {@link #WATCH_NEXT_TYPE_CONTINUE}, 3025 * {@link #WATCH_NEXT_TYPE_NEXT}, 3026 * {@link #WATCH_NEXT_TYPE_NEW}, and 3027 * {@link #WATCH_NEXT_TYPE_WATCHLIST}. 3028 * 3029 * <p>This is a required field. 3030 * 3031 * <p>Type: INTEGER 3032 */ 3033 public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type"; 3034 3035 /** 3036 * The last UTC time that the user engaged in this TV program, in milliseconds since the 3037 * epoch. This is a hint for the application that is used for ordering of "watch next" 3038 * programs. 3039 * 3040 * <p>The meaning of the value varies depending on the {@link #COLUMN_WATCH_NEXT_TYPE}: 3041 * <ul> 3042 * <li>{@link #WATCH_NEXT_TYPE_CONTINUE}: the date that the user was last watching the 3043 * content.</li> 3044 * <li>{@link #WATCH_NEXT_TYPE_NEXT}: the date of the last episode watched.</li> 3045 * <li>{@link #WATCH_NEXT_TYPE_NEW}: the release date of the new episode.</li> 3046 * <li>{@link #WATCH_NEXT_TYPE_WATCHLIST}: the date the item was added to the Watchlist. 3047 * </li> 3048 * </ul> 3049 * 3050 * <p>This is a required field. 3051 * 3052 * <p>Type: INTEGER (long) 3053 */ 3054 public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = 3055 "last_engagement_time_utc_millis"; 3056 WatchNextPrograms()3057 private WatchNextPrograms() {} 3058 } 3059 3060 /** 3061 * Column definitions for the TV programs that the user watched. Applications do not have access 3062 * to this table. 3063 * 3064 * <p>By default, the query results will be sorted by 3065 * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order. 3066 * @hide 3067 */ 3068 @SystemApi 3069 public static final class WatchedPrograms implements BaseTvColumns { 3070 3071 /** The content:// style URI for this table. */ 3072 public static final Uri CONTENT_URI = 3073 Uri.parse("content://" + AUTHORITY + "/watched_program"); 3074 3075 /** The MIME type of a directory of watched programs. */ 3076 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program"; 3077 3078 /** The MIME type of a single item in this table. */ 3079 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program"; 3080 3081 /** 3082 * The UTC time that the user started watching this TV program, in milliseconds since the 3083 * epoch. 3084 * 3085 * <p>Type: INTEGER (long) 3086 */ 3087 public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS = 3088 "watch_start_time_utc_millis"; 3089 3090 /** 3091 * The UTC time that the user stopped watching this TV program, in milliseconds since the 3092 * epoch. 3093 * 3094 * <p>Type: INTEGER (long) 3095 */ 3096 public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis"; 3097 3098 /** 3099 * The ID of the TV channel that provides this TV program. 3100 * 3101 * <p>This is a required field. 3102 * 3103 * <p>Type: INTEGER (long) 3104 */ 3105 public static final String COLUMN_CHANNEL_ID = "channel_id"; 3106 3107 /** 3108 * The title of this TV program. 3109 * 3110 * <p>Type: TEXT 3111 */ 3112 public static final String COLUMN_TITLE = "title"; 3113 3114 /** 3115 * The start time of this TV program, in milliseconds since the epoch. 3116 * 3117 * <p>Type: INTEGER (long) 3118 */ 3119 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 3120 3121 /** 3122 * The end time of this TV program, in milliseconds since the epoch. 3123 * 3124 * <p>Type: INTEGER (long) 3125 */ 3126 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 3127 3128 /** 3129 * The description of this TV program. 3130 * 3131 * <p>Type: TEXT 3132 */ 3133 public static final String COLUMN_DESCRIPTION = "description"; 3134 3135 /** 3136 * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle) 3137 * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that 3138 * provides this TV program. (Used internally.) 3139 * 3140 * <p>This column contains an encoded string that represents comma-separated key-value pairs of 3141 * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape 3142 * character for '%', '=', and ','. 3143 * 3144 * <p>Type: TEXT 3145 */ 3146 public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params"; 3147 3148 /** 3149 * The session token of this TV program. (Used internally.) 3150 * 3151 * <p>This contains a String representation of {@link IBinder} for 3152 * {@link TvInputService.Session} that provides the current TV program. It is used 3153 * internally to distinguish watched programs entries from different TV input sessions. 3154 * 3155 * <p>Type: TEXT 3156 */ 3157 public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token"; 3158 WatchedPrograms()3159 private WatchedPrograms() {} 3160 } 3161 } 3162