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