Download File
Download Project
Settings
Line Wrap
Themes
default
ambiance
bespin
dracula
eclipse
material
mbo
mdn-like
neat
solarized dark
ttcn
zenburn
Program.java
/* * Copyright 2015 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.media.tv.companionlibrary.model; import android.content.ContentValues; import android.database.Cursor; import android.media.tv.TvContentRating; import android.media.tv.TvContract; import android.os.Build; import android.support.annotation.NonNull; import android.text.TextUtils; import com.google.android.media.tv.companionlibrary.utils.CollectionUtils; import com.google.android.media.tv.companionlibrary.utils.TvContractUtils; import java.util.Arrays; import java.util.Objects; /** * A convenience class to create and insert program information into the database. */ public final class Program implements Comparable
{ /** * @hide */ public static final String[] PROJECTION = getProjection(); private static final long INVALID_LONG_VALUE = -1; private static final int INVALID_INT_VALUE = -1; private static final int IS_RECORDING_PROHIBITED = 1; private static final int IS_SEARCHABLE = 1; private long mId; private long mChannelId; private String mTitle; private String mEpisodeTitle; private String mSeasonNumber; private String mEpisodeNumber; private long mStartTimeUtcMillis; private long mEndTimeUtcMillis; private String mDescription; private String mLongDescription; private int mVideoWidth; private int mVideoHeight; private String mPosterArtUri; private String mThumbnailUri; private String[] mBroadcastGenres; private String[] mCanonicalGenres; private TvContentRating[] mContentRatings; private byte[] mInternalProviderData; private String mAudioLanguages; private int mRecordingProhibited; private int mSearchable; private String mSeasonTitle; private Program() { mChannelId = INVALID_LONG_VALUE; mId = INVALID_LONG_VALUE; mStartTimeUtcMillis = INVALID_LONG_VALUE; mEndTimeUtcMillis = INVALID_LONG_VALUE; mVideoWidth = INVALID_INT_VALUE; mVideoHeight = INVALID_INT_VALUE; mSearchable = IS_SEARCHABLE; } /** * @return The value of {@link TvContract.Programs#_ID} for the channel. */ public long getId() { return mId; } /** * @return The value of {@link TvContract.Programs#COLUMN_CHANNEL_ID} for the channel. */ public long getChannelId() { return mChannelId; } /** * @return The value of {@link TvContract.Programs#COLUMN_TITLE} for the channel. */ public String getTitle() { return mTitle; } /** * @return The value of {@link TvContract.Programs#COLUMN_EPISODE_TITLE} for the channel. */ public String getEpisodeTitle() { return mEpisodeTitle; } /** * @return The value of {@link TvContract.Programs#COLUMN_SEASON_DISPLAY_NUMBER} for the * channel. */ public String getSeasonNumber() { return mSeasonNumber; } /** * @return The value of {@link TvContract.Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the * channel. */ public String getEpisodeNumber() { return mEpisodeNumber; } /** * @return The value of {@link TvContract.Programs#COLUMN_START_TIME_UTC_MILLIS} for the * channel. */ public long getStartTimeUtcMillis() { return mStartTimeUtcMillis; } /** * @return The value of {@link TvContract.Programs#COLUMN_END_TIME_UTC_MILLIS} for the channel. */ public long getEndTimeUtcMillis() { return mEndTimeUtcMillis; } /** * @return The value of {@link TvContract.Programs#COLUMN_SHORT_DESCRIPTION} for the channel. */ public String getDescription() { return mDescription; } /** * @return The value of {@link TvContract.Programs#COLUMN_LONG_DESCRIPTION} for the channel. */ public String getLongDescription() { return mLongDescription; } /** * @return The value of {@link TvContract.Programs#COLUMN_VIDEO_WIDTH} for the channel. */ public int getVideoWidth() { return mVideoWidth; } /** * @return The value of {@link TvContract.Programs#COLUMN_VIDEO_HEIGHT} for the channel. */ public int getVideoHeight() { return mVideoHeight; } /** * @return The value of {@link TvContract.Programs#COLUMN_BROADCAST_GENRE} for the channel. */ public String[] getBroadcastGenres() { return mBroadcastGenres; } /** * @return The value of {@link TvContract.Programs#COLUMN_CANONICAL_GENRE} for the channel. */ public String[] getCanonicalGenres() { return mCanonicalGenres; } /** * @return The value of {@link TvContract.Programs#COLUMN_CONTENT_RATING} for the channel. */ public TvContentRating[] getContentRatings() { return mContentRatings; } /** * @return The value of {@link TvContract.Programs#COLUMN_POSTER_ART_URI} for the channel. */ public String getPosterArtUri() { return mPosterArtUri; } /** * @return The value of {@link TvContract.Programs#COLUMN_THUMBNAIL_URI} for the channel. */ public String getThumbnailUri() { return mThumbnailUri; } /** * @return The value of {@link TvContract.Channels#COLUMN_INTERNAL_PROVIDER_DATA} for the * channel. */ public byte[] getInternalProviderDataByteArray() { return mInternalProviderData; } /** * @return The value of {@link TvContract.Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the * channel. */ public InternalProviderData getInternalProviderData() { if (mInternalProviderData != null) { try { return new InternalProviderData(mInternalProviderData); } catch (InternalProviderData.ParseException e) { return null; } } return null; } /** * @return The value of {@link TvContract.Programs#COLUMN_AUDIO_LANGUAGE} for the channel. */ public String getAudioLanguages() { return mAudioLanguages; } /** * @return The value of {@link TvContract.Programs#COLUMN_RECORDING_PROHIBITED} for the * channel. */ public boolean isRecordingProhibited() { return mRecordingProhibited == IS_RECORDING_PROHIBITED; } /** * @return The value of {@link TvContract.Programs#COLUMN_RECORDING_PROHIBITED} for the * channel. */ public boolean isSearchable() { return mSearchable == IS_SEARCHABLE; } /** * @return The value of {@link TvContract.Programs#COLUMN_SEASON_TITLE} for the * channel. */ public String getSeasonTitle() { return mSeasonTitle; } @Override public int hashCode() { return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis, mTitle, mEpisodeTitle, mDescription, mLongDescription, mVideoWidth, mVideoHeight, mPosterArtUri, mThumbnailUri, Arrays.hashCode(mContentRatings), Arrays.hashCode(mCanonicalGenres), mSeasonNumber, mEpisodeNumber); } @Override public boolean equals(Object other) { if (!(other instanceof Program)) { return false; } Program program = (Program) other; return mChannelId == program.mChannelId && mStartTimeUtcMillis == program.mStartTimeUtcMillis && mEndTimeUtcMillis == program.mEndTimeUtcMillis && Objects.equals(mTitle, program.mTitle) && Objects.equals(mEpisodeTitle, program.mEpisodeTitle) && Objects.equals(mDescription, program.mDescription) && Objects.equals(mLongDescription, program.mLongDescription) && mVideoWidth == program.mVideoWidth && mVideoHeight == program.mVideoHeight && Objects.equals(mPosterArtUri, program.mPosterArtUri) && Objects.equals(mThumbnailUri, program.mThumbnailUri) && Arrays.equals(mInternalProviderData, program.mInternalProviderData) && Arrays.equals(mContentRatings, program.mContentRatings) && Arrays.equals(mCanonicalGenres, program.mCanonicalGenres) && Objects.equals(mSeasonNumber, program.mSeasonNumber) && Objects.equals(mEpisodeNumber, program.mEpisodeNumber); } /** * @param other The program you're comparing to. * @return The chronological order of the programs. */ @Override public int compareTo(@NonNull Program other) { return Long.compare(mStartTimeUtcMillis, other.mStartTimeUtcMillis); } @Override public String toString() { return "Program{" + "id=" + mId + ", channelId=" + mChannelId + ", title=" + mTitle + ", episodeTitle=" + mEpisodeTitle + ", seasonNumber=" + mSeasonNumber + ", episodeNumber=" + mEpisodeNumber + ", startTimeUtcSec=" + mStartTimeUtcMillis + ", endTimeUtcSec=" + mEndTimeUtcMillis + ", videoWidth=" + mVideoWidth + ", videoHeight=" + mVideoHeight + ", contentRatings=" + Arrays.toString(mContentRatings) + ", posterArtUri=" + mPosterArtUri + ", thumbnailUri=" + mThumbnailUri + ", contentRatings=" + Arrays.toString(mContentRatings) + ", genres=" + Arrays.toString(mCanonicalGenres) + "}"; } private void copyFrom(Program other) { if (this == other) { return; } mId = other.mId; mChannelId = other.mChannelId; mTitle = other.mTitle; mEpisodeTitle = other.mEpisodeTitle; mSeasonNumber = other.mSeasonNumber; mEpisodeNumber = other.mEpisodeNumber; mStartTimeUtcMillis = other.mStartTimeUtcMillis; mEndTimeUtcMillis = other.mEndTimeUtcMillis; mDescription = other.mDescription; mLongDescription = other.mLongDescription; mVideoWidth = other.mVideoWidth; mVideoHeight = other.mVideoHeight; mPosterArtUri = other.mPosterArtUri; mThumbnailUri = other.mThumbnailUri; mBroadcastGenres = other.mBroadcastGenres; mCanonicalGenres = other.mCanonicalGenres; mContentRatings = other.mContentRatings; mAudioLanguages = other.mAudioLanguages; mRecordingProhibited = other.mRecordingProhibited; mSearchable = other.mSearchable; mSeasonTitle = other.mSeasonTitle; mInternalProviderData = other.mInternalProviderData; } /** * @return The fields of the Program in the ContentValues format to be easily inserted into the * TV Input Framework database. * @hide */ public ContentValues toContentValues() { ContentValues values = new ContentValues(); if (mId != INVALID_LONG_VALUE) { values.put(TvContract.Programs._ID, mId); } if (mChannelId != INVALID_LONG_VALUE) { values.put(TvContract.Programs.COLUMN_CHANNEL_ID, mChannelId); } else { values.putNull(TvContract.Programs.COLUMN_CHANNEL_ID); } if (!TextUtils.isEmpty(mTitle)) { values.put(TvContract.Programs.COLUMN_TITLE, mTitle); } else { values.putNull(TvContract.Programs.COLUMN_TITLE); } if (!TextUtils.isEmpty(mEpisodeTitle)) { values.put(TvContract.Programs.COLUMN_EPISODE_TITLE, mEpisodeTitle); } else { values.putNull(TvContract.Programs.COLUMN_EPISODE_TITLE); } if (!TextUtils.isEmpty(mSeasonNumber) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER, mSeasonNumber); } else if (!TextUtils.isEmpty(mSeasonNumber) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_SEASON_NUMBER, Integer.parseInt(mSeasonNumber)); } else { values.putNull(TvContract.Programs.COLUMN_SEASON_NUMBER); } if (!TextUtils.isEmpty(mEpisodeNumber) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER, mEpisodeNumber); } else if (!TextUtils.isEmpty(mEpisodeNumber) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_EPISODE_NUMBER, Integer.parseInt(mEpisodeNumber)); } else { values.putNull(TvContract.Programs.COLUMN_EPISODE_NUMBER); } if (!TextUtils.isEmpty(mDescription)) { values.put(TvContract.Programs.COLUMN_SHORT_DESCRIPTION, mDescription); } else { values.putNull(TvContract.Programs.COLUMN_SHORT_DESCRIPTION); } if (!TextUtils.isEmpty(mDescription)) { values.put(TvContract.Programs.COLUMN_LONG_DESCRIPTION, mLongDescription); } else { values.putNull(TvContract.Programs.COLUMN_LONG_DESCRIPTION); } if (!TextUtils.isEmpty(mPosterArtUri)) { values.put(TvContract.Programs.COLUMN_POSTER_ART_URI, mPosterArtUri); } else { values.putNull(TvContract.Programs.COLUMN_POSTER_ART_URI); } if (!TextUtils.isEmpty(mThumbnailUri)) { values.put(TvContract.Programs.COLUMN_THUMBNAIL_URI, mThumbnailUri); } else { values.putNull(TvContract.Programs.COLUMN_THUMBNAIL_URI); } if (!TextUtils.isEmpty(mAudioLanguages)) { values.put(TvContract.Programs.COLUMN_AUDIO_LANGUAGE, mAudioLanguages); } else { values.putNull(TvContract.Programs.COLUMN_AUDIO_LANGUAGE); } if (mBroadcastGenres != null && mBroadcastGenres.length > 0) { values.put(TvContract.Programs.COLUMN_BROADCAST_GENRE, TvContract.Programs.Genres.encode(mBroadcastGenres)); } else { values.putNull(TvContract.Programs.COLUMN_BROADCAST_GENRE); } if (mCanonicalGenres != null && mCanonicalGenres.length > 0) { values.put(TvContract.Programs.COLUMN_CANONICAL_GENRE, TvContract.Programs.Genres.encode(mCanonicalGenres)); } else { values.putNull(TvContract.Programs.COLUMN_CANONICAL_GENRE); } if (mContentRatings != null && mContentRatings.length > 0) { values.put(TvContract.Programs.COLUMN_CONTENT_RATING, TvContractUtils.contentRatingsToString(mContentRatings)); } else { values.putNull(TvContract.Programs.COLUMN_CONTENT_RATING); } if (mStartTimeUtcMillis != INVALID_LONG_VALUE) { values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, mStartTimeUtcMillis); } else { values.putNull(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS); } if (mEndTimeUtcMillis != INVALID_LONG_VALUE) { values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, mEndTimeUtcMillis); } else { values.putNull(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS); } if (mVideoWidth != INVALID_INT_VALUE) { values.put(TvContract.Programs.COLUMN_VIDEO_WIDTH, mVideoWidth); } else { values.putNull(TvContract.Programs.COLUMN_VIDEO_WIDTH); } if (mVideoHeight != INVALID_INT_VALUE) { values.put(TvContract.Programs.COLUMN_VIDEO_HEIGHT, mVideoHeight); } else { values.putNull(TvContract.Programs.COLUMN_VIDEO_HEIGHT); } if (mInternalProviderData != null && mInternalProviderData.length > 0) { values.put(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA, mInternalProviderData); } else { values.putNull(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { values.put(TvContract.Programs.COLUMN_SEARCHABLE, mSearchable); } if (!TextUtils.isEmpty(mSeasonTitle) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_SEASON_TITLE, mSeasonTitle); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { values.putNull(TvContract.Programs.COLUMN_SEASON_TITLE); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { values.put(TvContract.Programs.COLUMN_RECORDING_PROHIBITED, mRecordingProhibited); } return values; } /** * Creates a Program object from a cursor including the fields defined in * {@link TvContract.Programs}. * * @param cursor A row from the TV Input Framework database. * @return A Program with the values taken from the cursor. * @hide */ public static Program fromCursor(Cursor cursor) { Builder builder = new Builder(); int index = 0; if (!cursor.isNull(index)) { builder.setId(cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setChannelId(cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setTitle(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setEpisodeTitle(cursor.getString(index)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (!cursor.isNull(++index)) { builder.setSeasonNumber(cursor.getString(index), INVALID_INT_VALUE); } } else { if (!cursor.isNull(++index)) { builder.setSeasonNumber(cursor.getInt(index)); } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (!cursor.isNull(++index)) { builder.setEpisodeNumber(cursor.getString(index), INVALID_INT_VALUE); } } else { if (!cursor.isNull(++index)) { builder.setEpisodeNumber(cursor.getInt(index)); } } if (!cursor.isNull(++index)) { builder.setDescription(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setLongDescription(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setPosterArtUri(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setThumbnailUri(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setAudioLanguages(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setBroadcastGenres(TvContract.Programs.Genres.decode(cursor.getString(index))); } if (!cursor.isNull(++index)) { builder.setCanonicalGenres(TvContract.Programs.Genres.decode(cursor.getString(index))); } if (!cursor.isNull(++index)) { builder.setContentRatings( TvContractUtils.stringToContentRatings(cursor.getString(index))); } if (!cursor.isNull(++index)) { builder.setStartTimeUtcMillis(cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setEndTimeUtcMillis(cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setVideoWidth((int) cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setVideoHeight((int) cursor.getLong(index)); } if (!cursor.isNull(++index)) { builder.setInternalProviderData(cursor.getBlob(index)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!cursor.isNull(++index)) { builder.setSearchable(cursor.getInt(index) == IS_SEARCHABLE); } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (!cursor.isNull(++index)) { builder.setSeasonTitle(cursor.getString(index)); } if (!cursor.isNull(++index)) { builder.setRecordingProhibited(cursor.getInt(index) == IS_RECORDING_PROHIBITED); } } return builder.build(); } private static String[] getProjection() { String[] baseColumns = new String[] { TvContract.Programs._ID, TvContract.Programs.COLUMN_CHANNEL_ID, TvContract.Programs.COLUMN_TITLE, TvContract.Programs.COLUMN_EPISODE_TITLE, (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ? TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER : TvContract.Programs.COLUMN_SEASON_NUMBER, (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ? TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER : TvContract.Programs.COLUMN_EPISODE_NUMBER, TvContract.Programs.COLUMN_SHORT_DESCRIPTION, TvContract.Programs.COLUMN_LONG_DESCRIPTION, TvContract.Programs.COLUMN_POSTER_ART_URI, TvContract.Programs.COLUMN_THUMBNAIL_URI, TvContract.Programs.COLUMN_AUDIO_LANGUAGE, TvContract.Programs.COLUMN_BROADCAST_GENRE, TvContract.Programs.COLUMN_CANONICAL_GENRE, TvContract.Programs.COLUMN_CONTENT_RATING, TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, TvContract.Programs.COLUMN_VIDEO_WIDTH, TvContract.Programs.COLUMN_VIDEO_HEIGHT, TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA }; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { String[] marshmallowColumns = new String[] { TvContract.Programs.COLUMN_SEARCHABLE }; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { String[] nougatColumns = new String[] { TvContract.Programs.COLUMN_SEASON_TITLE, TvContract.Programs.COLUMN_RECORDING_PROHIBITED }; return CollectionUtils.concatAll(baseColumns, marshmallowColumns, nougatColumns); } else { return CollectionUtils.concatAll(baseColumns, marshmallowColumns); } } return baseColumns; } /** * This Builder class simplifies the creation of a {@link Program} object. */ public static final class Builder { private final Program mProgram; /** * Creates a new Builder object. */ public Builder() { mProgram = new Program(); } /** * Creates a new Builder object with values copied from another Program. * @param other The Program you're copying from. */ public Builder(Program other) { mProgram = new Program(); mProgram.copyFrom(other); } /** * Creates a new Builder object with values from the Channel this program is playing on. * @param channel The Channel that contains this Program */ public Builder(Channel channel) { mProgram = new Program(); mProgram.mChannelId = channel.getId(); mProgram.mDescription = channel.getDescription(); mProgram.mInternalProviderData = channel.getInternalProviderDataByteArray(); mProgram.mThumbnailUri = channel.getChannelLogo(); mProgram.mTitle = channel.getDisplayName(); } /** * Sets a unique id for this program. * * @param programId The value of {@link TvContract.Programs#_ID} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ private Builder setId(long programId) { mProgram.mId = programId; return this; } /** * Sets the ID of the {@link Channel} that contains this program. * * @param channelId The value of {@link TvContract.Programs#COLUMN_CHANNEL_ID for the * program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setChannelId(long channelId) { mProgram.mChannelId = channelId; return this; } /** * Sets the title of this program. For a series, this is the series title. * * @param title The value of {@link TvContract.Programs#COLUMN_TITLE} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setTitle(String title) { mProgram.mTitle = title; return this; } /** * Sets the title of this particular episode for a series. * * @param episodeTitle The value of {@link TvContract.Programs#COLUMN_EPISODE_TITLE} for the * program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setEpisodeTitle(String episodeTitle) { mProgram.mEpisodeTitle = episodeTitle; return this; } /** * Sets the season number for this episode for a series. * * @param seasonNumber The value of {@link TvContract.Programs#COLUMN_SEASON_DISPLAY_NUMBER} * for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setSeasonNumber(int seasonNumber) { mProgram.mSeasonNumber = String.valueOf(seasonNumber); return this; } /** * Sets the season number for this episode for a series. * * @param seasonNumber The value of {@link TvContract.Programs#COLUMN_SEASON_NUMBER} for the * program. * @param numericalSeasonNumber An integer value for * {@link TvContract.Programs#COLUMN_SEASON_NUMBER} which will be used for API Level 23 and * below. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setSeasonNumber(String seasonNumber, int numericalSeasonNumber) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mProgram.mSeasonNumber = seasonNumber; } else { mProgram.mSeasonNumber = String.valueOf(numericalSeasonNumber); } return this; } /** * Sets the episode number in a season for this episode for a series. * * @param episodeNumber The value of * {@link TvContract.Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setEpisodeNumber(int episodeNumber) { mProgram.mEpisodeNumber = String.valueOf(episodeNumber); return this; } /** * Sets the episode number in a season for this episode for a series. * * @param episodeNumber The value of * {@link TvContract.Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program. * @param numericalEpisodeNumber An integer value for * {@link TvContract.Programs#COLUMN_SEASON_NUMBER} which will be used for API Level 23 and * below. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setEpisodeNumber(String episodeNumber, int numericalEpisodeNumber) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mProgram.mEpisodeNumber = episodeNumber; } else { mProgram.mEpisodeNumber = String.valueOf(numericalEpisodeNumber); } return this; } /** * Sets the time when the program is going to begin in milliseconds since the epoch. * * @param startTimeUtcMillis The value of * {@link TvContract.Programs#COLUMN_START_TIME_UTC_MILLIS} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setStartTimeUtcMillis(long startTimeUtcMillis) { mProgram.mStartTimeUtcMillis = startTimeUtcMillis; return this; } /** * Sets the time when this program is going to end in milliseconds since the epoch. * * @param endTimeUtcMillis The value of * {@link TvContract.Programs#COLUMN_END_TIME_UTC_MILLIS} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setEndTimeUtcMillis(long endTimeUtcMillis) { mProgram.mEndTimeUtcMillis = endTimeUtcMillis; return this; } /** * Sets a brief description of the program. For a series, this would be a brief description * of the episode. * * @param description The value of {@link TvContract.Programs#COLUMN_SHORT_DESCRIPTION} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setDescription(String description) { mProgram.mDescription = description; return this; } /** * Sets a longer description of a program if one exists. * * @param longDescription The value of {@link TvContract.Programs#COLUMN_LONG_DESCRIPTION} * for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setLongDescription(String longDescription) { mProgram.mLongDescription = longDescription; return this; } /** * Sets the video width of the program. * * @param width The value of {@link TvContract.Programs#COLUMN_VIDEO_WIDTH} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setVideoWidth(int width) { mProgram.mVideoWidth = width; return this; } /** * Sets the video height of the program. * * @param height The value of {@link TvContract.Programs#COLUMN_VIDEO_HEIGHT} for the * program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setVideoHeight(int height) { mProgram.mVideoHeight = height; return this; } /** * Sets the content ratings for this program. * * @param contentRatings An array of {@link TvContentRating} that apply to this program * which will be flattened to a String to store in a database. * @return This Builder object to allow for chaining of calls to builder methods. * @see TvContract.Programs#COLUMN_CONTENT_RATING */ public Builder setContentRatings(TvContentRating[] contentRatings) { mProgram.mContentRatings = contentRatings; return this; } /** * Sets the large poster art of the program. * * @param posterArtUri The value of {@link TvContract.Programs#COLUMN_POSTER_ART_URI} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setPosterArtUri(String posterArtUri) { mProgram.mPosterArtUri = posterArtUri; return this; } /** * Sets a small thumbnail of the program. * * @param thumbnailUri The value of {@link TvContract.Programs#COLUMN_THUMBNAIL_URI} for the * program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setThumbnailUri(String thumbnailUri) { mProgram.mThumbnailUri = thumbnailUri; return this; } /** * Sets the broadcast-specified genres of the program. * * @param genres Array of genres that apply to the program based on the broadcast standard * which will be flattened to a String to store in a database. * @return This Builder object to allow for chaining of calls to builder methods. * @see TvContract.Programs#COLUMN_BROADCAST_GENRE */ public Builder setBroadcastGenres(String[] genres) { mProgram.mBroadcastGenres = genres; return this; } /** * Sets the genres of the program. * * @param genres An array of {@link TvContract.Programs.Genres} that apply to the program * which will be flattened to a String to store in a database. * @return This Builder object to allow for chaining of calls to builder methods. * @see TvContract.Programs#COLUMN_CANONICAL_GENRE */ public Builder setCanonicalGenres(String[] genres) { mProgram.mCanonicalGenres = genres; return this; } /** * Sets the internal provider data for the program as raw bytes. * * @param data The value of {@link TvContract.Programs#COLUMN_INTERNAL_PROVIDER_DATA} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setInternalProviderData(byte[] data) { mProgram.mInternalProviderData = data; return this; } /** * Sets the internal provider data for the program. * * @param internalProviderData The value of * {@link TvContract.Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setInternalProviderData(InternalProviderData internalProviderData) { if (internalProviderData != null) { mProgram.mInternalProviderData = internalProviderData.toString().getBytes(); } return this; } /** * Sets the available audio languages for this program as a comma-separated String. * * @param audioLanguages The value of {@link TvContract.Programs#COLUMN_AUDIO_LANGUAGE} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setAudioLanguages(String audioLanguages) { mProgram.mAudioLanguages = audioLanguages; return this; } /** * Sets whether this program cannot be recorded. * * @param prohibited The value of {@link TvContract.Programs#COLUMN_RECORDING_PROHIBITED} * for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setRecordingProhibited(boolean prohibited) { mProgram.mRecordingProhibited = prohibited ? IS_RECORDING_PROHIBITED : 0; return this; } /** * Sets whether this channel can be searched for in other applications. * * @param searchable The value of {@link TvContract.Programs#COLUMN_SEARCHABLE} * for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setSearchable(boolean searchable) { mProgram.mSearchable = searchable ? IS_SEARCHABLE : 0; return this; } /** * Sets a custom name for the season, if applicable. * * @param seasonTitle The value of {@link TvContract.Programs#COLUMN_SEASON_TITLE} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setSeasonTitle(String seasonTitle) { mProgram.mSeasonTitle = seasonTitle; return this; } /** * @return A new Program with values supplied by the Builder. */ public Program build() { Program program = new Program(); program.copyFrom(mProgram); if(mProgram.getStartTimeUtcMillis() >= mProgram.getEndTimeUtcMillis()) { throw new IllegalArgumentException("This program must have defined start and end " + "times"); } return program; } } }