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