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 android.support.media.tv; 17 18import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 19 20import android.annotation.TargetApi; 21import android.content.ContentValues; 22import android.content.Intent; 23import android.database.Cursor; 24import android.net.Uri; 25import android.os.Build; 26import android.support.annotation.RestrictTo; 27import android.support.media.tv.TvContractCompat.PreviewProgramColumns; 28import android.support.media.tv.TvContractCompat.PreviewProgramColumns.AspectRatio; 29import android.support.media.tv.TvContractCompat.PreviewProgramColumns.Availability; 30import android.support.media.tv.TvContractCompat.PreviewProgramColumns.InteractionType; 31import android.support.media.tv.TvContractCompat.PreviewProgramColumns.Type; 32import android.support.media.tv.TvContractCompat.PreviewPrograms; 33 34import java.net.URISyntaxException; 35import java.text.SimpleDateFormat; 36import java.util.Date; 37import java.util.TimeZone; 38 39/** 40 * Base class for derived classes that want to have common fields for preview programs. 41 */ 42@TargetApi(26) 43public abstract class BasePreviewProgram extends BaseProgram { 44 /** 45 * @hide 46 */ 47 @RestrictTo(LIBRARY_GROUP) 48 public static final String[] PROJECTION = getProjection(); 49 50 private static final int INVALID_INT_VALUE = -1; 51 private static final long INVALID_LONG_VALUE = -1; 52 private static final int IS_TRANSIENT = 1; 53 private static final int IS_LIVE = 1; 54 private static final int IS_BROWSABLE = 1; 55 56 BasePreviewProgram(Builder builder) { 57 super(builder); 58 } 59 60 /** 61 * @return The internal provider ID for the program. 62 * @see PreviewPrograms#COLUMN_INTERNAL_PROVIDER_ID 63 */ 64 public String getInternalProviderId() { 65 return mValues.getAsString(PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID); 66 } 67 68 /** 69 * @return The preview video URI for the program. 70 * @see PreviewPrograms#COLUMN_PREVIEW_VIDEO_URI 71 */ 72 public Uri getPreviewVideoUri() { 73 String uri = mValues.getAsString(PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI); 74 return uri == null ? null : Uri.parse(uri); 75 } 76 77 /** 78 * @return The last playback position of the program in millis. 79 * @see PreviewPrograms#COLUMN_LAST_PLAYBACK_POSITION_MILLIS 80 */ 81 public int getLastPlaybackPositionMillis() { 82 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS); 83 return i == null ? INVALID_INT_VALUE : i; 84 } 85 86 /** 87 * @return The duration of the program in millis. 88 * @see PreviewPrograms#COLUMN_DURATION_MILLIS 89 */ 90 public int getDurationMillis() { 91 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_DURATION_MILLIS); 92 return i == null ? INVALID_INT_VALUE : i; 93 } 94 95 /** 96 * @return The intent URI which is launched when the program is selected. 97 * @see PreviewPrograms#COLUMN_INTENT_URI 98 */ 99 public Uri getIntentUri() { 100 String uri = mValues.getAsString(PreviewPrograms.COLUMN_INTENT_URI); 101 return uri == null ? null : Uri.parse(uri); 102 } 103 104 /** 105 * @return The intent which is launched when the program is selected. 106 * @see PreviewPrograms#COLUMN_INTENT_URI 107 */ 108 public Intent getIntent() throws URISyntaxException { 109 String uri = mValues.getAsString(PreviewPrograms.COLUMN_INTENT_URI); 110 return uri == null ? null : Intent.parseUri(uri, Intent.URI_INTENT_SCHEME); 111 } 112 113 /** 114 * @return Whether the program is transient or not. 115 * @see PreviewPrograms#COLUMN_TRANSIENT 116 */ 117 public boolean isTransient() { 118 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_TRANSIENT); 119 return i != null && i == IS_TRANSIENT; 120 } 121 122 /** 123 * @return The type of the program. 124 * @see PreviewPrograms#COLUMN_TYPE 125 */ 126 public @Type int getType() { 127 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_TYPE); 128 return i == null ? INVALID_INT_VALUE : i; 129 } 130 131 /** 132 * @return The poster art aspect ratio for the program. 133 * @see PreviewPrograms#COLUMN_POSTER_ART_ASPECT_RATIO 134 * @see PreviewPrograms#COLUMN_POSTER_ART_URI 135 */ 136 public @AspectRatio int getPosterArtAspectRatio() { 137 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO); 138 return i == null ? INVALID_INT_VALUE : i; 139 } 140 141 /** 142 * @return The thumbnail aspect ratio for the program. 143 * @see PreviewPrograms#COLUMN_THUMBNAIL_ASPECT_RATIO 144 * @see PreviewPrograms#COLUMN_THUMBNAIL_URI 145 */ 146 public @AspectRatio int getThumbnailAspectRatio() { 147 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO); 148 return i == null ? INVALID_INT_VALUE : i; 149 } 150 151 /** 152 * @return The logo URI for the program. 153 * @see PreviewPrograms#COLUMN_LOGO_URI 154 */ 155 public Uri getLogoUri() { 156 String uri = mValues.getAsString(PreviewPrograms.COLUMN_LOGO_URI); 157 return uri == null ? null : Uri.parse(uri); 158 } 159 160 /** 161 * @return The availability of the program. 162 * @see PreviewPrograms#COLUMN_AVAILABILITY 163 */ 164 public @Availability int getAvailability() { 165 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_AVAILABILITY); 166 return i == null ? INVALID_INT_VALUE : i; 167 } 168 169 /** 170 * @return The starting price of the program. 171 * @see PreviewPrograms#COLUMN_STARTING_PRICE 172 */ 173 public String getStartingPrice() { 174 return mValues.getAsString(PreviewPrograms.COLUMN_STARTING_PRICE); 175 } 176 177 /** 178 * @return The offer price of the program. 179 * @see PreviewPrograms#COLUMN_OFFER_PRICE 180 */ 181 public String getOfferPrice() { 182 return mValues.getAsString(PreviewPrograms.COLUMN_OFFER_PRICE); 183 } 184 185 /** 186 * @return The release date of the program. 187 * @see PreviewPrograms#COLUMN_RELEASE_DATE 188 */ 189 public String getReleaseDate() { 190 return mValues.getAsString(PreviewPrograms.COLUMN_RELEASE_DATE); 191 } 192 193 /** 194 * @return The item count for the program. 195 * @see PreviewPrograms#COLUMN_ITEM_COUNT 196 */ 197 public int getItemCount() { 198 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_ITEM_COUNT); 199 return i == null ? INVALID_INT_VALUE : i; 200 } 201 202 /** 203 * @return Whether the program is live or not. 204 * @see PreviewPrograms#COLUMN_LIVE 205 */ 206 public boolean isLive() { 207 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_LIVE); 208 return i != null && i == IS_LIVE; 209 } 210 211 /** 212 * @return The interaction type for the program. 213 * @see PreviewPrograms#COLUMN_INTERACTION_TYPE 214 */ 215 public @InteractionType int getInteractionType() { 216 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_INTERACTION_TYPE); 217 return i == null ? INVALID_INT_VALUE : i; 218 } 219 220 /** 221 * @return The interaction count for the program. 222 * @see PreviewPrograms#COLUMN_INTERACTION_COUNT 223 */ 224 public long getInteractionCount() { 225 Long l = mValues.getAsLong(PreviewPrograms.COLUMN_INTERACTION_COUNT); 226 return l == null ? INVALID_LONG_VALUE : l; 227 } 228 229 /** 230 * @return The author for the program. 231 * @see PreviewPrograms#COLUMN_AUTHOR 232 */ 233 public String getAuthor() { 234 return mValues.getAsString(PreviewPrograms.COLUMN_AUTHOR); 235 } 236 237 /** 238 * @return Whether the program is browsable or not. 239 * @see PreviewPrograms#COLUMN_BROWSABLE; 240 */ 241 public boolean isBrowsable() { 242 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_BROWSABLE); 243 return i != null && i == IS_BROWSABLE; 244 } 245 246 /** 247 * @return The content ID for the program. 248 * @see PreviewPrograms#COLUMN_CONTENT_ID 249 */ 250 public String getContentId() { 251 return mValues.getAsString(PreviewPrograms.COLUMN_CONTENT_ID); 252 } 253 254 @Override 255 public boolean equals(Object other) { 256 if (!(other instanceof BasePreviewProgram)) { 257 return false; 258 } 259 return mValues.equals(((BasePreviewProgram) other).mValues); 260 } 261 262 /** 263 * @return The fields of the BasePreviewProgram in {@link ContentValues} format to be easily 264 * inserted into the TV Input Framework database. 265 */ 266 @Override 267 public ContentValues toContentValues() { 268 return toContentValues(false); 269 } 270 271 /** 272 * Returns fields of the BasePreviewProgram in the ContentValues format to be easily inserted 273 * into the TV Input Framework database. 274 * 275 * @param includeProtectedFields Whether the fields protected by system is included or not. 276 * @hide 277 */ 278 @RestrictTo(LIBRARY_GROUP) 279 public ContentValues toContentValues(boolean includeProtectedFields) { 280 ContentValues values = super.toContentValues(); 281 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 282 values.remove(PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID); 283 values.remove(PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI); 284 values.remove(PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS); 285 values.remove(PreviewProgramColumns.COLUMN_DURATION_MILLIS); 286 values.remove(PreviewProgramColumns.COLUMN_INTENT_URI); 287 values.remove(PreviewProgramColumns.COLUMN_TRANSIENT); 288 values.remove(PreviewProgramColumns.COLUMN_TYPE); 289 values.remove(PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO); 290 values.remove(PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO); 291 values.remove(PreviewProgramColumns.COLUMN_LOGO_URI); 292 values.remove(PreviewProgramColumns.COLUMN_AVAILABILITY); 293 values.remove(PreviewProgramColumns.COLUMN_STARTING_PRICE); 294 values.remove(PreviewProgramColumns.COLUMN_OFFER_PRICE); 295 values.remove(PreviewProgramColumns.COLUMN_RELEASE_DATE); 296 values.remove(PreviewProgramColumns.COLUMN_ITEM_COUNT); 297 values.remove(PreviewProgramColumns.COLUMN_LIVE); 298 values.remove(PreviewProgramColumns.COLUMN_INTERACTION_COUNT); 299 values.remove(PreviewProgramColumns.COLUMN_AUTHOR); 300 values.remove(PreviewProgramColumns.COLUMN_CONTENT_ID); 301 } 302 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !includeProtectedFields) { 303 values.remove(PreviewProgramColumns.COLUMN_BROWSABLE); 304 } 305 return values; 306 } 307 308 /** 309 * Sets the fields in the cursor to the given builder instance. 310 * 311 * @param cursor A row from the TV Input Framework database. 312 * @param builder A Builder to set the fields. 313 */ 314 static void setFieldsFromCursor(Cursor cursor, Builder builder) { 315 // TODO: Add additional API which does not use costly getColumnIndex(). 316 BaseProgram.setFieldsFromCursor(cursor, builder); 317 int index; 318 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 319 if ((index = 320 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID)) >= 0 321 && !cursor.isNull(index)) { 322 builder.setInternalProviderId(cursor.getString(index)); 323 } 324 if ((index = 325 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI)) >= 0 326 && !cursor.isNull(index)) { 327 builder.setPreviewVideoUri(Uri.parse(cursor.getString(index))); 328 } 329 if ((index = cursor.getColumnIndex( 330 PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS)) >= 0 331 && !cursor.isNull(index)) { 332 builder.setLastPlaybackPositionMillis(cursor.getInt(index)); 333 } 334 if ((index = 335 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_DURATION_MILLIS)) >= 0 336 && !cursor.isNull(index)) { 337 builder.setDurationMillis(cursor.getInt(index)); 338 } 339 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTENT_URI)) >= 0 340 && !cursor.isNull(index)) { 341 builder.setIntentUri(Uri.parse(cursor.getString(index))); 342 } 343 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_TRANSIENT)) >= 0 344 && !cursor.isNull(index)) { 345 builder.setTransient(cursor.getInt(index) == IS_TRANSIENT); 346 } 347 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_TYPE)) >= 0 348 && !cursor.isNull(index)) { 349 builder.setType(cursor.getInt(index)); 350 } 351 if ((index = cursor.getColumnIndex( 352 PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO)) >= 0 353 && !cursor.isNull(index)) { 354 builder.setPosterArtAspectRatio(cursor.getInt(index)); 355 } 356 if ((index = 357 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO)) >= 0 358 && !cursor.isNull(index)) { 359 builder.setThumbnailAspectRatio(cursor.getInt(index)); 360 } 361 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_LOGO_URI)) >= 0 362 && !cursor.isNull(index)) { 363 builder.setLogoUri(Uri.parse(cursor.getString(index))); 364 } 365 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_AVAILABILITY)) >= 0 366 && !cursor.isNull(index)) { 367 builder.setAvailability(cursor.getInt(index)); 368 } 369 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_STARTING_PRICE)) >= 0 370 && !cursor.isNull(index)) { 371 builder.setStartingPrice(cursor.getString(index)); 372 } 373 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_OFFER_PRICE)) >= 0 374 && !cursor.isNull(index)) { 375 builder.setOfferPrice(cursor.getString(index)); 376 } 377 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_RELEASE_DATE)) >= 0 378 && !cursor.isNull(index)) { 379 builder.setReleaseDate(cursor.getString(index)); 380 } 381 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_ITEM_COUNT)) >= 0 382 && !cursor.isNull(index)) { 383 builder.setItemCount(cursor.getInt(index)); 384 } 385 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_LIVE)) >= 0 386 && !cursor.isNull(index)) { 387 builder.setLive(cursor.getInt(index) == IS_LIVE); 388 } 389 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERACTION_TYPE)) >= 0 390 && !cursor.isNull(index)) { 391 builder.setInteractionType(cursor.getInt(index)); 392 } 393 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERACTION_COUNT)) >= 0 394 && !cursor.isNull(index)) { 395 builder.setInteractionCount(cursor.getInt(index)); 396 } 397 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_AUTHOR)) >= 0 398 && !cursor.isNull(index)) { 399 builder.setAuthor(cursor.getString(index)); 400 } 401 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_BROWSABLE)) >= 0 402 && !cursor.isNull(index)) { 403 builder.setBrowsable(cursor.getInt(index) == IS_BROWSABLE); 404 } 405 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_CONTENT_ID)) >= 0 406 && !cursor.isNull(index)) { 407 builder.setContentId(cursor.getString(index)); 408 } 409 } 410 } 411 412 private static String[] getProjection() { 413 String[] oColumns = new String[] { 414 PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID, 415 PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI, 416 PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS, 417 PreviewProgramColumns.COLUMN_DURATION_MILLIS, 418 PreviewProgramColumns.COLUMN_INTENT_URI, 419 PreviewProgramColumns.COLUMN_TRANSIENT, 420 PreviewProgramColumns.COLUMN_TYPE, 421 PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO, 422 PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO, 423 PreviewProgramColumns.COLUMN_LOGO_URI, 424 PreviewProgramColumns.COLUMN_AVAILABILITY, 425 PreviewProgramColumns.COLUMN_STARTING_PRICE, 426 PreviewProgramColumns.COLUMN_OFFER_PRICE, 427 PreviewProgramColumns.COLUMN_RELEASE_DATE, 428 PreviewProgramColumns.COLUMN_ITEM_COUNT, 429 PreviewProgramColumns.COLUMN_LIVE, 430 PreviewProgramColumns.COLUMN_INTERACTION_TYPE, 431 PreviewProgramColumns.COLUMN_INTERACTION_COUNT, 432 PreviewProgramColumns.COLUMN_AUTHOR, 433 PreviewProgramColumns.COLUMN_BROWSABLE, 434 PreviewProgramColumns.COLUMN_CONTENT_ID, 435 }; 436 return CollectionUtils.concatAll(BaseProgram.PROJECTION, oColumns); 437 } 438 439 /** 440 * This Builder class simplifies the creation of a {@link BasePreviewProgram} object. 441 * 442 * @param <T> The Builder of the derived classe. 443 */ 444 public abstract static class Builder<T extends Builder> extends BaseProgram.Builder<T> { 445 private static final SimpleDateFormat sFormat = 446 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 447 448 static { 449 sFormat.setTimeZone(TimeZone.getTimeZone("GMT-0")); 450 } 451 452 /** 453 * Creates a new Builder object. 454 */ 455 public Builder() { 456 } 457 458 /** 459 * Creates a new Builder object with values copied from another Program. 460 * @param other The Program you're copying from. 461 */ 462 public Builder(BasePreviewProgram other) { 463 mValues = new ContentValues(other.mValues); 464 } 465 466 /** 467 * Sets external ID for the program. 468 * 469 * @param externalId The internal provider ID for the program. 470 * @return This Builder object to allow for chaining of calls to builder methods. 471 * @see PreviewPrograms#COLUMN_INTERNAL_PROVIDER_ID 472 */ 473 public T setInternalProviderId(String externalId) { 474 mValues.put(PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID, externalId); 475 return (T) this; 476 } 477 478 /** 479 * Sets a URI for the preview video. 480 * 481 * @param previewVideoUri The preview video URI for the program. 482 * @return This Builder object to allow for chaining of calls to builder methods. 483 * @see PreviewPrograms#COLUMN_PREVIEW_VIDEO_URI 484 */ 485 public T setPreviewVideoUri(Uri previewVideoUri) { 486 mValues.put(PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI, 487 previewVideoUri == null ? null : previewVideoUri.toString()); 488 return (T) this; 489 } 490 491 /** 492 * Sets the last playback position (in milliseconds) of the preview video. 493 * 494 * @param position The last playback posirion for the program in millis. 495 * @return This Builder object to allow for chaining of calls to builder methods. 496 * @see PreviewPrograms#COLUMN_LAST_PLAYBACK_POSITION_MILLIS 497 */ 498 public T setLastPlaybackPositionMillis(int position) { 499 mValues.put(PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS, position); 500 return (T) this; 501 } 502 503 /** 504 * Sets the last playback duration (in milliseconds) of the preview video. 505 * 506 * @param duration The duration the program in millis. 507 * @return This Builder object to allow for chaining of calls to builder methods. 508 * @see PreviewPrograms#COLUMN_DURATION_MILLIS 509 */ 510 public T setDurationMillis(int duration) { 511 mValues.put(PreviewPrograms.COLUMN_DURATION_MILLIS, duration); 512 return (T) this; 513 } 514 515 /** 516 * Sets the intent URI which is launched when the program is selected. 517 * 518 * @param intentUri The intent URI for the program. 519 * @return This Builder object to allow for chaining of calls to builder methods. 520 * @see PreviewPrograms#COLUMN_INTENT_URI 521 */ 522 public T setIntentUri(Uri intentUri) { 523 mValues.put(PreviewPrograms.COLUMN_INTENT_URI, 524 intentUri == null ? null : intentUri.toString()); 525 return (T) this; 526 } 527 528 /** 529 * Sets the intent which is launched when the program is selected. 530 * 531 * @param intent The Intent to be executed when the preview program is selected 532 * @return This Builder object to allow for chaining of calls to builder methods. 533 */ 534 public T setIntent(Intent intent) { 535 return setIntentUri(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); 536 } 537 538 /** 539 * Sets whether this program is transient or not. 540 * 541 * @param transientValue Whether the program is transient or not. 542 * @return This Builder object to allow for chaining of calls to builder methods. 543 * @see PreviewPrograms#COLUMN_TRANSIENT 544 */ 545 public T setTransient(boolean transientValue) { 546 mValues.put(PreviewPrograms.COLUMN_TRANSIENT, transientValue ? IS_TRANSIENT : 0); 547 return (T) this; 548 } 549 550 /** 551 * Sets the type of this program content. 552 * 553 * <p>The value should match one of the followings: 554 * {@link PreviewPrograms#TYPE_MOVIE}, 555 * {@link PreviewPrograms#TYPE_TV_SERIES}, 556 * {@link PreviewPrograms#TYPE_TV_SEASON}, 557 * {@link PreviewPrograms#TYPE_TV_EPISODE}, 558 * {@link PreviewPrograms#TYPE_CLIP}, 559 * {@link PreviewPrograms#TYPE_EVENT}, 560 * {@link PreviewPrograms#TYPE_CHANNEL}, 561 * {@link PreviewPrograms#TYPE_TRACK}, 562 * {@link PreviewPrograms#TYPE_ALBUM}, 563 * {@link PreviewPrograms#TYPE_ARTIST}, 564 * {@link PreviewPrograms#TYPE_PLAYLIST}, and 565 * {@link PreviewPrograms#TYPE_STATION}. 566 * 567 * @param type The type of the program. 568 * @return This Builder object to allow for chaining of calls to builder methods. 569 * @see PreviewPrograms#COLUMN_TYPE 570 */ 571 public T setType(@Type int type) { 572 mValues.put(PreviewPrograms.COLUMN_TYPE, type); 573 return (T) this; 574 } 575 576 /** 577 * Sets the aspect ratio of the poster art for this TV program. 578 * 579 * <p>The value should match one of the followings: 580 * {@link PreviewPrograms#ASPECT_RATIO_16_9}, 581 * {@link PreviewPrograms#ASPECT_RATIO_3_2}, 582 * {@link PreviewPrograms#ASPECT_RATIO_4_3}, 583 * {@link PreviewPrograms#ASPECT_RATIO_1_1}, and 584 * {@link PreviewPrograms#ASPECT_RATIO_2_3}. 585 * 586 * @param ratio The poster art aspect ratio for the program. 587 * @return This Builder object to allow for chaining of calls to builder methods. 588 * @see PreviewPrograms#COLUMN_POSTER_ART_ASPECT_RATIO 589 * @see PreviewPrograms#COLUMN_POSTER_ART_URI 590 */ 591 public T setPosterArtAspectRatio(@AspectRatio int ratio) { 592 mValues.put(PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO, ratio); 593 return (T) this; 594 } 595 596 /** 597 * Sets the aspect ratio of the thumbnail for this TV program. 598 * 599 * <p>The value should match one of the followings: 600 * {@link PreviewPrograms#ASPECT_RATIO_16_9}, 601 * {@link PreviewPrograms#ASPECT_RATIO_3_2}, 602 * {@link PreviewPrograms#ASPECT_RATIO_4_3}, 603 * {@link PreviewPrograms#ASPECT_RATIO_1_1}, and 604 * {@link PreviewPrograms#ASPECT_RATIO_2_3}. 605 * 606 * @param ratio The thumbnail aspect ratio of the program. 607 * @return This Builder object to allow for chaining of calls to builder methods. 608 * @see PreviewPrograms#COLUMN_THUMBNAIL_ASPECT_RATIO 609 */ 610 public T setThumbnailAspectRatio(@AspectRatio int ratio) { 611 mValues.put(PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO, ratio); 612 return (T) this; 613 } 614 615 /** 616 * Sets the URI for the logo of this TV program. 617 * 618 * @param logoUri The logo URI for the program. 619 * @return This Builder object to allow for chaining of calls to builder methods. 620 * @see PreviewPrograms#COLUMN_LOGO_URI 621 */ 622 public T setLogoUri(Uri logoUri) { 623 mValues.put(PreviewPrograms.COLUMN_LOGO_URI, 624 logoUri == null ? null : logoUri.toString()); 625 return (T) this; 626 } 627 628 /** 629 * Sets the availability of this TV program. 630 * 631 * <p>The value should match one of the followings: 632 * {@link PreviewPrograms#AVAILABILITY_AVAILABLE}, 633 * {@link PreviewPrograms#AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and 634 * {@link PreviewPrograms#AVAILABILITY_PAID_CONTENT}. 635 * 636 * @param availability The availability of the program. 637 * @return This Builder object to allow for chaining of calls to builder methods. 638 * @see PreviewPrograms#COLUMN_AVAILABILITY 639 */ 640 public T setAvailability(@Availability int availability) { 641 mValues.put(PreviewPrograms.COLUMN_AVAILABILITY, availability); 642 return (T) this; 643 } 644 645 /** 646 * Sets the starting price of this TV program. 647 * 648 * @param price The starting price of the program. 649 * @return This Builder object to allow for chaining of calls to builder methods. 650 * @see PreviewPrograms#COLUMN_STARTING_PRICE 651 */ 652 public T setStartingPrice(String price) { 653 mValues.put(PreviewPrograms.COLUMN_STARTING_PRICE, price); 654 return (T) this; 655 } 656 657 /** 658 * Sets the offer price of this TV program. 659 * 660 * @param price The offer price of the program. 661 * @return This Builder object to allow for chaining of calls to builder methods. 662 * @see PreviewPrograms#COLUMN_OFFER_PRICE 663 */ 664 public T setOfferPrice(String price) { 665 mValues.put(PreviewPrograms.COLUMN_OFFER_PRICE, price); 666 return (T) this; 667 } 668 669 /** 670 * Sets the release date of this TV program. 671 * 672 * <p>The value should be in one of the following formats: 673 * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601). 674 * 675 * @param releaseDate The release date of the program. 676 * @return This Builder object to allow for chaining of calls to builder methods. 677 * @see PreviewPrograms#COLUMN_RELEASE_DATE 678 */ 679 public T setReleaseDate(String releaseDate) { 680 mValues.put(PreviewPrograms.COLUMN_RELEASE_DATE, releaseDate); 681 return (T) this; 682 } 683 684 /** 685 * Sets the release date of this TV program. 686 * 687 * @param releaseDate The release date of the program. 688 * @return This Builder object to allow for chaining of calls to builder methods. 689 * @see PreviewPrograms#COLUMN_RELEASE_DATE 690 */ 691 public T setReleaseDate(Date releaseDate) { 692 mValues.put(PreviewPrograms.COLUMN_RELEASE_DATE, sFormat.format(releaseDate)); 693 return (T) this; 694 } 695 696 /** 697 * Sets the count of the items included in this TV program. 698 * 699 * @param itemCount The item count for the program. 700 * @return This Builder object to allow for chaining of calls to builder methods. 701 * @see PreviewPrograms#COLUMN_ITEM_COUNT 702 */ 703 public T setItemCount(int itemCount) { 704 mValues.put(PreviewPrograms.COLUMN_ITEM_COUNT, itemCount); 705 return (T) this; 706 } 707 708 /** 709 * Sets whether this TV program is live or not. 710 * 711 * @param live Whether the program is live or not. 712 * @return This Builder object to allow for chaining of calls to builder methods. 713 * @see PreviewPrograms#COLUMN_LIVE 714 */ 715 public T setLive(boolean live) { 716 mValues.put(PreviewPrograms.COLUMN_LIVE, live ? IS_LIVE : 0); 717 return (T) this; 718 } 719 720 /** 721 * Sets the type of interaction for this TV program. 722 * 723 * <p> The value should match one of the followings: 724 * {@link PreviewPrograms#INTERACTION_TYPE_LISTENS}, 725 * {@link PreviewPrograms#INTERACTION_TYPE_FOLLOWERS}, 726 * {@link PreviewPrograms#INTERACTION_TYPE_FANS}, 727 * {@link PreviewPrograms#INTERACTION_TYPE_LIKES}, 728 * {@link PreviewPrograms#INTERACTION_TYPE_THUMBS}, 729 * {@link PreviewPrograms#INTERACTION_TYPE_VIEWS}, and 730 * {@link PreviewPrograms#INTERACTION_TYPE_VIEWERS}. 731 * 732 * @param interactionType The interaction type of the program. 733 * @return This Builder object to allow for chaining of calls to builder methods. 734 * @see PreviewPrograms#COLUMN_INTERACTION_TYPE 735 */ 736 public T setInteractionType(@InteractionType int interactionType) { 737 mValues.put(PreviewPrograms.COLUMN_INTERACTION_TYPE, interactionType); 738 return (T) this; 739 } 740 741 /** 742 * Sets the interaction count for this program. 743 * 744 * @param interactionCount The interaction count for the program. 745 * @return This Builder object to allow for chaining of calls to builder methods. 746 * @see PreviewPrograms#COLUMN_INTERACTION_COUNT 747 */ 748 public T setInteractionCount(long interactionCount) { 749 mValues.put(PreviewPrograms.COLUMN_INTERACTION_COUNT, interactionCount); 750 return (T) this; 751 } 752 753 /** 754 * Sets the author or artist of this content. 755 * 756 * @param author The author of the program. 757 * @return This Builder object to allow for chaining of calls to builder methods. 758 * @see PreviewPrograms#COLUMN_AUTHOR 759 */ 760 public T setAuthor(String author) { 761 mValues.put(PreviewPrograms.COLUMN_AUTHOR, author); 762 return (T) this; 763 } 764 765 /** 766 * Sets whether this TV program is browsable or not. 767 * 768 * @param browsable Whether the program is browsable or not. 769 * @return This Builder object to allow for chaining of calls to builder methods. 770 * @see PreviewPrograms#COLUMN_BROWSABLE 771 * @hide 772 */ 773 @RestrictTo(LIBRARY_GROUP) 774 public T setBrowsable(boolean browsable) { 775 mValues.put(PreviewPrograms.COLUMN_BROWSABLE, browsable ? IS_BROWSABLE : 0); 776 return (T) this; 777 } 778 779 /** 780 * Sets the content ID for this program. 781 * 782 * @param contentId The content ID for the program. 783 * @return This Builder object to allow for chaining of calls to builder methods. 784 * @see PreviewPrograms#COLUMN_CONTENT_ID 785 */ 786 public T setContentId(String contentId) { 787 mValues.put(PreviewPrograms.COLUMN_CONTENT_ID, contentId); 788 return (T) this; 789 } 790 } 791} 792