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 */ 16package androidx.tvprovider.media.tv; 17 18import static androidx.annotation.RestrictTo.Scope.LIBRARY; 19import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21import android.content.ContentValues; 22import android.database.Cursor; 23import android.media.tv.TvContentRating; 24import android.net.Uri; 25import android.os.Build; 26 27import androidx.annotation.IntDef; 28import androidx.annotation.RestrictTo; 29import androidx.tvprovider.media.tv.TvContractCompat.BaseTvColumns; 30import androidx.tvprovider.media.tv.TvContractCompat.ProgramColumns; 31import androidx.tvprovider.media.tv.TvContractCompat.Programs; 32import androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres.Genre; 33 34import java.lang.annotation.Retention; 35import java.lang.annotation.RetentionPolicy; 36 37/** 38 * Base class for derived classes that want to have common fields for programs defined in 39 * {@link TvContractCompat}. 40 * @hide 41 */ 42@RestrictTo(LIBRARY) 43public abstract class BaseProgram { 44 /** 45 * @hide 46 */ 47 @RestrictTo(LIBRARY_GROUP) 48 public static final String[] PROJECTION = getProjection(); 49 50 private static final long INVALID_LONG_VALUE = -1; 51 private static final int INVALID_INT_VALUE = -1; 52 private static final int IS_SEARCHABLE = 1; 53 54 /** @hide */ 55 @IntDef({ 56 REVIEW_RATING_STYLE_UNKNOWN, 57 ProgramColumns.REVIEW_RATING_STYLE_STARS, 58 ProgramColumns.REVIEW_RATING_STYLE_THUMBS_UP_DOWN, 59 ProgramColumns.REVIEW_RATING_STYLE_PERCENTAGE, 60 }) 61 @Retention(RetentionPolicy.SOURCE) 62 @RestrictTo(LIBRARY_GROUP) 63 @interface ReviewRatingStyle {} 64 65 /** 66 * The unknown review rating style. 67 */ 68 private static final int REVIEW_RATING_STYLE_UNKNOWN = -1; 69 70 /** @hide */ 71 @RestrictTo(LIBRARY_GROUP) 72 protected ContentValues mValues; 73 74 /* package-private */ 75 BaseProgram(Builder builder) { 76 mValues = builder.mValues; 77 } 78 79 /** 80 * @return The ID for the program. 81 * @see androidx.tvprovider.media.tv.TvContractCompat.BaseTvColumns#_ID 82 */ 83 public long getId() { 84 Long l = mValues.getAsLong(BaseTvColumns._ID); 85 return l == null ? INVALID_LONG_VALUE : l; 86 } 87 88 /** 89 * @return The package name for the program. 90 * @see androidx.tvprovider.media.tv.TvContractCompat.BaseTvColumns#COLUMN_PACKAGE_NAME 91 * @hide 92 */ 93 @RestrictTo(LIBRARY_GROUP) 94 public String getPackageName() { 95 return mValues.getAsString(BaseTvColumns.COLUMN_PACKAGE_NAME); 96 } 97 98 /** 99 * @return The title for the program. 100 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_TITLE 101 */ 102 public String getTitle() { 103 return mValues.getAsString(Programs.COLUMN_TITLE); 104 } 105 106 /** 107 * @return The episode title for the program. 108 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_TITLE 109 */ 110 public String getEpisodeTitle() { 111 return mValues.getAsString(Programs.COLUMN_EPISODE_TITLE); 112 } 113 114 /** 115 * @return The season display number for the program. 116 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_DISPLAY_NUMBER 117 */ 118 public String getSeasonNumber() { 119 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 120 return mValues.getAsString(Programs.COLUMN_SEASON_DISPLAY_NUMBER); 121 } else { 122 return mValues.getAsString(Programs.COLUMN_SEASON_NUMBER); 123 } 124 } 125 126 /** 127 * @return The episode display number for the program. 128 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_DISPLAY_NUMBER 129 */ 130 public String getEpisodeNumber() { 131 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 132 return mValues.getAsString(Programs.COLUMN_EPISODE_DISPLAY_NUMBER); 133 } else { 134 return mValues.getAsString(Programs.COLUMN_EPISODE_NUMBER); 135 } 136 } 137 138 /** 139 * @return The short description for the program. 140 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SHORT_DESCRIPTION 141 */ 142 public String getDescription() { 143 return mValues.getAsString(Programs.COLUMN_SHORT_DESCRIPTION); 144 } 145 146 /** 147 * @return The long description for the program. 148 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_LONG_DESCRIPTION 149 */ 150 public String getLongDescription() { 151 return mValues.getAsString(Programs.COLUMN_LONG_DESCRIPTION); 152 } 153 154 /** 155 * @return The video width for the program. 156 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_VIDEO_WIDTH 157 */ 158 public int getVideoWidth() { 159 Integer i = mValues.getAsInteger(Programs.COLUMN_VIDEO_WIDTH); 160 return i == null ? INVALID_INT_VALUE : i; 161 } 162 163 /** 164 * @return The video height for the program. 165 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_VIDEO_HEIGHT 166 */ 167 public int getVideoHeight() { 168 Integer i = mValues.getAsInteger(Programs.COLUMN_VIDEO_HEIGHT); 169 return i == null ? INVALID_INT_VALUE : i; 170 } 171 172 /** 173 * @return The canonical genre for the program. 174 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_CANONICAL_GENRE 175 */ 176 public @Genre String[] getCanonicalGenres() { 177 return Programs.Genres.decode(mValues.getAsString(Programs.COLUMN_CANONICAL_GENRE)); 178 } 179 180 /** 181 * @return The content rating for the program. 182 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_CONTENT_RATING 183 */ 184 public TvContentRating[] getContentRatings() { 185 return TvContractUtils.stringToContentRatings(mValues.getAsString( 186 Programs.COLUMN_CONTENT_RATING)); 187 } 188 189 /** 190 * @return The poster art URI for the program. 191 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_POSTER_ART_URI 192 */ 193 public Uri getPosterArtUri() { 194 String uri = mValues.getAsString(Programs.COLUMN_POSTER_ART_URI); 195 return uri == null ? null : Uri.parse(uri); 196 } 197 198 /** 199 * @return The thumbnail URI for the program. 200 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_THUMBNAIL_URI 201 */ 202 public Uri getThumbnailUri() { 203 String uri = mValues.getAsString(Programs.COLUMN_POSTER_ART_URI); 204 return uri == null ? null : Uri.parse(uri); 205 } 206 207 /** 208 * @return The internal provider data for the program. 209 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_DATA 210 */ 211 public byte[] getInternalProviderDataByteArray() { 212 return mValues.getAsByteArray(Programs.COLUMN_INTERNAL_PROVIDER_DATA); 213 } 214 215 /** 216 * @return The audio languages for the program. 217 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_AUDIO_LANGUAGE 218 */ 219 public String[] getAudioLanguages() { 220 return TvContractUtils.stringToAudioLanguages(mValues.getAsString( 221 Programs.COLUMN_AUDIO_LANGUAGE)); 222 } 223 224 /** 225 * @return Whether the program is searchable or not. 226 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEARCHABLE 227 */ 228 public boolean isSearchable() { 229 Integer i = mValues.getAsInteger(Programs.COLUMN_SEARCHABLE); 230 return i == null || i == IS_SEARCHABLE; 231 } 232 233 /** 234 * @return The first internal provider flag for the program. 235 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG1 236 */ 237 public Long getInternalProviderFlag1() { 238 return mValues.getAsLong(Programs.COLUMN_INTERNAL_PROVIDER_FLAG1); 239 } 240 241 /** 242 * @return The second internal provider flag for the program. 243 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG2 244 */ 245 public Long getInternalProviderFlag2() { 246 return mValues.getAsLong(Programs.COLUMN_INTERNAL_PROVIDER_FLAG2); 247 } 248 249 /** 250 * @return The third internal provider flag for the program. 251 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG3 252 */ 253 public Long getInternalProviderFlag3() { 254 return mValues.getAsLong(Programs.COLUMN_INTERNAL_PROVIDER_FLAG3); 255 } 256 257 /** 258 * @return The forth internal provider flag for the program. 259 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG4 260 */ 261 public Long getInternalProviderFlag4() { 262 return mValues.getAsLong(Programs.COLUMN_INTERNAL_PROVIDER_FLAG4); 263 } 264 265 /** 266 * @return The season title for the program. 267 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_TITLE 268 */ 269 public String getSeasonTitle() { 270 return mValues.getAsString(Programs.COLUMN_SEASON_TITLE); 271 } 272 273 /** 274 * @return The review rating style for the program. 275 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_REVIEW_RATING_STYLE 276 */ 277 public @ReviewRatingStyle int getReviewRatingStyle() { 278 Integer i = mValues.getAsInteger(Programs.COLUMN_REVIEW_RATING_STYLE); 279 return i == null ? REVIEW_RATING_STYLE_UNKNOWN : i; 280 } 281 282 /** 283 * @return The review rating for the program. 284 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_REVIEW_RATING 285 */ 286 public String getReviewRating() { 287 return mValues.getAsString(Programs.COLUMN_REVIEW_RATING); 288 } 289 290 @Override 291 public int hashCode() { 292 return mValues.hashCode(); 293 } 294 295 @Override 296 public boolean equals(Object other) { 297 if (!(other instanceof BaseProgram)) { 298 return false; 299 } 300 return mValues.equals(((BaseProgram) other).mValues); 301 } 302 303 @Override 304 public String toString() { 305 return "BaseProgram{" + mValues.toString() + "}"; 306 } 307 308 /** 309 * @return The fields of the BaseProgram in {@link ContentValues} format to be easily inserted 310 * into the TV Input Framework database. 311 */ 312 public ContentValues toContentValues() { 313 ContentValues values = new ContentValues(mValues); 314 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 315 values.remove(ProgramColumns.COLUMN_SEARCHABLE); 316 values.remove(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG1); 317 values.remove(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG2); 318 values.remove(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG3); 319 values.remove(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG4); 320 } 321 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 322 values.remove(ProgramColumns.COLUMN_SEASON_TITLE); 323 } 324 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 325 values.remove(ProgramColumns.COLUMN_REVIEW_RATING_STYLE); 326 values.remove(ProgramColumns.COLUMN_REVIEW_RATING); 327 } 328 return values; 329 } 330 331 /** 332 * Sets the fields in the cursor to the given builder instance. 333 * 334 * @param cursor A row from the TV Input Framework database. 335 * @param builder A Builder to set the fields. 336 */ 337 static void setFieldsFromCursor(Cursor cursor, Builder builder) { 338 // TODO: Add additional API which does not use costly getColumnIndex(). 339 int index; 340 if ((index = cursor.getColumnIndex(BaseTvColumns._ID)) >= 0 && !cursor.isNull(index)) { 341 builder.setId(cursor.getLong(index)); 342 } 343 if ((index = cursor.getColumnIndex(BaseTvColumns.COLUMN_PACKAGE_NAME)) >= 0 344 && !cursor.isNull(index)) { 345 builder.setPackageName(cursor.getString(index)); 346 } 347 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_TITLE)) >= 0 348 && !cursor.isNull(index)) { 349 builder.setTitle(cursor.getString(index)); 350 } 351 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_EPISODE_TITLE)) >= 0 352 && !cursor.isNull(index)) { 353 builder.setEpisodeTitle(cursor.getString(index)); 354 } 355 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 356 if ((index = 357 cursor.getColumnIndex(ProgramColumns.COLUMN_SEASON_DISPLAY_NUMBER)) >= 0 358 && !cursor.isNull(index)) { 359 builder.setSeasonNumber(cursor.getString(index), INVALID_INT_VALUE); 360 } 361 } else { 362 if ((index = cursor.getColumnIndex(Programs.COLUMN_SEASON_NUMBER)) >= 0 363 && !cursor.isNull(index)) { 364 builder.setSeasonNumber(cursor.getInt(index)); 365 } 366 } 367 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 368 if ((index = 369 cursor.getColumnIndex(ProgramColumns.COLUMN_EPISODE_DISPLAY_NUMBER)) >= 0 370 && !cursor.isNull(index)) { 371 builder.setEpisodeNumber(cursor.getString(index), INVALID_INT_VALUE); 372 } 373 } else { 374 if ((index = cursor.getColumnIndex(Programs.COLUMN_EPISODE_NUMBER)) >= 0 375 && !cursor.isNull(index)) { 376 builder.setEpisodeNumber(cursor.getInt(index)); 377 } 378 } 379 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_SHORT_DESCRIPTION)) >= 0 380 && !cursor.isNull(index)) { 381 builder.setDescription(cursor.getString(index)); 382 } 383 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_LONG_DESCRIPTION)) >= 0 384 && !cursor.isNull(index)) { 385 builder.setLongDescription(cursor.getString(index)); 386 } 387 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_POSTER_ART_URI)) >= 0 388 && !cursor.isNull(index)) { 389 builder.setPosterArtUri(Uri.parse(cursor.getString(index))); 390 } 391 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_THUMBNAIL_URI)) >= 0 392 && !cursor.isNull(index)) { 393 builder.setThumbnailUri(Uri.parse(cursor.getString(index))); 394 } 395 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_AUDIO_LANGUAGE)) >= 0 396 && !cursor.isNull(index)) { 397 builder.setAudioLanguages( 398 TvContractUtils.stringToAudioLanguages(cursor.getString(index))); 399 } 400 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_CANONICAL_GENRE)) >= 0 401 && !cursor.isNull(index)) { 402 builder.setCanonicalGenres(Programs.Genres.decode( 403 cursor.getString(index))); 404 } 405 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_CONTENT_RATING)) >= 0 406 && !cursor.isNull(index)) { 407 builder.setContentRatings( 408 TvContractUtils.stringToContentRatings(cursor.getString(index))); 409 } 410 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_VIDEO_WIDTH)) >= 0 411 && !cursor.isNull(index)) { 412 builder.setVideoWidth((int) cursor.getLong(index)); 413 } 414 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_VIDEO_HEIGHT)) >= 0 415 && !cursor.isNull(index)) { 416 builder.setVideoHeight((int) cursor.getLong(index)); 417 } 418 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_INTERNAL_PROVIDER_DATA)) >= 0 419 && !cursor.isNull(index)) { 420 builder.setInternalProviderData(cursor.getBlob(index)); 421 } 422 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 423 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_SEARCHABLE)) >= 0 424 && !cursor.isNull(index)) { 425 builder.setSearchable(cursor.getInt(index) == IS_SEARCHABLE); 426 } 427 if ((index = 428 cursor.getColumnIndex(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG1)) >= 0 429 && !cursor.isNull(index)) { 430 builder.setInternalProviderFlag1(cursor.getLong(index)); 431 } 432 if ((index = 433 cursor.getColumnIndex(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG2)) >= 0 434 && !cursor.isNull(index)) { 435 builder.setInternalProviderFlag2(cursor.getLong(index)); 436 } 437 if ((index = 438 cursor.getColumnIndex(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG3)) >= 0 439 && !cursor.isNull(index)) { 440 builder.setInternalProviderFlag3(cursor.getLong(index)); 441 } 442 if ((index = 443 cursor.getColumnIndex(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG4)) >= 0 444 && !cursor.isNull(index)) { 445 builder.setInternalProviderFlag4(cursor.getLong(index)); 446 } 447 } 448 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 449 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_SEASON_TITLE)) >= 0 450 && !cursor.isNull(index)) { 451 builder.setSeasonTitle(cursor.getString(index)); 452 } 453 } 454 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 455 if ((index = cursor.getColumnIndex( 456 ProgramColumns.COLUMN_REVIEW_RATING_STYLE)) >= 0 457 && !cursor.isNull(index)) { 458 builder.setReviewRatingStyle(cursor.getInt(index)); 459 } 460 if ((index = cursor.getColumnIndex(ProgramColumns.COLUMN_REVIEW_RATING)) >= 0 461 && !cursor.isNull(index)) { 462 builder.setReviewRating(cursor.getString(index)); 463 } 464 } 465 } 466 467 private static String[] getProjection() { 468 String[] baseColumns = new String[] { 469 BaseTvColumns._ID, 470 BaseTvColumns.COLUMN_PACKAGE_NAME, 471 ProgramColumns.COLUMN_TITLE, 472 ProgramColumns.COLUMN_EPISODE_TITLE, 473 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 474 ? ProgramColumns.COLUMN_SEASON_DISPLAY_NUMBER 475 : Programs.COLUMN_SEASON_NUMBER, 476 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 477 ? ProgramColumns.COLUMN_EPISODE_DISPLAY_NUMBER 478 : Programs.COLUMN_EPISODE_NUMBER, 479 ProgramColumns.COLUMN_SHORT_DESCRIPTION, 480 ProgramColumns.COLUMN_LONG_DESCRIPTION, 481 ProgramColumns.COLUMN_POSTER_ART_URI, 482 ProgramColumns.COLUMN_THUMBNAIL_URI, 483 ProgramColumns.COLUMN_AUDIO_LANGUAGE, 484 ProgramColumns.COLUMN_CANONICAL_GENRE, 485 ProgramColumns.COLUMN_CONTENT_RATING, 486 ProgramColumns.COLUMN_VIDEO_WIDTH, 487 ProgramColumns.COLUMN_VIDEO_HEIGHT, 488 ProgramColumns.COLUMN_INTERNAL_PROVIDER_DATA 489 }; 490 String[] marshmallowColumns = new String[] { 491 ProgramColumns.COLUMN_SEARCHABLE, 492 ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG1, 493 ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG2, 494 ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG3, 495 ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG4, 496 }; 497 String[] nougatColumns = new String[] { 498 ProgramColumns.COLUMN_SEASON_TITLE, 499 }; 500 String[] oColumns = new String[] { 501 ProgramColumns.COLUMN_REVIEW_RATING, 502 ProgramColumns.COLUMN_REVIEW_RATING_STYLE, 503 }; 504 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 505 return CollectionUtils.concatAll(baseColumns, marshmallowColumns, nougatColumns, 506 oColumns); 507 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 508 return CollectionUtils.concatAll(baseColumns, marshmallowColumns, nougatColumns); 509 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 510 return CollectionUtils.concatAll(baseColumns, marshmallowColumns); 511 } else { 512 return baseColumns; 513 } 514 } 515 516 /** 517 * This Builder class simplifies the creation of a {@link BaseProgram} object. 518 * 519 * @param <T> The Builder of the derived classe. 520 */ 521 public abstract static class Builder<T extends Builder> { 522 /** @hide */ 523 @RestrictTo(LIBRARY_GROUP) 524 protected ContentValues mValues; 525 526 /** 527 * Creates a new Builder object. 528 */ 529 public Builder() { 530 mValues = new ContentValues(); 531 } 532 533 /** 534 * Creates a new Builder object with values copied from another Program. 535 * @param other The Program you're copying from. 536 */ 537 public Builder(BaseProgram other) { 538 mValues = new ContentValues(other.mValues); 539 } 540 541 /** 542 * Sets a unique id for this program. 543 * 544 * @param programId The ID for the program. 545 * @return This Builder object to allow for chaining of calls to builder methods. 546 * @see androidx.tvprovider.media.tv.TvContractCompat.BaseTvColumns#_ID 547 */ 548 public T setId(long programId) { 549 mValues.put(BaseTvColumns._ID, programId); 550 return (T) this; 551 } 552 553 /** 554 * Sets the package name for this program. 555 * 556 * @param packageName The package name for the program. 557 * @return This Builder object to allow for chaining of calls to builder methods. 558 * @see androidx.tvprovider.media.tv.TvContractCompat.BaseTvColumns#COLUMN_PACKAGE_NAME 559 * @hide 560 */ 561 @RestrictTo(LIBRARY_GROUP) 562 public T setPackageName(String packageName) { 563 mValues.put(BaseTvColumns.COLUMN_PACKAGE_NAME, packageName); 564 return (T) this; 565 } 566 567 /** 568 * Sets the title of this program. For a series, this is the series title. 569 * 570 * @param title The title for the program. 571 * @return This Builder object to allow for chaining of calls to builder methods. 572 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_TITLE 573 */ 574 public T setTitle(String title) { 575 mValues.put(Programs.COLUMN_TITLE, title); 576 return (T) this; 577 } 578 579 /** 580 * Sets the title of this particular episode for a series. 581 * 582 * @param episodeTitle The episode title for the program. 583 * @return This Builder object to allow for chaining of calls to builder methods. 584 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_TITLE 585 */ 586 public T setEpisodeTitle(String episodeTitle) { 587 mValues.put(Programs.COLUMN_EPISODE_TITLE, episodeTitle); 588 return (T) this; 589 } 590 591 /** 592 * Sets the season number for this episode for a series. 593 * 594 * @param seasonNumber The season display number for the program. 595 * @return This Builder object to allow for chaining of calls to builder methods. 596 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_DISPLAY_NUMBER 597 */ 598 public T setSeasonNumber(int seasonNumber) { 599 setSeasonNumber(String.valueOf(seasonNumber), seasonNumber); 600 return (T) this; 601 } 602 603 /** 604 * Sets the season number for this episode for a series. 605 * 606 * @param seasonNumber The season display number for the program. 607 * @param numericalSeasonNumber An integer value for 608 * {@link androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_NUMBER} 609 * which will be used for API Level 23 and below. 610 * @return This Builder object to allow for chaining of calls to builder methods. 611 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_DISPLAY_NUMBER 612 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_NUMBER 613 */ 614 public T setSeasonNumber(String seasonNumber, int numericalSeasonNumber) { 615 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 616 mValues.put(Programs.COLUMN_SEASON_DISPLAY_NUMBER, seasonNumber); 617 } else { 618 mValues.put(Programs.COLUMN_SEASON_NUMBER, numericalSeasonNumber); 619 } 620 return (T) this; 621 } 622 623 /** 624 * Sets the episode number in a season for this episode for a series. 625 * 626 * @param episodeNumber The value of episode display number for the program. 627 * @return This Builder object to allow for chaining of calls to builder methods. 628 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_DISPLAY_NUMBER 629 */ 630 public T setEpisodeNumber(int episodeNumber) { 631 setEpisodeNumber(String.valueOf(episodeNumber), episodeNumber); 632 return (T) this; 633 } 634 635 /** 636 * Sets the episode number in a season for this episode for a series. 637 * 638 * @param episodeNumber The value of episode display number for the program. 639 * @param numericalEpisodeNumber An integer value for 640 * {@link androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_NUMBER} 641 * which will be used for API Level 23 and below. 642 * @return This Builder object to allow for chaining of calls to builder methods. 643 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_DISPLAY_NUMBER 644 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_EPISODE_NUMBER 645 */ 646 public T setEpisodeNumber(String episodeNumber, int numericalEpisodeNumber) { 647 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 648 mValues.put(Programs.COLUMN_EPISODE_DISPLAY_NUMBER, episodeNumber); 649 } else { 650 mValues.put(Programs.COLUMN_EPISODE_NUMBER, numericalEpisodeNumber); 651 } 652 return (T) this; 653 } 654 655 /** 656 * Sets a brief description of the program. For a series, this would be a brief description 657 * of the episode. 658 * 659 * @param description The short description for the program. 660 * @return This Builder object to allow for chaining of calls to builder methods. 661 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SHORT_DESCRIPTION 662 */ 663 public T setDescription(String description) { 664 mValues.put(Programs.COLUMN_SHORT_DESCRIPTION, description); 665 return (T) this; 666 } 667 668 /** 669 * Sets a longer description of a program if one exists. 670 * 671 * @param longDescription The long description for the program. 672 * @return This Builder object to allow for chaining of calls to builder methods. 673 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_LONG_DESCRIPTION 674 */ 675 public T setLongDescription(String longDescription) { 676 mValues.put(Programs.COLUMN_LONG_DESCRIPTION, longDescription); 677 return (T) this; 678 } 679 680 /** 681 * Sets the video width of the program. 682 * 683 * @param width The video width for the program. 684 * @return This Builder object to allow for chaining of calls to builder methods. 685 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_VIDEO_WIDTH 686 */ 687 public T setVideoWidth(int width) { 688 mValues.put(Programs.COLUMN_VIDEO_WIDTH, width); 689 return (T) this; 690 } 691 692 /** 693 * Sets the video height of the program. 694 * 695 * @param height The video height for the program. 696 * @return This Builder object to allow for chaining of calls to builder methods. 697 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_VIDEO_HEIGHT 698 */ 699 public T setVideoHeight(int height) { 700 mValues.put(Programs.COLUMN_VIDEO_HEIGHT, height); 701 return (T) this; 702 } 703 704 /** 705 * Sets the content ratings for this program. 706 * 707 * @param contentRatings An array of {@link android.media.tv.TvContentRating} that apply to 708 * this program which will be flattened to a String to store in 709 * a database. 710 * @return This Builder object to allow for chaining of calls to builder methods. 711 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_CONTENT_RATING 712 */ 713 public T setContentRatings(TvContentRating[] contentRatings) { 714 mValues.put(Programs.COLUMN_CONTENT_RATING, 715 TvContractUtils.contentRatingsToString(contentRatings)); 716 return (T) this; 717 } 718 719 /** 720 * Sets the large poster art of the program. 721 * 722 * @param posterArtUri The poster art URI for the program. 723 * @return This Builder object to allow for chaining of calls to builder methods. 724 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_POSTER_ART_URI 725 */ 726 public T setPosterArtUri(Uri posterArtUri) { 727 mValues.put(Programs.COLUMN_POSTER_ART_URI, 728 posterArtUri == null ? null : posterArtUri.toString()); 729 return (T) this; 730 } 731 732 /** 733 * Sets a small thumbnail of the program. 734 * 735 * @param thumbnailUri The thumbnail URI for the program. 736 * @return This Builder object to allow for chaining of calls to builder methods. 737 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_THUMBNAIL_URI 738 */ 739 public T setThumbnailUri(Uri thumbnailUri) { 740 mValues.put(Programs.COLUMN_THUMBNAIL_URI, 741 thumbnailUri == null ? null : thumbnailUri.toString()); 742 return (T) this; 743 } 744 745 /** 746 * Sets the genres of the program. 747 * 748 * @param genres An array of 749 * {@link androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres} 750 * that apply to the program which will be flattened to a String to store in a database. 751 * @return This Builder object to allow for chaining of calls to builder methods. 752 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_CANONICAL_GENRE 753 */ 754 public T setCanonicalGenres(@Genre String[] genres) { 755 mValues.put(Programs.COLUMN_CANONICAL_GENRE, Programs.Genres.encode(genres)); 756 return (T) this; 757 } 758 759 /** 760 * Sets the internal provider data for the program as raw bytes. 761 * 762 * @param data The internal provider data for the program. 763 * @return This Builder object to allow for chaining of calls to builder methods. 764 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_DATA 765 */ 766 public T setInternalProviderData(byte[] data) { 767 mValues.put(ProgramColumns.COLUMN_INTERNAL_PROVIDER_DATA, data); 768 return (T) this; 769 } 770 771 /** 772 * Sets the available audio languages for this program as an array of strings. 773 * 774 * @param audioLanguages An array of audio languages, in ISO 639-1 or 639-2/T codes, that 775 * apply to this program which will be stored in a database. 776 * @return This Builder object to allow for chaining of calls to builder methods. 777 */ 778 public T setAudioLanguages(String[] audioLanguages) { 779 mValues.put(ProgramColumns.COLUMN_AUDIO_LANGUAGE, 780 TvContractUtils.audioLanguagesToString(audioLanguages)); 781 return (T) this; 782 } 783 784 /** 785 * Sets whether this channel can be searched for in other applications. 786 * 787 * @param searchable Whether the program is searchable or not. 788 * @return This Builder object to allow for chaining of calls to builder methods. 789 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEARCHABLE 790 */ 791 public T setSearchable(boolean searchable) { 792 mValues.put(Programs.COLUMN_SEARCHABLE, searchable ? IS_SEARCHABLE : 0); 793 return (T) this; 794 } 795 796 /** 797 * Sets the internal provider flag1 for the program. 798 * 799 * @param flag The first internal provider flag for the program. 800 * @return This Builder object to allow for chaining of calls to builder methods. 801 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG1 802 */ 803 public T setInternalProviderFlag1(long flag) { 804 mValues.put(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG1, flag); 805 return (T) this; 806 } 807 808 /** 809 * Sets the internal provider flag2 for the program. 810 * 811 * @param flag The second internal provider flag for the program. 812 * @return This Builder object to allow for chaining of calls to builder methods. 813 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG2 814 */ 815 public T setInternalProviderFlag2(long flag) { 816 mValues.put(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG2, flag); 817 return (T) this; 818 } 819 820 /** 821 * Sets the internal provider flag3 for the program. 822 * 823 * @param flag The third internal provider flag for the program. 824 * @return This Builder object to allow for chaining of calls to builder methods. 825 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG3 826 */ 827 public T setInternalProviderFlag3(long flag) { 828 mValues.put(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG3, flag); 829 return (T) this; 830 } 831 832 /** 833 * Sets the internal provider flag4 for the program. 834 * 835 * @param flag The forth internal provider flag for the program. 836 * @return This Builder object to allow for chaining of calls to builder methods. 837 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_INTERNAL_PROVIDER_FLAG4 838 */ 839 public T setInternalProviderFlag4(long flag) { 840 mValues.put(ProgramColumns.COLUMN_INTERNAL_PROVIDER_FLAG4, flag); 841 return (T) this; 842 } 843 844 /** 845 * Sets the review rating score style used for {@link #setReviewRating}. 846 * 847 * @param reviewRatingStyle The reviewing rating style for the program. 848 * @return This Builder object to allow for chaining of calls to builder methods. 849 * 850 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_REVIEW_RATING_STYLE 851 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#REVIEW_RATING_STYLE_STARS 852 * @see androidx.tvprovider.media.tv.TvContractCompat 853 * .Programs#REVIEW_RATING_STYLE_THUMBS_UP_DOWN 854 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#REVIEW_RATING_STYLE_PERCENTAGE 855 */ 856 public T setReviewRatingStyle(@ReviewRatingStyle int reviewRatingStyle) { 857 mValues.put(ProgramColumns.COLUMN_REVIEW_RATING_STYLE, reviewRatingStyle); 858 return (T) this; 859 } 860 861 /** 862 * Sets the review rating score for this program. 863 * 864 * <p>The format of the value is dependent on the review rating style. If the style is 865 * based on "stars", the value should be a real number between 0.0 and 5.0. (e.g. "4.5") 866 * If the style is based on "thumbs up/down", the value should be two integers, one for 867 * thumbs-up count and the other for thumbs-down count, with a comma between them. 868 * (e.g. "200,40") If the style is base on "percentage", the value should be a 869 * real number between 0 and 100. (e.g. "99.9") 870 * 871 * @param reviewRating The value of the review rating for the program. 872 * @return This Builder object to allow for chaining of calls to builder methods. 873 * 874 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_REVIEW_RATING 875 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_REVIEW_RATING_STYLE 876 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#REVIEW_RATING_STYLE_STARS 877 * @see androidx.tvprovider.media.tv.TvContractCompat 878 * .Programs#REVIEW_RATING_STYLE_THUMBS_UP_DOWN 879 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#REVIEW_RATING_STYLE_PERCENTAGE 880 */ 881 public T setReviewRating(String reviewRating) { 882 mValues.put(ProgramColumns.COLUMN_REVIEW_RATING, reviewRating); 883 return (T) this; 884 } 885 886 /** 887 * Sets a custom name for the season, if applicable. 888 * 889 * @param seasonTitle The season title for the program. 890 * @return This Builder object to allow for chaining of calls to builder methods. 891 * @see androidx.tvprovider.media.tv.TvContractCompat.Programs#COLUMN_SEASON_TITLE 892 */ 893 public T setSeasonTitle(String seasonTitle) { 894 mValues.put(ProgramColumns.COLUMN_SEASON_TITLE, seasonTitle); 895 return (T) this; 896 } 897 } 898} 899