BasePreviewProgram.java revision b31c3281d870e9abb673db239234d580dcc4feff
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.content.Intent; 23import android.database.Cursor; 24import android.net.Uri; 25import android.os.Build; 26import androidx.annotation.IntDef; 27import androidx.annotation.RestrictTo; 28import androidx.tvprovider.media.tv.TvContractCompat.PreviewProgramColumns; 29import androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms; 30 31import java.lang.annotation.Retention; 32import java.lang.annotation.RetentionPolicy; 33import java.net.URISyntaxException; 34import java.text.SimpleDateFormat; 35import java.util.Date; 36import java.util.TimeZone; 37 38/** 39 * Base class for derived classes that want to have common fields for preview programs. 40 * 41 * @hide 42 */ 43@RestrictTo(LIBRARY) 44public abstract class BasePreviewProgram extends BaseProgram { 45 /** 46 * @hide 47 */ 48 @RestrictTo(LIBRARY_GROUP) 49 public static final String[] PROJECTION = getProjection(); 50 51 private static final int INVALID_INT_VALUE = -1; 52 private static final long INVALID_LONG_VALUE = -1; 53 private static final int IS_TRANSIENT = 1; 54 private static final int IS_LIVE = 1; 55 private static final int IS_BROWSABLE = 1; 56 57 /** @hide */ 58 @IntDef({ 59 TYPE_UNKNOWN, 60 PreviewProgramColumns.TYPE_MOVIE, 61 PreviewProgramColumns.TYPE_TV_SERIES, 62 PreviewProgramColumns.TYPE_TV_SEASON, 63 PreviewProgramColumns.TYPE_TV_EPISODE, 64 PreviewProgramColumns.TYPE_CLIP, 65 PreviewProgramColumns.TYPE_EVENT, 66 PreviewProgramColumns.TYPE_CHANNEL, 67 PreviewProgramColumns.TYPE_TRACK, 68 PreviewProgramColumns.TYPE_ALBUM, 69 PreviewProgramColumns.TYPE_ARTIST, 70 PreviewProgramColumns.TYPE_PLAYLIST, 71 PreviewProgramColumns.TYPE_STATION, 72 PreviewProgramColumns.TYPE_GAME 73 }) 74 @Retention(RetentionPolicy.SOURCE) 75 @RestrictTo(LIBRARY_GROUP) 76 public @interface Type {} 77 78 /** 79 * The unknown program type. 80 */ 81 private static final int TYPE_UNKNOWN = -1; 82 83 /** @hide */ 84 @IntDef({ 85 ASPECT_RATIO_UNKNOWN, 86 PreviewProgramColumns.ASPECT_RATIO_16_9, 87 PreviewProgramColumns.ASPECT_RATIO_3_2, 88 PreviewProgramColumns.ASPECT_RATIO_4_3, 89 PreviewProgramColumns.ASPECT_RATIO_1_1, 90 PreviewProgramColumns.ASPECT_RATIO_2_3, 91 PreviewProgramColumns.ASPECT_RATIO_MOVIE_POSTER 92 }) 93 @Retention(RetentionPolicy.SOURCE) 94 @RestrictTo(LIBRARY_GROUP) 95 public @interface AspectRatio {} 96 97 /** 98 * The aspect ratio for unknown aspect ratios. 99 */ 100 private static final int ASPECT_RATIO_UNKNOWN = -1; 101 102 /** @hide */ 103 @IntDef({ 104 AVAILABILITY_UNKNOWN, 105 PreviewProgramColumns.AVAILABILITY_AVAILABLE, 106 PreviewProgramColumns.AVAILABILITY_FREE_WITH_SUBSCRIPTION, 107 PreviewProgramColumns.AVAILABILITY_PAID_CONTENT, 108 PreviewProgramColumns.AVAILABILITY_PURCHASED, 109 PreviewProgramColumns.AVAILABILITY_FREE 110 }) 111 @Retention(RetentionPolicy.SOURCE) 112 @RestrictTo(LIBRARY_GROUP) 113 public @interface Availability {} 114 115 /** 116 * The unknown availability. 117 */ 118 private static final int AVAILABILITY_UNKNOWN = -1; 119 120 /** @hide */ 121 @IntDef({ 122 INTERACTION_TYPE_UNKNOWN, 123 PreviewProgramColumns.INTERACTION_TYPE_VIEWS, 124 PreviewProgramColumns.INTERACTION_TYPE_LISTENS, 125 PreviewProgramColumns.INTERACTION_TYPE_FOLLOWERS, 126 PreviewProgramColumns.INTERACTION_TYPE_FANS, 127 PreviewProgramColumns.INTERACTION_TYPE_LIKES, 128 PreviewProgramColumns.INTERACTION_TYPE_THUMBS, 129 PreviewProgramColumns.INTERACTION_TYPE_VIEWERS, 130 }) 131 @Retention(RetentionPolicy.SOURCE) 132 @RestrictTo(LIBRARY_GROUP) 133 public @interface InteractionType {} 134 135 /** 136 * The unknown interaction type. 137 */ 138 private static final int INTERACTION_TYPE_UNKNOWN = -1; 139 140 BasePreviewProgram(Builder builder) { 141 super(builder); 142 } 143 144 /** 145 * @return The internal provider ID for the program. 146 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTERNAL_PROVIDER_ID 147 */ 148 public String getInternalProviderId() { 149 return mValues.getAsString(PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID); 150 } 151 152 /** 153 * @return The preview video URI for the program. 154 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_PREVIEW_VIDEO_URI 155 */ 156 public Uri getPreviewVideoUri() { 157 String uri = mValues.getAsString(PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI); 158 return uri == null ? null : Uri.parse(uri); 159 } 160 161 /** 162 * @return The last playback position of the program in millis. 163 * @see androidx.tvprovider.media.tv.TvContractCompat 164 * .PreviewPrograms#COLUMN_LAST_PLAYBACK_POSITION_MILLIS 165 */ 166 public int getLastPlaybackPositionMillis() { 167 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS); 168 return i == null ? INVALID_INT_VALUE : i; 169 } 170 171 /** 172 * @return The duration of the program in millis. 173 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_DURATION_MILLIS 174 */ 175 public int getDurationMillis() { 176 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_DURATION_MILLIS); 177 return i == null ? INVALID_INT_VALUE : i; 178 } 179 180 /** 181 * @return The intent URI which is launched when the program is selected. 182 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTENT_URI 183 */ 184 public Uri getIntentUri() { 185 String uri = mValues.getAsString(PreviewPrograms.COLUMN_INTENT_URI); 186 return uri == null ? null : Uri.parse(uri); 187 } 188 189 /** 190 * @return The intent which is launched when the program is selected. 191 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTENT_URI 192 */ 193 public Intent getIntent() throws URISyntaxException { 194 String uri = mValues.getAsString(PreviewPrograms.COLUMN_INTENT_URI); 195 return uri == null ? null : Intent.parseUri(uri, Intent.URI_INTENT_SCHEME); 196 } 197 198 /** 199 * @return Whether the program is transient or not. 200 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_TRANSIENT 201 */ 202 public boolean isTransient() { 203 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_TRANSIENT); 204 return i != null && i == IS_TRANSIENT; 205 } 206 207 /** 208 * @return The type of the program. 209 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_TYPE 210 */ 211 public @Type int getType() { 212 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_TYPE); 213 return i == null ? TYPE_UNKNOWN : i; 214 } 215 216 /** 217 * @return The poster art aspect ratio for the program. 218 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_POSTER_ART_ASPECT_RATIO 219 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_POSTER_ART_URI 220 */ 221 public @AspectRatio int getPosterArtAspectRatio() { 222 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO); 223 return i == null ? ASPECT_RATIO_UNKNOWN : i; 224 } 225 226 /** 227 * @return The thumbnail aspect ratio for the program. 228 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_THUMBNAIL_ASPECT_RATIO 229 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_THUMBNAIL_URI 230 */ 231 public @AspectRatio int getThumbnailAspectRatio() { 232 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO); 233 return i == null ? ASPECT_RATIO_UNKNOWN : i; 234 } 235 236 /** 237 * @return The logo URI for the program. 238 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LOGO_URI 239 */ 240 public Uri getLogoUri() { 241 String uri = mValues.getAsString(PreviewPrograms.COLUMN_LOGO_URI); 242 return uri == null ? null : Uri.parse(uri); 243 } 244 245 /** 246 * @return The availability of the program. 247 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_AVAILABILITY 248 */ 249 public @Availability int getAvailability() { 250 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_AVAILABILITY); 251 return i == null ? AVAILABILITY_UNKNOWN : i; 252 } 253 254 /** 255 * @return The starting price of the program. 256 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_STARTING_PRICE 257 */ 258 public String getStartingPrice() { 259 return mValues.getAsString(PreviewPrograms.COLUMN_STARTING_PRICE); 260 } 261 262 /** 263 * @return The offer price of the program. 264 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_OFFER_PRICE 265 */ 266 public String getOfferPrice() { 267 return mValues.getAsString(PreviewPrograms.COLUMN_OFFER_PRICE); 268 } 269 270 /** 271 * @return The release date of the program. 272 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_RELEASE_DATE 273 */ 274 public String getReleaseDate() { 275 return mValues.getAsString(PreviewPrograms.COLUMN_RELEASE_DATE); 276 } 277 278 /** 279 * @return The item count for the program. 280 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_ITEM_COUNT 281 */ 282 public int getItemCount() { 283 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_ITEM_COUNT); 284 return i == null ? INVALID_INT_VALUE : i; 285 } 286 287 /** 288 * @return Whether the program is live or not. 289 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LIVE 290 */ 291 public boolean isLive() { 292 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_LIVE); 293 return i != null && i == IS_LIVE; 294 } 295 296 /** 297 * @return The interaction type for the program. 298 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTERACTION_TYPE 299 */ 300 public @InteractionType int getInteractionType() { 301 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_INTERACTION_TYPE); 302 return i == null ? INTERACTION_TYPE_UNKNOWN : i; 303 } 304 305 /** 306 * @return The interaction count for the program. 307 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTERACTION_COUNT 308 */ 309 public long getInteractionCount() { 310 Long l = mValues.getAsLong(PreviewPrograms.COLUMN_INTERACTION_COUNT); 311 return l == null ? INVALID_LONG_VALUE : l; 312 } 313 314 /** 315 * @return The author for the program. 316 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_AUTHOR 317 */ 318 public String getAuthor() { 319 return mValues.getAsString(PreviewPrograms.COLUMN_AUTHOR); 320 } 321 322 /** 323 * @return Whether the program is browsable or not. 324 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_BROWSABLE 325 */ 326 public boolean isBrowsable() { 327 Integer i = mValues.getAsInteger(PreviewPrograms.COLUMN_BROWSABLE); 328 return i != null && i == IS_BROWSABLE; 329 } 330 331 /** 332 * @return The content ID for the program. 333 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_CONTENT_ID 334 */ 335 public String getContentId() { 336 return mValues.getAsString(PreviewPrograms.COLUMN_CONTENT_ID); 337 } 338 339 /** 340 * @return The logo content description for the program. 341 * @see androidx.tvprovider.media.tv.TvContractCompat 342 * .PreviewPrograms#COLUMN_LOGO_CONTENT_DESCRIPTION 343 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LOGO_URI 344 */ 345 public String getLogoContentDescription() { 346 return mValues.getAsString(PreviewPrograms.COLUMN_LOGO_CONTENT_DESCRIPTION); 347 } 348 349 /** 350 * @return The genre for the program. 351 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_GENRE 352 */ 353 public String getGenre() { 354 return mValues.getAsString(PreviewPrograms.COLUMN_GENRE); 355 } 356 357 /** 358 * @return The start time for the program. 359 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_START_TIME_UTC_MILLIS 360 */ 361 public long getStartTimeUtcMillis() { 362 Long l = mValues.getAsLong(PreviewPrograms.COLUMN_START_TIME_UTC_MILLIS); 363 return l == null ? INVALID_LONG_VALUE : l; 364 } 365 366 /** 367 * @return The end time for the program. 368 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_END_TIME_UTC_MILLIS 369 */ 370 public long getEndTimeUtcMillis() { 371 Long l = mValues.getAsLong(PreviewPrograms.COLUMN_END_TIME_UTC_MILLIS); 372 return l == null ? INVALID_LONG_VALUE : l; 373 } 374 375 /** 376 * @return The preview audio URI for the program. 377 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_PREVIEW_AUDIO_URI 378 */ 379 public Uri getPreviewAudioUri() { 380 String uri = mValues.getAsString(PreviewPrograms.COLUMN_PREVIEW_AUDIO_URI); 381 return uri == null ? null : Uri.parse(uri); 382 } 383 384 @Override 385 public boolean equals(Object other) { 386 if (!(other instanceof BasePreviewProgram)) { 387 return false; 388 } 389 return mValues.equals(((BasePreviewProgram) other).mValues); 390 } 391 392 /** 393 * @return The fields of the BasePreviewProgram in {@link ContentValues} format to be easily 394 * inserted into the TV Input Framework database. 395 */ 396 @Override 397 public ContentValues toContentValues() { 398 return toContentValues(false); 399 } 400 401 /** 402 * Returns fields of the BasePreviewProgram in the ContentValues format to be easily inserted 403 * into the TV Input Framework database. 404 * 405 * @param includeProtectedFields Whether the fields protected by system is included or not. 406 * @hide 407 */ 408 @RestrictTo(LIBRARY_GROUP) 409 public ContentValues toContentValues(boolean includeProtectedFields) { 410 ContentValues values = super.toContentValues(); 411 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 412 values.remove(PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID); 413 values.remove(PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI); 414 values.remove(PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS); 415 values.remove(PreviewProgramColumns.COLUMN_DURATION_MILLIS); 416 values.remove(PreviewProgramColumns.COLUMN_INTENT_URI); 417 values.remove(PreviewProgramColumns.COLUMN_TRANSIENT); 418 values.remove(PreviewProgramColumns.COLUMN_TYPE); 419 values.remove(PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO); 420 values.remove(PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO); 421 values.remove(PreviewProgramColumns.COLUMN_LOGO_URI); 422 values.remove(PreviewProgramColumns.COLUMN_AVAILABILITY); 423 values.remove(PreviewProgramColumns.COLUMN_STARTING_PRICE); 424 values.remove(PreviewProgramColumns.COLUMN_OFFER_PRICE); 425 values.remove(PreviewProgramColumns.COLUMN_RELEASE_DATE); 426 values.remove(PreviewProgramColumns.COLUMN_ITEM_COUNT); 427 values.remove(PreviewProgramColumns.COLUMN_LIVE); 428 values.remove(PreviewProgramColumns.COLUMN_INTERACTION_COUNT); 429 values.remove(PreviewProgramColumns.COLUMN_AUTHOR); 430 values.remove(PreviewProgramColumns.COLUMN_CONTENT_ID); 431 values.remove(PreviewProgramColumns.COLUMN_LOGO_CONTENT_DESCRIPTION); 432 values.remove(PreviewProgramColumns.COLUMN_GENRE); 433 values.remove(PreviewProgramColumns.COLUMN_START_TIME_UTC_MILLIS); 434 values.remove(PreviewProgramColumns.COLUMN_END_TIME_UTC_MILLIS); 435 values.remove(PreviewProgramColumns.COLUMN_PREVIEW_AUDIO_URI); 436 } 437 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !includeProtectedFields) { 438 values.remove(PreviewProgramColumns.COLUMN_BROWSABLE); 439 } 440 return values; 441 } 442 443 /** 444 * Sets the fields in the cursor to the given builder instance. 445 * 446 * @param cursor A row from the TV Input Framework database. 447 * @param builder A Builder to set the fields. 448 */ 449 static void setFieldsFromCursor(Cursor cursor, Builder builder) { 450 // TODO: Add additional API which does not use costly getColumnIndex(). 451 BaseProgram.setFieldsFromCursor(cursor, builder); 452 int index; 453 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 454 if ((index = 455 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID)) >= 0 456 && !cursor.isNull(index)) { 457 builder.setInternalProviderId(cursor.getString(index)); 458 } 459 if ((index = 460 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI)) >= 0 461 && !cursor.isNull(index)) { 462 builder.setPreviewVideoUri(Uri.parse(cursor.getString(index))); 463 } 464 if ((index = cursor.getColumnIndex( 465 PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS)) >= 0 466 && !cursor.isNull(index)) { 467 builder.setLastPlaybackPositionMillis(cursor.getInt(index)); 468 } 469 if ((index = 470 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_DURATION_MILLIS)) >= 0 471 && !cursor.isNull(index)) { 472 builder.setDurationMillis(cursor.getInt(index)); 473 } 474 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTENT_URI)) >= 0 475 && !cursor.isNull(index)) { 476 builder.setIntentUri(Uri.parse(cursor.getString(index))); 477 } 478 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_TRANSIENT)) >= 0 479 && !cursor.isNull(index)) { 480 builder.setTransient(cursor.getInt(index) == IS_TRANSIENT); 481 } 482 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_TYPE)) >= 0 483 && !cursor.isNull(index)) { 484 builder.setType(cursor.getInt(index)); 485 } 486 if ((index = cursor.getColumnIndex( 487 PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO)) >= 0 488 && !cursor.isNull(index)) { 489 builder.setPosterArtAspectRatio(cursor.getInt(index)); 490 } 491 if ((index = 492 cursor.getColumnIndex(PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO)) >= 0 493 && !cursor.isNull(index)) { 494 builder.setThumbnailAspectRatio(cursor.getInt(index)); 495 } 496 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_LOGO_URI)) >= 0 497 && !cursor.isNull(index)) { 498 builder.setLogoUri(Uri.parse(cursor.getString(index))); 499 } 500 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_AVAILABILITY)) >= 0 501 && !cursor.isNull(index)) { 502 builder.setAvailability(cursor.getInt(index)); 503 } 504 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_STARTING_PRICE)) >= 0 505 && !cursor.isNull(index)) { 506 builder.setStartingPrice(cursor.getString(index)); 507 } 508 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_OFFER_PRICE)) >= 0 509 && !cursor.isNull(index)) { 510 builder.setOfferPrice(cursor.getString(index)); 511 } 512 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_RELEASE_DATE)) >= 0 513 && !cursor.isNull(index)) { 514 builder.setReleaseDate(cursor.getString(index)); 515 } 516 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_ITEM_COUNT)) >= 0 517 && !cursor.isNull(index)) { 518 builder.setItemCount(cursor.getInt(index)); 519 } 520 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_LIVE)) >= 0 521 && !cursor.isNull(index)) { 522 builder.setLive(cursor.getInt(index) == IS_LIVE); 523 } 524 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERACTION_TYPE)) >= 0 525 && !cursor.isNull(index)) { 526 builder.setInteractionType(cursor.getInt(index)); 527 } 528 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_INTERACTION_COUNT)) >= 0 529 && !cursor.isNull(index)) { 530 builder.setInteractionCount(cursor.getInt(index)); 531 } 532 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_AUTHOR)) >= 0 533 && !cursor.isNull(index)) { 534 builder.setAuthor(cursor.getString(index)); 535 } 536 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_BROWSABLE)) >= 0 537 && !cursor.isNull(index)) { 538 builder.setBrowsable(cursor.getInt(index) == IS_BROWSABLE); 539 } 540 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_CONTENT_ID)) >= 0 541 && !cursor.isNull(index)) { 542 builder.setContentId(cursor.getString(index)); 543 } 544 if ((index = cursor.getColumnIndex( 545 PreviewProgramColumns.COLUMN_LOGO_CONTENT_DESCRIPTION)) >= 0 546 && !cursor.isNull(index)) { 547 builder.setLogoContentDescription(cursor.getString(index)); 548 } 549 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_GENRE)) >= 0 550 && !cursor.isNull(index)) { 551 builder.setGenre(cursor.getString(index)); 552 } 553 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_START_TIME_UTC_MILLIS)) 554 >= 0 && !cursor.isNull(index)) { 555 builder.setStartTimeUtcMillis(cursor.getLong(index)); 556 } 557 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_END_TIME_UTC_MILLIS)) 558 >= 0 && !cursor.isNull(index)) { 559 builder.setEndTimeUtcMillis(cursor.getLong(index)); 560 } 561 if ((index = cursor.getColumnIndex(PreviewProgramColumns.COLUMN_PREVIEW_AUDIO_URI)) >= 0 562 && !cursor.isNull(index)) { 563 builder.setPreviewAudioUri(Uri.parse(cursor.getString(index))); 564 } 565 } 566 } 567 568 private static String[] getProjection() { 569 String[] oColumns = new String[] { 570 PreviewProgramColumns.COLUMN_INTERNAL_PROVIDER_ID, 571 PreviewProgramColumns.COLUMN_PREVIEW_VIDEO_URI, 572 PreviewProgramColumns.COLUMN_LAST_PLAYBACK_POSITION_MILLIS, 573 PreviewProgramColumns.COLUMN_DURATION_MILLIS, 574 PreviewProgramColumns.COLUMN_INTENT_URI, 575 PreviewProgramColumns.COLUMN_TRANSIENT, 576 PreviewProgramColumns.COLUMN_TYPE, 577 PreviewProgramColumns.COLUMN_POSTER_ART_ASPECT_RATIO, 578 PreviewProgramColumns.COLUMN_THUMBNAIL_ASPECT_RATIO, 579 PreviewProgramColumns.COLUMN_LOGO_URI, 580 PreviewProgramColumns.COLUMN_AVAILABILITY, 581 PreviewProgramColumns.COLUMN_STARTING_PRICE, 582 PreviewProgramColumns.COLUMN_OFFER_PRICE, 583 PreviewProgramColumns.COLUMN_RELEASE_DATE, 584 PreviewProgramColumns.COLUMN_ITEM_COUNT, 585 PreviewProgramColumns.COLUMN_LIVE, 586 PreviewProgramColumns.COLUMN_INTERACTION_TYPE, 587 PreviewProgramColumns.COLUMN_INTERACTION_COUNT, 588 PreviewProgramColumns.COLUMN_AUTHOR, 589 PreviewProgramColumns.COLUMN_BROWSABLE, 590 PreviewProgramColumns.COLUMN_CONTENT_ID, 591 PreviewProgramColumns.COLUMN_LOGO_CONTENT_DESCRIPTION, 592 PreviewProgramColumns.COLUMN_GENRE, 593 PreviewProgramColumns.COLUMN_START_TIME_UTC_MILLIS, 594 PreviewProgramColumns.COLUMN_END_TIME_UTC_MILLIS, 595 PreviewProgramColumns.COLUMN_PREVIEW_AUDIO_URI, 596 }; 597 return CollectionUtils.concatAll(BaseProgram.PROJECTION, oColumns); 598 } 599 600 /** 601 * This Builder class simplifies the creation of a {@link BasePreviewProgram} object. 602 * 603 * @param <T> The Builder of the derived classe. 604 */ 605 public abstract static class Builder<T extends Builder> extends BaseProgram.Builder<T> { 606 private static final SimpleDateFormat sFormat = 607 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 608 609 static { 610 sFormat.setTimeZone(TimeZone.getTimeZone("GMT-0")); 611 } 612 613 /** 614 * Creates a new Builder object. 615 */ 616 public Builder() { 617 } 618 619 /** 620 * Creates a new Builder object with values copied from another Program. 621 * 622 * @param other The Program you're copying from. 623 */ 624 public Builder(BasePreviewProgram other) { 625 mValues = new ContentValues(other.mValues); 626 } 627 628 /** 629 * Sets external ID for the program. 630 * 631 * @param externalId The internal provider ID for the program. 632 * @return This Builder object to allow for chaining of calls to builder methods. 633 * @see androidx.tvprovider.media.tv.TvContractCompat 634 * .PreviewPrograms#COLUMN_INTERNAL_PROVIDER_ID 635 */ 636 public T setInternalProviderId(String externalId) { 637 mValues.put(PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID, externalId); 638 return (T) this; 639 } 640 641 /** 642 * Sets a URI for the preview video. 643 * 644 * @param previewVideoUri The preview video URI for the program. 645 * @return This Builder object to allow for chaining of calls to builder methods. 646 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_PREVIEW_VIDEO_URI 647 */ 648 public T setPreviewVideoUri(Uri previewVideoUri) { 649 mValues.put(PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI, 650 previewVideoUri == null ? null : previewVideoUri.toString()); 651 return (T) this; 652 } 653 654 /** 655 * Sets the last playback position (in milliseconds) of the preview video. 656 * 657 * @param position The last playback posirion for the program in millis. 658 * @return This Builder object to allow for chaining of calls to builder methods. 659 * @see androidx.tvprovider.media.tv.TvContractCompat 660 * .PreviewPrograms#COLUMN_LAST_PLAYBACK_POSITION_MILLIS 661 */ 662 public T setLastPlaybackPositionMillis(int position) { 663 mValues.put(PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS, position); 664 return (T) this; 665 } 666 667 /** 668 * Sets the last playback duration (in milliseconds) of the preview video. 669 * 670 * @param duration The duration the program in millis. 671 * @return This Builder object to allow for chaining of calls to builder methods. 672 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_DURATION_MILLIS 673 */ 674 public T setDurationMillis(int duration) { 675 mValues.put(PreviewPrograms.COLUMN_DURATION_MILLIS, duration); 676 return (T) this; 677 } 678 679 /** 680 * Sets the intent URI which is launched when the program is selected. 681 * 682 * @param intentUri The intent URI for the program. 683 * @return This Builder object to allow for chaining of calls to builder methods. 684 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTENT_URI 685 */ 686 public T setIntentUri(Uri intentUri) { 687 mValues.put(PreviewPrograms.COLUMN_INTENT_URI, 688 intentUri == null ? null : intentUri.toString()); 689 return (T) this; 690 } 691 692 /** 693 * Sets the intent which is launched when the program is selected. 694 * 695 * @param intent The Intent to be executed when the preview program is selected 696 * @return This Builder object to allow for chaining of calls to builder methods. 697 */ 698 public T setIntent(Intent intent) { 699 return setIntentUri(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); 700 } 701 702 /** 703 * Sets whether this program is transient or not. 704 * 705 * @param transientValue Whether the program is transient or not. 706 * @return This Builder object to allow for chaining of calls to builder methods. 707 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_TRANSIENT 708 */ 709 public T setTransient(boolean transientValue) { 710 mValues.put(PreviewPrograms.COLUMN_TRANSIENT, transientValue ? IS_TRANSIENT : 0); 711 return (T) this; 712 } 713 714 /** 715 * Sets the type of this program content. 716 * 717 * <p>The value should match one of the followings: 718 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_MOVIE}, 719 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_TV_SERIES}, 720 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_TV_SEASON}, 721 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_TV_EPISODE}, 722 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_CLIP}, 723 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_EVENT}, 724 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_CHANNEL}, 725 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_TRACK}, 726 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_ALBUM}, 727 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_ARTIST}, 728 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_PLAYLIST}, 729 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_STATION}, and 730 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#TYPE_GAME}. 731 * 732 * @param type The type of the program. 733 * @return This Builder object to allow for chaining of calls to builder methods. 734 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_TYPE 735 */ 736 public T setType(@Type int type) { 737 mValues.put(PreviewPrograms.COLUMN_TYPE, type); 738 return (T) this; 739 } 740 741 /** 742 * Sets the aspect ratio of the poster art for this TV program. 743 * 744 * <p>The value should match one of the followings: 745 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_16_9}, 746 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_3_2}, 747 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_4_3}, 748 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_1_1}, 749 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_2_3}, and 750 * {@link androidx.tvprovider.media.tv.TvContractCompat 751 * .PreviewPrograms#ASPECT_RATIO_MOVIE_POSTER}. 752 * 753 * @param ratio The poster art aspect ratio for the program. 754 * @return This Builder object to allow for chaining of calls to builder methods. 755 * @see androidx.tvprovider.media.tv.TvContractCompat 756 * .PreviewPrograms#COLUMN_POSTER_ART_ASPECT_RATIO 757 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_POSTER_ART_URI 758 */ 759 public T setPosterArtAspectRatio(@AspectRatio int ratio) { 760 mValues.put(PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO, ratio); 761 return (T) this; 762 } 763 764 /** 765 * Sets the aspect ratio of the thumbnail for this TV program. 766 * 767 * <p>The value should match one of the followings: 768 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_16_9}, 769 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_3_2}, 770 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_4_3}, 771 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_1_1}, 772 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#ASPECT_RATIO_2_3}, and 773 * {@link androidx.tvprovider.media.tv.TvContractCompat 774 * .PreviewPrograms#ASPECT_RATIO_MOVIE_POSTER}. 775 * 776 * @param ratio The thumbnail aspect ratio of the program. 777 * @return This Builder object to allow for chaining of calls to builder methods. 778 * @see androidx.tvprovider.media.tv.TvContractCompat 779 * .PreviewPrograms#COLUMN_THUMBNAIL_ASPECT_RATIO 780 */ 781 public T setThumbnailAspectRatio(@AspectRatio int ratio) { 782 mValues.put(PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO, ratio); 783 return (T) this; 784 } 785 786 /** 787 * Sets the URI for the logo of this TV program. 788 * 789 * @param logoUri The logo URI for the program. 790 * @return This Builder object to allow for chaining of calls to builder methods. 791 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LOGO_URI 792 */ 793 public T setLogoUri(Uri logoUri) { 794 mValues.put(PreviewPrograms.COLUMN_LOGO_URI, 795 logoUri == null ? null : logoUri.toString()); 796 return (T) this; 797 } 798 799 /** 800 * Sets the availability of this TV program. 801 * 802 * <p>The value should match one of the followings: 803 * {@link androidx.tvprovider.media.tv.TvContractCompat 804 * .PreviewPrograms#AVAILABILITY_AVAILABLE}, 805 * {@link androidx.tvprovider.media.tv.TvContractCompat 806 * .PreviewPrograms#AVAILABILITY_FREE_WITH_SUBSCRIPTION}, 807 * {@link androidx.tvprovider.media.tv.TvContractCompat 808 * .PreviewPrograms#AVAILABILITY_PAID_CONTENT}, 809 * {@link androidx.tvprovider.media.tv.TvContractCompat 810 * .PreviewPrograms#AVAILABILITY_PURCHASED}, and 811 * {@link androidx.tvprovider.media.tv.TvContractCompat 812 * .PreviewPrograms#AVAILABILITY_FREE}. 813 * 814 * @param availability The availability of the program. 815 * @return This Builder object to allow for chaining of calls to builder methods. 816 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_AVAILABILITY 817 */ 818 public T setAvailability(@Availability int availability) { 819 mValues.put(PreviewPrograms.COLUMN_AVAILABILITY, availability); 820 return (T) this; 821 } 822 823 /** 824 * Sets the starting price of this TV program. 825 * 826 * @param price The starting price of the program. 827 * @return This Builder object to allow for chaining of calls to builder methods. 828 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_STARTING_PRICE 829 */ 830 public T setStartingPrice(String price) { 831 mValues.put(PreviewPrograms.COLUMN_STARTING_PRICE, price); 832 return (T) this; 833 } 834 835 /** 836 * Sets the offer price of this TV program. 837 * 838 * @param price The offer price of the program. 839 * @return This Builder object to allow for chaining of calls to builder methods. 840 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_OFFER_PRICE 841 */ 842 public T setOfferPrice(String price) { 843 mValues.put(PreviewPrograms.COLUMN_OFFER_PRICE, price); 844 return (T) this; 845 } 846 847 /** 848 * Sets the release date of this TV program. 849 * 850 * <p>The value should be in one of the following formats: 851 * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601). 852 * 853 * @param releaseDate The release date of the program. 854 * @return This Builder object to allow for chaining of calls to builder methods. 855 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_RELEASE_DATE 856 */ 857 public T setReleaseDate(String releaseDate) { 858 mValues.put(PreviewPrograms.COLUMN_RELEASE_DATE, releaseDate); 859 return (T) this; 860 } 861 862 /** 863 * Sets the release date of this TV program. 864 * 865 * @param releaseDate The release date of the program. 866 * @return This Builder object to allow for chaining of calls to builder methods. 867 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_RELEASE_DATE 868 */ 869 public T setReleaseDate(Date releaseDate) { 870 mValues.put(PreviewPrograms.COLUMN_RELEASE_DATE, sFormat.format(releaseDate)); 871 return (T) this; 872 } 873 874 /** 875 * Sets the count of the items included in this TV program. 876 * 877 * @param itemCount The item count for the program. 878 * @return This Builder object to allow for chaining of calls to builder methods. 879 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_ITEM_COUNT 880 */ 881 public T setItemCount(int itemCount) { 882 mValues.put(PreviewPrograms.COLUMN_ITEM_COUNT, itemCount); 883 return (T) this; 884 } 885 886 /** 887 * Sets whether this TV program is live or not. 888 * 889 * @param live Whether the program is live or not. 890 * @return This Builder object to allow for chaining of calls to builder methods. 891 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LIVE 892 */ 893 public T setLive(boolean live) { 894 mValues.put(PreviewPrograms.COLUMN_LIVE, live ? IS_LIVE : 0); 895 return (T) this; 896 } 897 898 /** 899 * Sets the type of interaction for this TV program. 900 * 901 * <p> The value should match one of the followings: 902 * {@link androidx.tvprovider.media.tv.TvContractCompat 903 * .PreviewPrograms#INTERACTION_TYPE_LISTENS}, 904 * {@link androidx.tvprovider.media.tv.TvContractCompat 905 * .PreviewPrograms#INTERACTION_TYPE_FOLLOWERS}, 906 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#INTERACTION_TYPE_FANS}, 907 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#INTERACTION_TYPE_LIKES}, 908 * {@link androidx.tvprovider.media.tv.TvContractCompat 909 * .PreviewPrograms#INTERACTION_TYPE_THUMBS}, 910 * {@link androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#INTERACTION_TYPE_VIEWS}, 911 * and 912 * {@link androidx.tvprovider.media.tv.TvContractCompat 913 * .PreviewPrograms#INTERACTION_TYPE_VIEWERS}. 914 * 915 * @param interactionType The interaction type of the program. 916 * @return This Builder object to allow for chaining of calls to builder methods. 917 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTERACTION_TYPE 918 */ 919 public T setInteractionType(@InteractionType int interactionType) { 920 mValues.put(PreviewPrograms.COLUMN_INTERACTION_TYPE, interactionType); 921 return (T) this; 922 } 923 924 /** 925 * Sets the interaction count for this program. 926 * 927 * @param interactionCount The interaction count for the program. 928 * @return This Builder object to allow for chaining of calls to builder methods. 929 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_INTERACTION_COUNT 930 */ 931 public T setInteractionCount(long interactionCount) { 932 mValues.put(PreviewPrograms.COLUMN_INTERACTION_COUNT, interactionCount); 933 return (T) this; 934 } 935 936 /** 937 * Sets the author or artist of this content. 938 * 939 * @param author The author of the program. 940 * @return This Builder object to allow for chaining of calls to builder methods. 941 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_AUTHOR 942 */ 943 public T setAuthor(String author) { 944 mValues.put(PreviewPrograms.COLUMN_AUTHOR, author); 945 return (T) this; 946 } 947 948 /** 949 * Sets whether this TV program is browsable or not. 950 * 951 * @param browsable Whether the program is browsable or not. 952 * @return This Builder object to allow for chaining of calls to builder methods. 953 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_BROWSABLE 954 * @hide 955 */ 956 @RestrictTo(LIBRARY_GROUP) 957 public T setBrowsable(boolean browsable) { 958 mValues.put(PreviewPrograms.COLUMN_BROWSABLE, browsable ? IS_BROWSABLE : 0); 959 return (T) this; 960 } 961 962 /** 963 * Sets the content ID for this program. 964 * 965 * @param contentId The content ID for the program. 966 * @return This Builder object to allow for chaining of calls to builder methods. 967 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_CONTENT_ID 968 */ 969 public T setContentId(String contentId) { 970 mValues.put(PreviewPrograms.COLUMN_CONTENT_ID, contentId); 971 return (T) this; 972 } 973 974 /** 975 * Sets the logo's content description for this program. 976 * 977 * @param logoContentDescription The content description for the logo displayed in the 978 * program. 979 * @return This Builder object to allow for chaining of calls to builder methods. 980 * @see androidx.tvprovider.media.tv.TvContractCompat 981 * .PreviewPrograms#COLUMN_LOGO_CONTENT_DESCRIPTION 982 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_LOGO_URI 983 */ 984 public T setLogoContentDescription(String logoContentDescription) { 985 mValues.put(PreviewPrograms.COLUMN_LOGO_CONTENT_DESCRIPTION, logoContentDescription); 986 return (T) this; 987 } 988 989 /** 990 * Sets the genre for this program. 991 * 992 * @param genre The genre for the program. 993 * @return This Builder object to allow for chaining of calls to builder methods. 994 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_GENRE 995 */ 996 public T setGenre(String genre) { 997 mValues.put(PreviewPrograms.COLUMN_GENRE, genre); 998 return (T) this; 999 } 1000 1001 /** 1002 * Sets the start time of the program (for live programs). 1003 * 1004 * @param startTime The start time for the program. 1005 * @return This Builder object to allow for chaining of calls to builder methods. 1006 * @see androidx.tvprovider.media.tv.TvContractCompat 1007 * .PreviewPrograms#COLUMN_START_TIME_UTC_MILLIS 1008 */ 1009 public T setStartTimeUtcMillis(long startTime) { 1010 mValues.put(PreviewPrograms.COLUMN_START_TIME_UTC_MILLIS, startTime); 1011 return (T) this; 1012 } 1013 1014 /** 1015 * Sets the end time of the program (for live programs). 1016 * 1017 * @param endTime The end time for the program. 1018 * @return This Builder object to allow for chaining of calls to builder methods. 1019 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_END_TIME_UTC_MILLIS 1020 */ 1021 public T setEndTimeUtcMillis(long endTime) { 1022 mValues.put(PreviewPrograms.COLUMN_END_TIME_UTC_MILLIS, endTime); 1023 return (T) this; 1024 } 1025 1026 /** 1027 * Sets a URI for the preview audio. 1028 * 1029 * @param previewAudioUri The preview audio URI for the program. 1030 * @return This Builder object to allow for chaining of calls to builder methods. 1031 * @see androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms#COLUMN_PREVIEW_AUDIO_URI 1032 */ 1033 public T setPreviewAudioUri(Uri previewAudioUri) { 1034 mValues.put(PreviewPrograms.COLUMN_PREVIEW_AUDIO_URI, 1035 previewAudioUri == null ? null : previewAudioUri.toString()); 1036 return (T) this; 1037 } 1038 } 1039} 1040