TvContract.java revision 0e33c1286d984555802f6b2b81ace9b6021c2d9f
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.media.tv; 18 19import android.content.ComponentName; 20import android.content.ContentResolver; 21import android.content.ContentUris; 22import android.net.Uri; 23import android.provider.BaseColumns; 24 25import java.util.HashMap; 26import java.util.List; 27import java.util.Map; 28 29/** 30 * <p> 31 * The contract between the TV provider and applications. Contains definitions for the supported 32 * URIs and columns. 33 * </p> 34 * <h3>Overview</h3> 35 * <p> 36 * TvContract defines a basic database of TV content metadata such as channel and program 37 * information. The information is stored in {@link Channels} and {@link Programs} tables. 38 * </p> 39 * <ul> 40 * <li>A row in the {@link Channels} table represents information about a TV channel. The data 41 * format can vary greatly from standard to standard or according to service provider, thus 42 * the columns here are mostly comprised of basic entities that are usually seen to users 43 * regardless of standard such as channel number and name.</li> 44 * <li>A row in the {@link Programs} table represents a set of data describing a TV program such 45 * as program title and start time.</li> 46 * </ul> 47 */ 48public final class TvContract { 49 /** The authority for the TV provider. */ 50 public static final String AUTHORITY = "android.media.tv"; 51 52 private static final String PATH_CHANNEL = "channel"; 53 private static final String PATH_PROGRAM = "program"; 54 private static final String PATH_INPUT = "input"; 55 56 /** 57 * An optional query, update or delete URI parameter that allows the caller to specify start 58 * time (in milliseconds since the epoch) to filter programs. 59 * 60 * @hide 61 */ 62 public static final String PARAM_START_TIME = "start_time"; 63 64 /** 65 * An optional query, update or delete URI parameter that allows the caller to specify end time 66 * (in milliseconds since the epoch) to filter programs. 67 * 68 * @hide 69 */ 70 public static final String PARAM_END_TIME = "end_time"; 71 72 /** 73 * A query, update or delete URI parameter that allows the caller to operate on all or 74 * browsable-only channels. If set to "true", the rows that contain non-browsable channels are 75 * not affected. 76 * 77 * @hide 78 */ 79 public static final String PARAM_BROWSABLE_ONLY = "browsable_only"; 80 81 /** 82 * Builds a URI that points to a specific channel. 83 * 84 * @param channelId The ID of the channel to point to. 85 */ 86 public static final Uri buildChannelUri(long channelId) { 87 return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId); 88 } 89 90 /** 91 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 92 * 93 * @param channelId The ID of the channel whose logo is pointed to. 94 */ 95 public static final Uri buildChannelLogoUri(long channelId) { 96 return buildChannelLogoUri(buildChannelUri(channelId)); 97 } 98 99 /** 100 * Builds a URI that points to a channel logo. See {@link Channels.Logo}. 101 * 102 * @param channelUri The URI of the channel whose logo is pointed to. 103 */ 104 public static final Uri buildChannelLogoUri(Uri channelUri) { 105 if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) { 106 throw new IllegalArgumentException("Not a channel: " + channelUri); 107 } 108 return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY); 109 } 110 111 /** 112 * Builds a URI that points to all browsable channels from a given TV input. 113 * 114 * @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that 115 * implements the given TV input. 116 */ 117 public static final Uri buildChannelsUriForInput(ComponentName name) { 118 return buildChannelsUriForInput(name, true); 119 } 120 121 /** 122 * Builds a URI that points to all or browsable-only channels from a given TV input. 123 * 124 * @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that 125 * implements the given TV input. 126 * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set 127 * to {@code false} the URI points to all channels regardless of whether they are 128 * browsable or not. 129 */ 130 public static final Uri buildChannelsUriForInput(ComponentName name, boolean browsableOnly) { 131 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY) 132 .appendPath(PATH_INPUT).appendPath(name.getPackageName()) 133 .appendPath(name.getClassName()).appendPath(PATH_CHANNEL) 134 .appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)).build(); 135 } 136 137 /** 138 * Builds a URI that points to a specific program. 139 * 140 * @param programId The ID of the program to point to. 141 */ 142 public static final Uri buildProgramUri(long programId) { 143 return ContentUris.withAppendedId(Programs.CONTENT_URI, programId); 144 } 145 146 /** 147 * Builds a URI that points to all programs on a given channel. 148 * 149 * @param channelId The ID of the channel to return programs for. 150 */ 151 public static final Uri buildProgramsUriForChannel(long channelId) { 152 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY) 153 .appendPath(PATH_CHANNEL).appendPath(String.valueOf(channelId)) 154 .appendPath(PATH_PROGRAM).build(); 155 } 156 157 /** 158 * Builds a URI that points to all programs on a given channel. 159 * 160 * @param channelUri The URI of the channel to return programs for. 161 */ 162 public static final Uri buildProgramsUriForChannel(Uri channelUri) { 163 if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) { 164 throw new IllegalArgumentException("Not a channel: " + channelUri); 165 } 166 return buildProgramsUriForChannel(ContentUris.parseId(channelUri)); 167 } 168 169 /** 170 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 171 * given time frame. 172 * 173 * @param channelId The ID of the channel to return programs for. 174 * @param startTime The start time used to filter programs. The returned programs should have 175 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 176 * @param endTime The end time used to filter programs. The returned programs should have 177 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 178 */ 179 public static final Uri buildProgramsUriForChannel(long channelId, long startTime, 180 long endTime) { 181 Uri uri = buildProgramsUriForChannel(channelId); 182 return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime)) 183 .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build(); 184 } 185 186 /** 187 * Builds a URI that points to programs on a specific channel whose schedules overlap with the 188 * given time frame. 189 * 190 * @param channelUri The URI of the channel to return programs for. 191 * @param startTime The start time used to filter programs. The returned programs should have 192 * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time. 193 * @param endTime The end time used to filter programs. The returned programs should have 194 * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time. 195 */ 196 public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime, 197 long endTime) { 198 if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) { 199 throw new IllegalArgumentException("Not a channel: " + channelUri); 200 } 201 return buildProgramsUriForChannel(ContentUris.parseId(channelUri), startTime, endTime); 202 } 203 204 /** 205 * Builds a URI that points to a specific program the user watched. 206 * 207 * @param watchedProgramId The ID of the watched program to point to. 208 * @hide 209 */ 210 public static final Uri buildWatchedProgramUri(long watchedProgramId) { 211 return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId); 212 } 213 214 /** 215 * Extracts the {@link Channels#COLUMN_PACKAGE_NAME} from a given URI. 216 * 217 * @param channelsUri A URI constructed by {@link #buildChannelsUriForInput(ComponentName)} or 218 * {@link #buildChannelsUriForInput(ComponentName, boolean)}. 219 * @hide 220 */ 221 public static final String getPackageName(Uri channelsUri) { 222 final List<String> paths = channelsUri.getPathSegments(); 223 if (paths.size() < 4) { 224 throw new IllegalArgumentException("Not channels: " + channelsUri); 225 } 226 if (!PATH_INPUT.equals(paths.get(0)) || !PATH_CHANNEL.equals(paths.get(3))) { 227 throw new IllegalArgumentException("Not channels: " + channelsUri); 228 } 229 return paths.get(1); 230 } 231 232 /** 233 * Extracts the {@link Channels#COLUMN_SERVICE_NAME} from a given URI. 234 * 235 * @param channelsUri A URI constructed by {@link #buildChannelsUriForInput(ComponentName)} or 236 * {@link #buildChannelsUriForInput(ComponentName, boolean)}. 237 * @hide 238 */ 239 public static final String getServiceName(Uri channelsUri) { 240 final List<String> paths = channelsUri.getPathSegments(); 241 if (paths.size() < 4) { 242 throw new IllegalArgumentException("Not channels: " + channelsUri); 243 } 244 if (!PATH_INPUT.equals(paths.get(0)) || !PATH_CHANNEL.equals(paths.get(3))) { 245 throw new IllegalArgumentException("Not channels: " + channelsUri); 246 } 247 return paths.get(2); 248 } 249 250 /** 251 * Extracts the {@link Channels#_ID} from a given URI. 252 * 253 * @param programsUri A URI constructed by {@link #buildProgramsUriForChannel(Uri)} or 254 * {@link #buildProgramsUriForChannel(Uri, long, long)}. 255 * @hide 256 */ 257 public static final String getChannelId(Uri programsUri) { 258 final List<String> paths = programsUri.getPathSegments(); 259 if (paths.size() < 3) { 260 throw new IllegalArgumentException("Not programs: " + programsUri); 261 } 262 if (!PATH_CHANNEL.equals(paths.get(0)) || !PATH_PROGRAM.equals(paths.get(2))) { 263 throw new IllegalArgumentException("Not programs: " + programsUri); 264 } 265 return paths.get(1); 266 } 267 268 269 private TvContract() {} 270 271 /** 272 * Common base for the tables of TV channels/programs. 273 */ 274 public interface BaseTvColumns extends BaseColumns { 275 /** 276 * The name of the package that owns a row in each table. 277 * <p> 278 * The TV provider fills it in with the name of the package that provides the initial data 279 * of that row. If the package is later uninstalled, the rows it owns are automatically 280 * removed from the tables. 281 * </p><p> 282 * Type: TEXT 283 * </p> 284 */ 285 public static final String COLUMN_PACKAGE_NAME = "package_name"; 286 } 287 288 /** Column definitions for the TV channels table. */ 289 public static final class Channels implements BaseTvColumns { 290 291 /** The content:// style URI for this table. */ 292 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 293 + PATH_CHANNEL); 294 295 /** The MIME type of a directory of TV channels. */ 296 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel"; 297 298 /** The MIME type of a single TV channel. */ 299 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel"; 300 301 /** A generic channel type. */ 302 public static final int TYPE_OTHER = 0x0; 303 304 /** The channel type for NTSC. */ 305 public static final int TYPE_NTSC = 0x1; 306 307 /** The channel type for PAL. */ 308 public static final int TYPE_PAL = 0x2; 309 310 /** The channel type for SECAM. */ 311 public static final int TYPE_SECAM = 0x3; 312 313 /** The special channel type used for pass-through inputs such as HDMI. */ 314 public static final int TYPE_PASSTHROUGH = 0x00010000; 315 316 /** The channel type for DVB-T (terrestrial). */ 317 public static final int TYPE_DVB_T = 0x00020000; 318 319 /** The channel type for DVB-T2 (terrestrial). */ 320 public static final int TYPE_DVB_T2 = 0x00020001; 321 322 /** The channel type for DVB-S (satellite). */ 323 public static final int TYPE_DVB_S = 0x00020100; 324 325 /** The channel type for DVB-S2 (satellite). */ 326 public static final int TYPE_DVB_S2 = 0x00020101; 327 328 /** The channel type for DVB-C (cable). */ 329 public static final int TYPE_DVB_C = 0x00020200; 330 331 /** The channel type for DVB-C2 (cable). */ 332 public static final int TYPE_DVB_C2 = 0x00020201; 333 334 /** The channel type for DVB-H (handheld). */ 335 public static final int TYPE_DVB_H = 0x00020300; 336 337 /** The channel type for DVB-SH (satellite). */ 338 public static final int TYPE_DVB_SH = 0x00020400; 339 340 /** The channel type for ATSC (terrestrial). */ 341 public static final int TYPE_ATSC_T = 0x00030000; 342 343 /** The channel type for ATSC (cable). */ 344 public static final int TYPE_ATSC_C = 0x00030200; 345 346 /** The channel type for ATSC-M/H (mobile/handheld). */ 347 public static final int TYPE_ATSC_M_H = 0x00030300; 348 349 /** The channel type for ISDB-T (terrestrial). */ 350 public static final int TYPE_ISDB_T = 0x00040000; 351 352 /** The channel type for ISDB-Tb (Brazil). */ 353 public static final int TYPE_ISDB_TB = 0x00040100; 354 355 /** The channel type for ISDB-S (satellite). */ 356 public static final int TYPE_ISDB_S = 0x00040200; 357 358 /** The channel type for ISDB-C (cable). */ 359 public static final int TYPE_ISDB_C = 0x00040300; 360 361 /** The channel type for 1seg (handheld). */ 362 public static final int TYPE_1SEG = 0x00040400; 363 364 /** The channel type for DTMB (terrestrial). */ 365 public static final int TYPE_DTMB = 0x00050000; 366 367 /** The channel type for CMMB (handheld). */ 368 public static final int TYPE_CMMB = 0x00050100; 369 370 /** The channel type for T-DMB (terrestrial). */ 371 public static final int TYPE_T_DMB = 0x00060000; 372 373 /** The channel type for S-DMB (satellite). */ 374 public static final int TYPE_S_DMB = 0x00060100; 375 376 /** A generic service type. */ 377 public static final int SERVICE_TYPE_OTHER = 0x0; 378 379 /** The service type for regular TV channels that have both audio and video. */ 380 public static final int SERVICE_TYPE_AUDIO_VIDEO = 0x1; 381 382 /** The service type for radio channels that have audio only. */ 383 public static final int SERVICE_TYPE_AUDIO = 0x2; 384 385 /** The video format for 240p. */ 386 public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P"; 387 388 /** The video format for 360p. */ 389 public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P"; 390 391 /** The video format for 480i. */ 392 public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I"; 393 394 /** The video format for 480p. */ 395 public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P"; 396 397 /** The video format for 576i. */ 398 public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I"; 399 400 /** The video format for 576p. */ 401 public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P"; 402 403 /** The video format for 720p. */ 404 public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P"; 405 406 /** The video format for 1080i. */ 407 public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I"; 408 409 /** The video format for 1080p. */ 410 public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P"; 411 412 /** The video format for 2160p. */ 413 public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P"; 414 415 /** The video format for 4320p. */ 416 public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P"; 417 418 /** The video resolution for standard-definition. */ 419 public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD"; 420 421 /** The video resolution for enhanced-definition. */ 422 public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED"; 423 424 /** The video resolution for high-definition. */ 425 public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD"; 426 427 /** The video resolution for full high-definition. */ 428 public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD"; 429 430 /** The video resolution for ultra high-definition. */ 431 public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD"; 432 433 private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = 434 new HashMap<String, String>(); 435 436 static { 437 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD); 438 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED); 439 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD); 440 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED); 441 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD); 442 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD); 443 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD); 444 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD); 445 VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD); 446 } 447 448 /** 449 * Returns the video resolution (definition) for a given video format. 450 * 451 * @param videoFormat The video format defined in {@link Channels}. 452 * @return the corresponding video resolution string. {@code null} if the resolution string 453 * is not defined for the given video format. 454 * @see #COLUMN_VIDEO_FORMAT 455 */ 456 public static final String getVideoResolution(String videoFormat) { 457 return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat); 458 } 459 460 /** 461 * The name of the {@link TvInputService} subclass that provides this TV channel. This 462 * should be a fully qualified class name (such as, "com.example.project.TvInputService"). 463 * <p> 464 * This is a required field. 465 * </p><p> 466 * Type: TEXT 467 * </p> 468 */ 469 public static final String COLUMN_SERVICE_NAME = "service_name"; 470 471 /** 472 * The predefined type of this TV channel. 473 * <p> 474 * This is primarily used to indicate which broadcast standard (e.g. ATSC, DVB or ISDB) the 475 * current channel conforms to, with an exception being {@link #TYPE_PASSTHROUGH}, which is 476 * a special channel type used only by pass-through inputs such as HDMI. The value should 477 * match to one of the followings: {@link #TYPE_OTHER}, {@link #TYPE_PASSTHROUGH}, 478 * {@link #TYPE_DVB_T}, {@link #TYPE_DVB_T2}, {@link #TYPE_DVB_S}, {@link #TYPE_DVB_S2}, 479 * {@link #TYPE_DVB_C}, {@link #TYPE_DVB_C2}, {@link #TYPE_DVB_H}, {@link #TYPE_DVB_SH}, 480 * {@link #TYPE_ATSC_T}, {@link #TYPE_ATSC_C}, {@link #TYPE_ATSC_M_H}, {@link #TYPE_ISDB_T}, 481 * {@link #TYPE_ISDB_TB}, {@link #TYPE_ISDB_S}, {@link #TYPE_ISDB_C} {@link #TYPE_1SEG}, 482 * {@link #TYPE_DTMB}, {@link #TYPE_CMMB}, {@link #TYPE_T_DMB}, {@link #TYPE_S_DMB} 483 * </p><p> 484 * This is a required field. 485 * </p><p> 486 * Type: INTEGER 487 * </p> 488 */ 489 public static final String COLUMN_TYPE = "type"; 490 491 /** 492 * The predefined service type of this TV channel. 493 * <p> 494 * This is primarily used to indicate whether the current channel is a regular TV channel or 495 * a radio-like channel. Use the same coding for {@code service_type} in the underlying 496 * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB 497 * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER}, 498 * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO} 499 * </p><p> 500 * This is a required field. 501 * </p><p> 502 * Type: INTEGER 503 * </p> 504 */ 505 public static final String COLUMN_SERVICE_TYPE = "service_type"; 506 507 /** 508 * The original network ID of this TV channel. 509 * <p> 510 * This is used to identify the originating delivery system, if applicable. Use the same 511 * coding for {@code original_network_id} in the underlying broadcast standard if it is 512 * defined there (e.g. ETSI EN 300 468/TR 101 211 and ARIB STD-B10). If channels cannot be 513 * globally identified by 2-tuple {{@link #COLUMN_TRANSPORT_STREAM_ID}, 514 * {@link #COLUMN_SERVICE_ID}}, one must carefully assign a value to this field to form a 515 * unique 3-tuple identification {{@link #COLUMN_ORIGINAL_NETWORK_ID}, 516 * {@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}} for its channels. 517 * </p><p> 518 * This is a required field if the channel cannot be uniquely identified by a 2-tuple 519 * {{@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}}. 520 * </p><p> 521 * Type: INTEGER 522 * </p> 523 */ 524 public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; 525 526 /** 527 * The transport stream ID of this channel. 528 * <p> 529 * This is used to identify the Transport Stream that contains the current channel from any 530 * other multiplex within a network, if applicable. Use the same coding for 531 * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via 532 * the MPEG Transport Stream as is the case for many digital broadcast standards. 533 * </p><p> 534 * This is a required field if the current channel is transmitted via the MPEG Transport 535 * Stream. 536 * </p><p> 537 * Type: INTEGER 538 * </p> 539 */ 540 public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; 541 542 /** 543 * The service ID of this channel. 544 * <p> 545 * This is used to identify the current service (roughly equivalent to channel) from any 546 * other service within the Transport Stream, if applicable. Use the same coding for 547 * {@code service_id} in the underlying broadcast standard if it is defined there (e.g. ETSI 548 * EN 300 468 and ARIB STD-B10) or {@code program_number} (which usually has the same value 549 * as {@code service_id}) in ISO/IEC 13818-1 if the channel is transmitted via the MPEG 550 * Transport Stream. 551 * </p><p> 552 * This is a required field if the current channel is transmitted via the MPEG Transport 553 * Stream. 554 * </p><p> 555 * Type: INTEGER 556 * </p> 557 */ 558 public static final String COLUMN_SERVICE_ID = "service_id"; 559 560 /** 561 * The channel number that is displayed to the user. 562 * <p> 563 * The format can vary depending on broadcast standard and product specification. 564 * </p><p> 565 * Type: TEXT 566 * </p> 567 */ 568 public static final String COLUMN_DISPLAY_NUMBER = "display_number"; 569 570 /** 571 * The channel name that is displayed to the user. 572 * <p> 573 * A call sign is a good candidate to use for this purpose but any name that helps the user 574 * recognize the current channel will be enough. Can also be empty depending on broadcast 575 * standard. 576 * </p><p> 577 * Type: TEXT 578 * </p> 579 */ 580 public static final String COLUMN_DISPLAY_NAME = "display_name"; 581 582 /** 583 * The description of this TV channel. 584 * <p> 585 * Can be empty initially. 586 * </p><p> 587 * Type: TEXT 588 * </p> 589 */ 590 public static final String COLUMN_DESCRIPTION = "description"; 591 592 /** 593 * The typical video format for programs from this TV channel. 594 * <p> 595 * This is primarily used to filter out channels based on video format by applications. The 596 * value should match one of the followings: {@link #VIDEO_FORMAT_240P}, 597 * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P}, 598 * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P}, 599 * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P}, 600 * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a 601 * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and 602 * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution. 603 * </p><p> 604 * Type: TEXT 605 * </p><p> 606 * @see #getVideoResolution 607 */ 608 public static final String COLUMN_VIDEO_FORMAT = "video_format"; 609 610 /** 611 * The flag indicating whether this TV channel is browsable or not. 612 * <p> 613 * A value of 1 indicates the channel is included in the channel list that applications use 614 * to browse channels, a value of 0 indicates the channel is not included in the list. If 615 * not specified, this value is set to 1 (browsable) by default. 616 * </p><p> 617 * Type: INTEGER (boolean) 618 * </p> 619 */ 620 public static final String COLUMN_BROWSABLE = "browsable"; 621 622 /** 623 * The flag indicating whether this TV channel is searchable or not. 624 * <p> 625 * In some regions, it is not allowed to surface search results for a given channel without 626 * broadcaster's consent. This is used to impose such restriction. A value of 1 indicates 627 * the channel is searchable and can be included in search results, a value of 0 indicates 628 * the channel and its TV programs are hidden from search. If not specified, this value is 629 * set to 1 (searchable) by default. 630 * </p> 631 * <p> 632 * Type: INTEGER (boolean) 633 * </p> 634 */ 635 public static final String COLUMN_SEARCHABLE = "searchable"; 636 637 /** 638 * The flag indicating whether this TV channel is locked or not. 639 * <p> 640 * This is primarily used for alternative parental control to prevent unauthorized users 641 * from watching the current channel regardless of the content rating. A value of 1 642 * indicates the channel is locked and the user is required to enter passcode to unlock it 643 * in order to watch the current program from the channel, a value of 0 indicates the 644 * channel is not locked thus the user is not prompted to enter passcode If not specified, 645 * this value is set to 0 (not locked) by default. 646 * </p><p> 647 * Type: INTEGER (boolean) 648 * </p> 649 * @hide 650 */ 651 public static final String COLUMN_LOCKED = "locked"; 652 653 /** 654 * Internal data used by individual TV input services. 655 * <p> 656 * This is internal to the provider that inserted it, and should not be decoded by other 657 * apps. 658 * </p><p> 659 * Type: BLOB 660 * </p> 661 */ 662 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 663 664 /** 665 * The version number of this row entry used by TV input services. 666 * <p> 667 * This is best used by sync adapters to identify the rows to update. The number can be 668 * defined by individual TV input services. One may assign the same value as 669 * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are 670 * coming from a TV broadcast. 671 * </p><p> 672 * Type: INTEGER 673 * </p> 674 */ 675 public static final String COLUMN_VERSION_NUMBER = "version_number"; 676 677 private Channels() {} 678 679 /** 680 * A sub-directory of a single TV channel that represents its primary logo. 681 * <p> 682 * To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw 683 * channel URI. The resulting URI represents an image file, and should be interacted 684 * using ContentResolver.openAssetFileDescriptor. 685 * </p> 686 * <p> 687 * Note that this sub-directory also supports opening the logo as an asset file in write 688 * mode. Callers can create or replace the primary logo associated with this channel by 689 * opening the asset file and writing the full-size photo contents into it. When the file 690 * is closed, the image will be parsed, sized down if necessary, and stored. 691 * </p> 692 * <p> 693 * Usage example: 694 * <pre> 695 * public void writeChannelLogo(long channelId, byte[] logo) { 696 * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId); 697 * try { 698 * AssetFileDescriptor fd = 699 * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw"); 700 * OutputStream os = fd.createOutputStream(); 701 * os.write(logo); 702 * os.close(); 703 * fd.close(); 704 * } catch (IOException e) { 705 * // Handle error cases. 706 * } 707 * } 708 * </pre> 709 * </p> 710 */ 711 public static final class Logo { 712 713 /** 714 * The directory twig for this sub-table. 715 */ 716 public static final String CONTENT_DIRECTORY = "logo"; 717 718 private Logo() {} 719 } 720 } 721 722 /** Column definitions for the TV programs table. */ 723 public static final class Programs implements BaseTvColumns { 724 725 /** The content:// style URI for this table. */ 726 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" 727 + PATH_PROGRAM); 728 729 /** The MIME type of a directory of TV programs. */ 730 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program"; 731 732 /** The MIME type of a single TV program. */ 733 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program"; 734 735 /** 736 * The ID of the TV channel that contains this TV program. 737 * <p> 738 * This is a part of the channel URI and matches to {@link BaseColumns#_ID}. 739 * </p><p> 740 * Type: INTEGER (long) 741 * </p> 742 */ 743 public static final String COLUMN_CHANNEL_ID = "channel_id"; 744 745 /** 746 * The title of this TV program. 747 * <p> 748 * Type: TEXT 749 * </p> 750 **/ 751 public static final String COLUMN_TITLE = "title"; 752 753 /** 754 * The start time of this TV program, in milliseconds since the epoch. 755 * <p> 756 * Type: INTEGER (long) 757 * </p> 758 */ 759 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 760 761 /** 762 * The end time of this TV program, in milliseconds since the epoch. 763 * <p> 764 * Type: INTEGER (long) 765 * </p> 766 */ 767 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 768 769 /** 770 * The comma-separated genre string of this TV program. 771 * <p> 772 * Use the same language appeared in the underlying broadcast standard, if applicable. (For 773 * example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or 774 * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. 775 * </p><p> 776 * Type: TEXT 777 * </p> 778 */ 779 public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre"; 780 781 /** 782 * The comma-separated canonical genre string of this TV program. 783 * <p> 784 * Canonical genres are defined in {@link Genres}. Use {@link Genres#encode Genres.encode()} 785 * to create a text that can be stored in this column. Use {@link Genres#decode 786 * Genres.decode()} to get the canonical genre strings from the text stored in this column. 787 * </p><p> 788 * Type: TEXT 789 * </p> 790 * @see Genres 791 */ 792 public static final String COLUMN_CANONICAL_GENRE = "canonical_genre"; 793 794 /** 795 * The short description of this TV program that is displayed to the user by default. 796 * <p> 797 * It is recommended to limit the length of the descriptions to 256 characters. 798 * </p><p> 799 * Type: TEXT 800 * </p> 801 */ 802 public static final String COLUMN_SHORT_DESCRIPTION = "short_description"; 803 804 /** 805 * The detailed, lengthy description of this TV program that is displayed only when the user 806 * wants to see more information. 807 * <p> 808 * TV input services should leave this field empty if they have no additional details beyond 809 * {@link #COLUMN_SHORT_DESCRIPTION}. 810 * </p><p> 811 * Type: TEXT 812 * </p> 813 */ 814 public static final String COLUMN_LONG_DESCRIPTION = "long_description"; 815 816 /** 817 * The width of the video for this TV program, in the unit of pixels. 818 * <p> 819 * Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video resolution 820 * of the current TV program. Can be empty if it is not known initially or the program does 821 * not convey any video such as the programs from type {@link Channels#SERVICE_TYPE_AUDIO} 822 * channels. 823 * </p><p> 824 * Type: INTEGER 825 * </p> 826 */ 827 public static final String COLUMN_VIDEO_WIDTH = "video_width"; 828 829 /** 830 * The height of the video for this TV program, in the unit of pixels. 831 * <p> 832 * Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video resolution 833 * of the current TV program. Can be empty if it is not known initially or the program does 834 * not convey any video such as the programs from type {@link Channels#SERVICE_TYPE_AUDIO} 835 * channels. 836 * </p><p> 837 * Type: INTEGER 838 * </p> 839 */ 840 public static final String COLUMN_VIDEO_HEIGHT = "video_height"; 841 842 /** 843 * The comma-separated audio languages of this TV program. 844 * <p> 845 * This is used to describe available audio languages included in the program. Use 846 * 3-character language code as specified by ISO 639-2. 847 * </p><p> 848 * Type: TEXT 849 * </p> 850 */ 851 public static final String COLUMN_AUDIO_LANGUAGE = "audio_language"; 852 853 /** 854 * The URI for the poster art of this TV program. 855 * <p> 856 * Can be empty. 857 * </p><p> 858 * Type: TEXT 859 * </p> 860 */ 861 public static final String COLUMN_POSTER_ART_URI = "poster_art_uri"; 862 863 /** 864 * The URI for the thumbnail of this TV program. 865 * <p> 866 * Can be empty. 867 * </p><p> 868 * Type: TEXT 869 * </p> 870 */ 871 public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri"; 872 873 /** 874 * Internal data used by individual TV input services. 875 * <p> 876 * This is internal to the provider that inserted it, and should not be decoded by other 877 * apps. 878 * </p><p> 879 * Type: BLOB 880 * </p> 881 */ 882 public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data"; 883 884 /** 885 * The version number of this row entry used by TV input services. 886 * <p> 887 * This is best used by sync adapters to identify the rows to update. The number can be 888 * defined by individual TV input services. One may assign the same value as 889 * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV 890 * broadcast. 891 * </p><p> 892 * Type: INTEGER 893 * </p> 894 */ 895 public static final String COLUMN_VERSION_NUMBER = "version_number"; 896 897 private Programs() {} 898 899 /** Canonical genres for TV programs. */ 900 public static final class Genres { 901 /** The genre for Family/Kids. */ 902 public static final String FAMILY_KIDS = "Family/Kids"; 903 904 /** The genre for Sports. */ 905 public static final String SPORTS = "Sports"; 906 907 /** The genre for Shopping. */ 908 public static final String SHOPPING = "Shopping"; 909 910 /** The genre for Movies. */ 911 public static final String MOVIES = "Movies"; 912 913 /** The genre for Comedy. */ 914 public static final String COMEDY = "Comedy"; 915 916 /** The genre for Travel. */ 917 public static final String TRAVEL = "Travel"; 918 919 /** The genre for Drama. */ 920 public static final String DRAMA = "Drama"; 921 922 /** The genre for Education. */ 923 public static final String EDUCATION = "Education"; 924 925 /** The genre for Animal/Wildlife. */ 926 public static final String ANIMAL_WILDLIFE = "Animal/Wildlife"; 927 928 /** The genre for News. */ 929 public static final String NEWS = "News"; 930 931 /** The genre for Gaming. */ 932 public static final String GAMING = "Gaming"; 933 934 private Genres() {} 935 936 /** 937 * Encodes canonical genre strings to a text that can be put into the database. 938 * 939 * @param genres Canonical genre strings. Use the strings defined in this class. 940 * @return an encoded genre string that can be inserted into the 941 * {@link #COLUMN_CANONICAL_GENRE} column. 942 */ 943 public static String encode(String... genres) { 944 StringBuilder sb = new StringBuilder(); 945 String separator = ""; 946 for (String genre : genres) { 947 sb.append(separator).append(genre); 948 separator = ","; 949 } 950 return sb.toString(); 951 } 952 953 /** 954 * Decodes the canonical genre strings from the text stored in the database. 955 * 956 * @param genres The encoded genre string retrieved from the 957 * {@link #COLUMN_CANONICAL_GENRE} column. 958 * @return canonical genre strings. 959 */ 960 public static String[] decode(String genres) { 961 return genres.split("\\s*,\\s*"); 962 } 963 } 964 } 965 966 /** 967 * Column definitions for the TV programs that the user watched. Applications do not have access 968 * to this table. 969 * 970 * @hide 971 */ 972 public static final class WatchedPrograms implements BaseTvColumns { 973 974 /** The content:// style URI for this table. */ 975 public static final Uri CONTENT_URI = 976 Uri.parse("content://" + AUTHORITY + "/watched_program"); 977 978 /** The MIME type of a directory of watched programs. */ 979 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program"; 980 981 /** The MIME type of a single item in this table. */ 982 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program"; 983 984 /** 985 * The UTC time that the user started watching this TV program, in milliseconds since the 986 * epoch. 987 * <p> 988 * Type: INTEGER (long) 989 * </p> 990 */ 991 public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS = 992 "watch_start_time_utc_millis"; 993 994 /** 995 * The UTC time that the user stopped watching this TV program, in milliseconds since the 996 * epoch. 997 * <p> 998 * Type: INTEGER (long) 999 * </p> 1000 */ 1001 public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis"; 1002 1003 /** 1004 * The channel ID that contains this TV program. 1005 * <p> 1006 * Type: INTEGER (long) 1007 * </p> 1008 */ 1009 public static final String COLUMN_CHANNEL_ID = "channel_id"; 1010 1011 /** 1012 * The title of this TV program. 1013 * <p> 1014 * Type: TEXT 1015 * </p> 1016 */ 1017 public static final String COLUMN_TITLE = "title"; 1018 1019 /** 1020 * The start time of this TV program, in milliseconds since the epoch. 1021 * <p> 1022 * Type: INTEGER (long) 1023 * </p> 1024 */ 1025 public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; 1026 1027 /** 1028 * The end time of this TV program, in milliseconds since the epoch. 1029 * <p> 1030 * Type: INTEGER (long) 1031 * </p> 1032 */ 1033 public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; 1034 1035 /** 1036 * The description of this TV program. 1037 * <p> 1038 * Type: TEXT 1039 * </p> 1040 */ 1041 public static final String COLUMN_DESCRIPTION = "description"; 1042 1043 private WatchedPrograms() {} 1044 } 1045} 1046