13f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho/*
2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project
33f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho *
43f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * Licensed under the Apache License, Version 2.0 (the "License");
53f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * you may not use this file except in compliance with the License.
63f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * You may obtain a copy of the License at
73f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho *
83f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho *      http://www.apache.org/licenses/LICENSE-2.0
93f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho *
103f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * Unless required by applicable law or agreed to in writing, software
113f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * distributed under the License is distributed on an "AS IS" BASIS,
123f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * See the License for the specific language governing permissions and
143f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * limitations under the License.
153f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho */
163f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
17d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leepackage com.android.tv.data;
183f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.annotation.SuppressLint;
206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.content.ContentValues;
21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Context;
22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.database.Cursor;
232be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Limimport android.media.tv.TvContentRating;
249035590d94d136a020e499ce720b9d2cf1f6f45cJae Seoimport android.media.tv.TvContract;
256ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.media.tv.TvContract.Programs;
266ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.os.Build;
2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.Parcel;
2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.Parcelable;
29816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.support.annotation.NonNull;
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.Nullable;
31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.support.annotation.UiThread;
3265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.VisibleForTesting;
33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.TextUtils;
34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.util.Log;
35816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
36ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.BuildConfig;
372e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport com.android.tv.common.CollectionUtils;
38ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.TvContentRatingCache;
39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.ImageLoader;
40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.Utils;
41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.io.Serializable;
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.ArrayList;
44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.Arrays;
4565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.List;
46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.Objects;
473f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
483f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho/**
493f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho * A convenience class to create and insert program information entries into the database.
503f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho */
5165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopublic final class Program extends BaseProgram implements Comparable<Program>, Parcelable {
52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final boolean DEBUG = false;
53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final boolean DEBUG_DUMP_DESCRIPTION = false;
54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String TAG = "Program";
55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
562e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static final String[] PROJECTION_BASE = {
572e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            // Columns must match what is read in Program.fromCursor()
582e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs._ID,
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_PACKAGE_NAME,
602e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_CHANNEL_ID,
612e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_TITLE,
622e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_EPISODE_TITLE,
632e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_SHORT_DESCRIPTION,
6465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_LONG_DESCRIPTION,
652e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_POSTER_ART_URI,
662e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_THUMBNAIL_URI,
672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_CANONICAL_GENRE,
682e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_CONTENT_RATING,
692e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
702e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS,
712e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_VIDEO_WIDTH,
7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_VIDEO_HEIGHT,
7365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA
74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
758f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo
762e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    // Columns which is deprecated in NYC
7765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @SuppressWarnings("deprecation")
782e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static final String[] PROJECTION_DEPRECATED_IN_NYC = {
792e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_SEASON_NUMBER,
802e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_EPISODE_NUMBER
812e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    };
822e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
832e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static final String[] PROJECTION_ADDED_IN_NYC = {
842e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER,
852e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            TvContract.Programs.COLUMN_SEASON_TITLE,
8665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
8765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            TvContract.Programs.COLUMN_RECORDING_PROHIBITED
881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    };
891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
902e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public static final String[] PROJECTION = createProjection();
912e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
922e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static String[] createProjection() {
936ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return CollectionUtils.concatAll(
946ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                PROJECTION_BASE,
956ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
966ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                        ? PROJECTION_ADDED_IN_NYC
976ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                        : PROJECTION_DEPRECATED_IN_NYC);
982e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    }
992e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
1001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    /**
10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns the column index for {@code column}, -1 if the column doesn't exist.
10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static int getColumnIndex(String column) {
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        for (int i = 0; i < PROJECTION.length; ++i) {
10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            if (PROJECTION[i].equals(column)) {
10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                return i;
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
10865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
10965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return -1;
11065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
11165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
11265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
11307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko     * Creates {@code Program} object from cursor.
11407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko     *
11507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko     * <p>The query that created the cursor MUST use {@link #PROJECTION}.
11607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko     */
11707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko    public static Program fromCursor(Cursor cursor) {
11807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        // Columns read must match the order of match {@link #PROJECTION}
11907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        Builder builder = new Builder();
12007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        int index = 0;
1212e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        builder.setId(cursor.getLong(index++));
12265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        String packageName = cursor.getString(index++);
12365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        builder.setPackageName(packageName);
12407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setChannelId(cursor.getLong(index++));
12507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setTitle(cursor.getString(index++));
12607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setEpisodeTitle(cursor.getString(index++));
12707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setDescription(cursor.getString(index++));
12865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        builder.setLongDescription(cursor.getString(index++));
12907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setPosterArtUri(cursor.getString(index++));
13007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setThumbnailUri(cursor.getString(index++));
13107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setCanonicalGenres(cursor.getString(index++));
1322e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        builder.setContentRatings(
1332e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                TvContentRatingCache.getInstance().getRatings(cursor.getString(index++)));
13407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setStartTimeUtcMillis(cursor.getLong(index++));
13507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setEndTimeUtcMillis(cursor.getLong(index++));
13607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setVideoWidth((int) cursor.getLong(index++));
13707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        builder.setVideoHeight((int) cursor.getLong(index++));
13865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (Utils.isInBundledPackageSet(packageName)) {
13965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            InternalDataUtils.deserializeInternalProviderData(cursor.getBlob(index), builder);
14065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
14165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        index++;
1426ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
1432e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            builder.setSeasonNumber(cursor.getString(index++));
1442e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            builder.setSeasonTitle(cursor.getString(index++));
1452e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            builder.setEpisodeNumber(cursor.getString(index++));
14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            builder.setRecordingProhibited(cursor.getInt(index++) == 1);
1472e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        } else {
1482e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            builder.setSeasonNumber(cursor.getString(index++));
1492e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            builder.setEpisodeNumber(cursor.getString(index++));
1502e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
15107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        return builder.build();
15207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko    }
15307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko
15465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static Program fromParcel(Parcel in) {
15565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        Program program = new Program();
15665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mId = in.readLong();
15765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mPackageName = in.readString();
15865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mChannelId = in.readLong();
15965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mTitle = in.readString();
16065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mSeriesId = in.readString();
16165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mEpisodeTitle = in.readString();
16265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mSeasonNumber = in.readString();
16365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mSeasonTitle = in.readString();
16465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mEpisodeNumber = in.readString();
16565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mStartTimeUtcMillis = in.readLong();
16665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mEndTimeUtcMillis = in.readLong();
16765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mDescription = in.readString();
16865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mLongDescription = in.readString();
16965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mVideoWidth = in.readInt();
17065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mVideoHeight = in.readInt();
17165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mCriticScores = in.readArrayList(Thread.currentThread().getContextClassLoader());
17265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mPosterArtUri = in.readString();
17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mThumbnailUri = in.readString();
17465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mCanonicalGenreIds = in.createIntArray();
17565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        int length = in.readInt();
17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (length > 0) {
17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            program.mContentRatings = new TvContentRating[length];
17865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            for (int i = 0; i < length; ++i) {
17965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                program.mContentRatings[i] = TvContentRating.unflattenFromString(in.readString());
18065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
18165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
18265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        program.mRecordingProhibited = in.readByte() != (byte) 0;
18365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return program;
18465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
18565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
18665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static final Parcelable.Creator<Program> CREATOR = new Parcelable.Creator<Program>() {
18765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @Override
18865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Program createFromParcel(Parcel in) {
18965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko          return Program.fromParcel(in);
19065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
19165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
19265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @Override
19365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Program[] newArray(int size) {
19465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko          return new Program[size];
19565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    };
19765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
1982e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private long mId;
19965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private String mPackageName;
2003f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private long mChannelId;
2013f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private String mTitle;
20265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private String mSeriesId;
203816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private String mEpisodeTitle;
2042e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private String mSeasonNumber;
2052e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private String mSeasonTitle;
2062e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private String mEpisodeNumber;
2073f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private long mStartTimeUtcMillis;
2083f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private long mEndTimeUtcMillis;
2093f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private String mDescription;
21065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private String mLongDescription;
211816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private int mVideoWidth;
212816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private int mVideoHeight;
21365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private List<CriticScore> mCriticScores;
214e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    private String mPosterArtUri;
215e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    private String mThumbnailUri;
216816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private int[] mCanonicalGenreIds;
2172be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim    private TvContentRating[] mContentRatings;
21865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private boolean mRecordingProhibited;
2193f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
2203f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    private Program() {
2213f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        // Do nothing.
2223f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2233f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
2242e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public long getId() {
2252e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        return mId;
2262e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    }
2272e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
22865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
22965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns the package name of this program.
23065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
23165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public String getPackageName() {
23265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mPackageName;
23365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
23465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
2353f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public long getChannelId() {
2363f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        return mChannelId;
2373f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2383f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
239816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
240816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Returns {@code true} if this program is valid or {@code false} otherwise.
241816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
24265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
243816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public boolean isValid() {
244816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mChannelId >= 0;
245816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
246816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
247816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
248816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Returns {@code true} if the program is valid and {@code false} otherwise.
249816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
250816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public static boolean isValid(Program program) {
251816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return program != null && program.isValid();
2523f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2533f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
25465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
2553f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public String getTitle() {
2563f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        return mTitle;
2573f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2583f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
25965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
26065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns the series ID.
26165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
262d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @Override
26365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public String getSeriesId() {
26465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mSeriesId;
26565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
26665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
26765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
26865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns the episode title.
26965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
27065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
2716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public String getEpisodeTitle() {
272816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mEpisodeTitle;
2733f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2743f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
27565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
2762e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public String getSeasonNumber() {
2772e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        return mSeasonNumber;
2782e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    }
2792e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
2812e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public String getEpisodeNumber() {
2822e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        return mEpisodeNumber;
2832e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    }
2842e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
28565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public long getStartTimeUtcMillis() {
287816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mStartTimeUtcMillis;
2883f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2893f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
29065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
2913f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public long getEndTimeUtcMillis() {
2923f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        return mEndTimeUtcMillis;
2933f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
2943f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
295816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
296816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Returns the program duration.
297816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
299816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public long getDurationMillis() {
300816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mEndTimeUtcMillis - mStartTimeUtcMillis;
3013f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
3023f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
30365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
3043f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public String getDescription() {
3053f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        return mDescription;
3063f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
3073f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
30865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
30965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public String getLongDescription() {
31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mLongDescription;
31165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
31265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
313816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public int getVideoWidth() {
314816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mVideoWidth;
3153f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
3163f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
317816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public int getVideoHeight() {
318816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mVideoHeight;
3198f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo    }
3208f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo
32165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
32265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns the list of Critic Scores for this program
32365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
32465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Nullable
32565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public List<CriticScore> getCriticScores() {
32665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mCriticScores;
32765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
32865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
3296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @Nullable
3306ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @Override
3312be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim    public TvContentRating[] getContentRatings() {
3322be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim        return mContentRatings;
3332be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim    }
3342be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim
33565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
336e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    public String getPosterArtUri() {
337e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        return mPosterArtUri;
338e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    }
339e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok
34065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
341e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    public String getThumbnailUri() {
342e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        return mThumbnailUri;
343e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    }
344e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok
345816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
34665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns {@code true} if the recording of this program is prohibited.
34765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
34865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public boolean isRecordingProhibited() {
34965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mRecordingProhibited;
35065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
35165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
35265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
353816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Returns array of canonical genres for this program.
354816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * This is expected to be called rarely.
355816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
35665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Nullable
357816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public String[] getCanonicalGenres() {
358816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mCanonicalGenreIds == null) {
359816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return null;
360816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
361816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        String[] genres = new String[mCanonicalGenreIds.length];
362816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (int i = 0; i < mCanonicalGenreIds.length; i++) {
363816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            genres[i] = GenreItems.getCanonicalGenre(mCanonicalGenreIds[i]);
364816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
365816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return genres;
366816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
367816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
368816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
36965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns array of canonical genre ID's for this program.
37065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
371d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @Override
37265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public int[] getCanonicalGenreIds() {
37365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mCanonicalGenreIds;
37465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
37565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
37665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
377816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Returns if this program has the genre.
378816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
379816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public boolean hasGenre(int genreId) {
380816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (genreId == GenreItems.ID_ALL_CHANNELS) {
381816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return true;
382816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
383816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mCanonicalGenreIds != null) {
384816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (int id : mCanonicalGenreIds) {
385816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (id == genreId) {
386816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return true;
387816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
388816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
389816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
390816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return false;
391e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok    }
392e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok
393816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
394816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public int hashCode() {
39565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        // Hash with all the properties because program ID can be invalid for the dummy programs.
396816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis,
39765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mTitle, mSeriesId, mEpisodeTitle, mDescription, mLongDescription, mVideoWidth,
39865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mVideoHeight, mPosterArtUri, mThumbnailUri, Arrays.hashCode(mContentRatings),
39965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                Arrays.hashCode(mCanonicalGenreIds), mSeasonNumber, mSeasonTitle, mEpisodeNumber,
40065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mRecordingProhibited);
401816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
402816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
403816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
404816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public boolean equals(Object other) {
405816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (!(other instanceof Program)) {
406816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return false;
407816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
40865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        // Compare all the properties because program ID can be invalid for the dummy programs.
409816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Program program = (Program) other;
41065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return Objects.equals(mPackageName, program.mPackageName)
41165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && mChannelId == program.mChannelId
412816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && mStartTimeUtcMillis == program.mStartTimeUtcMillis
413816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && mEndTimeUtcMillis == program.mEndTimeUtcMillis
414816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Objects.equals(mTitle, program.mTitle)
41565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && Objects.equals(mSeriesId, program.mSeriesId)
416816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Objects.equals(mEpisodeTitle, program.mEpisodeTitle)
417816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Objects.equals(mDescription, program.mDescription)
41865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && Objects.equals(mLongDescription, program.mLongDescription)
419816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && mVideoWidth == program.mVideoWidth
420816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && mVideoHeight == program.mVideoHeight
421816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Objects.equals(mPosterArtUri, program.mPosterArtUri)
422816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Objects.equals(mThumbnailUri, program.mThumbnailUri)
423816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Arrays.equals(mContentRatings, program.mContentRatings)
424816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && Arrays.equals(mCanonicalGenreIds, program.mCanonicalGenreIds)
4252e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                && Objects.equals(mSeasonNumber, program.mSeasonNumber)
4262e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                && Objects.equals(mSeasonTitle, program.mSeasonTitle)
42765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && Objects.equals(mEpisodeNumber, program.mEpisodeNumber)
42865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && mRecordingProhibited == program.mRecordingProhibited;
429816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
430816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
431816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
432816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public int compareTo(@NonNull Program other) {
433816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return Long.compare(mStartTimeUtcMillis, other.mStartTimeUtcMillis);
4343f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
4353f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
4363f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    @Override
4373f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public String toString() {
438816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        StringBuilder builder = new StringBuilder();
43965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        builder.append("Program[").append(mId)
44065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .append("]{channelId=").append(mChannelId)
44165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .append(", packageName=").append(mPackageName)
4423f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho                .append(", title=").append(mTitle)
44365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .append(", seriesId=").append(mSeriesId)
444816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", episodeTitle=").append(mEpisodeTitle)
445816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", seasonNumber=").append(mSeasonNumber)
4462e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                .append(", seasonTitle=").append(mSeasonTitle)
447816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", episodeNumber=").append(mEpisodeNumber)
448816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", startTimeUtcSec=").append(Utils.toTimeString(mStartTimeUtcMillis))
449816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", endTimeUtcSec=").append(Utils.toTimeString(mEndTimeUtcMillis))
450816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", videoWidth=").append(mVideoWidth)
451816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                .append(", videoHeight=").append(mVideoHeight)
452ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                .append(", contentRatings=")
453ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                .append(TvContentRatingCache.contentRatingsToString(mContentRatings))
454e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok                .append(", posterArtUri=").append(mPosterArtUri)
455e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok                .append(", thumbnailUri=").append(mThumbnailUri)
45665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .append(", canonicalGenres=").append(Arrays.toString(mCanonicalGenreIds))
45765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .append(", recordingProhibited=").append(mRecordingProhibited);
458816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (DEBUG_DUMP_DESCRIPTION) {
45965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            builder.append(", description=").append(mDescription)
46065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .append(", longDescription=").append(mLongDescription);
461816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
462816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return builder.append("}").toString();
4633f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
4643f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
4656ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    /**
4666ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     * Translates a {@link Program} to {@link ContentValues} that are ready to be written into
4676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     * Database.
4686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     */
4696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @SuppressLint("InlinedApi")
4706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @SuppressWarnings("deprecation")
4716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public static ContentValues toContentValues(Program program) {
4726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        ContentValues values = new ContentValues();
4736ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        values.put(TvContract.Programs.COLUMN_CHANNEL_ID, program.getChannelId());
4746ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_TITLE, program.getTitle());
4756ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_EPISODE_TITLE, program.getEpisodeTitle());
4766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
4776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER,
4786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    program.getSeasonNumber());
4796ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
4806ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    program.getEpisodeNumber());
4816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else {
4826ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_SEASON_NUMBER, program.getSeasonNumber());
4836ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_EPISODE_NUMBER, program.getEpisodeNumber());
4846ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
4856ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_SHORT_DESCRIPTION, program.getDescription());
4866ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_LONG_DESCRIPTION, program.getLongDescription());
4876ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_POSTER_ART_URI, program.getPosterArtUri());
4886ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_THUMBNAIL_URI, program.getThumbnailUri());
4896ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        String[] canonicalGenres = program.getCanonicalGenres();
4906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (canonicalGenres != null && canonicalGenres.length > 0) {
4916ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE,
4926ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    TvContract.Programs.Genres.encode(canonicalGenres));
4936ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else {
4946ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE, "");
4956ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
4966ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, Programs.COLUMN_CONTENT_RATING,
4976ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                TvContentRatingCache.contentRatingsToString(program.getContentRatings()));
4986ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
4996ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                program.getStartTimeUtcMillis());
5006ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, program.getEndTimeUtcMillis());
5016ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        putValue(values, TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA,
5026ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                InternalDataUtils.serializeInternalProviderData(program));
5036ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return values;
5046ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
5056ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
5066ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static void putValue(ContentValues contentValues, String key, String value) {
5076ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (TextUtils.isEmpty(value)) {
5086ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            contentValues.putNull(key);
5096ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else {
5106ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            contentValues.put(key, value);
5116ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
5126ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
5136ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
5146ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static void putValue(ContentValues contentValues, String key, byte[] value) {
5156ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (value == null || value.length == 0) {
5166ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            contentValues.putNull(key);
5176ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else {
5186ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            contentValues.put(key, value);
5196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
5206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
5216ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
5223f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public void copyFrom(Program other) {
5233f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        if (this == other) {
5243f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return;
5253f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
5263f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
5272e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mId = other.mId;
52865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mPackageName = other.mPackageName;
5293f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        mChannelId = other.mChannelId;
5303f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        mTitle = other.mTitle;
53165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mSeriesId = other.mSeriesId;
532816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mEpisodeTitle = other.mEpisodeTitle;
533816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mSeasonNumber = other.mSeasonNumber;
5342e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        mSeasonTitle = other.mSeasonTitle;
535816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mEpisodeNumber = other.mEpisodeNumber;
5363f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        mStartTimeUtcMillis = other.mStartTimeUtcMillis;
5373f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        mEndTimeUtcMillis = other.mEndTimeUtcMillis;
5383f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        mDescription = other.mDescription;
53965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mLongDescription = other.mLongDescription;
540816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mVideoWidth = other.mVideoWidth;
541816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mVideoHeight = other.mVideoHeight;
54265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mCriticScores = other.mCriticScores;
543e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        mPosterArtUri = other.mPosterArtUri;
544e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        mThumbnailUri = other.mThumbnailUri;
545816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mCanonicalGenreIds = other.mCanonicalGenreIds;
546816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentRatings = other.mContentRatings;
54765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mRecordingProhibited = other.mRecordingProhibited;
54865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
54965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
55065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
55165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * A Builder for the Program class
55265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
5533f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    public static final class Builder {
5543f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        private final Program mProgram;
5553f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
55665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
55765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Creates a Builder for this Program class
55865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
5593f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder() {
5603f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram = new Program();
5613f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            // Fill initial data.
56265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mPackageName = null;
5633f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mChannelId = Channel.INVALID_ID;
5642e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mTitle = null;
5652e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mSeasonNumber = null;
5662e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mSeasonTitle = null;
5672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mEpisodeNumber = null;
5683f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mStartTimeUtcMillis = -1;
5693f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mEndTimeUtcMillis = -1;
5702e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mDescription = null;
57165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mLongDescription = null;
57265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mRecordingProhibited = false;
57365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mCriticScores = null;
5743f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
5753f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
57665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
57765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Creates a builder for this Program class
57865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * by setting default values equivalent to another Program
57965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param other the program to be copied
58065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
58165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @VisibleForTesting
5823f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder(Program other) {
5833f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram = new Program();
5843f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.copyFrom(other);
5853f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
5863f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
58765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
58865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the ID of this program
58965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param id the ID
59065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
59165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
5922e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        public Builder setId(long id) {
5932e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mId = id;
5942e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            return this;
5952e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
5962e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
59765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
59865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the package name for this program
59965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param packageName the package name
60065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
60165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
60265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder setPackageName(String packageName){
60365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mPackageName = packageName;
60465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
60565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
60665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
60765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
60865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the channel ID for this program
60965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param channelId the channel ID
61065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
61165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6123f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder setChannelId(long channelId) {
6133f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mChannelId = channelId;
6143f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
6153f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
6163f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
61765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
61865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the program title
61965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param title the title
62065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
62165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6223f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder setTitle(String title) {
6233f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mTitle = title;
6243f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
6253f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
6263f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
62765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
62865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the series ID.
62965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param seriesId the series ID
63065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
63165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
63265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder setSeriesId(String seriesId) {
63365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mSeriesId = seriesId;
63465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
63565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
63665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
63765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
63865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the episode title if this is a series program
63965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param episodeTitle the episode title
64065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
64165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
642816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public Builder setEpisodeTitle(String episodeTitle) {
643816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgram.mEpisodeTitle = episodeTitle;
644816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return this;
645816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
646816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
64765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
64865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the season number if this is a series program
64965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param seasonNumber the season number
65065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
65165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6522e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        public Builder setSeasonNumber(String seasonNumber) {
653816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgram.mSeasonNumber = seasonNumber;
654816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return this;
655816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
656816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
65765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
65865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
65965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the season title if this is a series program
66065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param seasonTitle the season title
66165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
66265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6632e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        public Builder setSeasonTitle(String seasonTitle) {
6642e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            mProgram.mSeasonTitle = seasonTitle;
6652e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            return this;
6662e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
6672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
66865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
66965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the episode number if this is a series program
67065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param episodeNumber the episode number
67165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
67265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6732e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        public Builder setEpisodeNumber(String episodeNumber) {
674816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgram.mEpisodeNumber = episodeNumber;
675816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return this;
676816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
677816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
67865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
67965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the start time of this program
68065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param startTimeUtcMillis the start time in UTC milliseconds
68165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
68265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6833f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
6843f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mStartTimeUtcMillis = startTimeUtcMillis;
6853f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
6863f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
6873f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
68865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
68965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the end time of this program
69065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param endTimeUtcMillis the end time in UTC milliseconds
69165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
69265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
6933f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
6943f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mEndTimeUtcMillis = endTimeUtcMillis;
6953f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
6963f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
6973f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
69865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
69965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets a description
70065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param description the description
70165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
70265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
7033f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Builder setDescription(String description) {
7043f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            mProgram.mDescription = description;
7053f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
7063f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
7073f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
70865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
70965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets a long description
71065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param longDescription the long description
71165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
71265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
71365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder setLongDescription(String longDescription) {
71465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mLongDescription = longDescription;
71565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
71665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
71765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
71865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
71965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Defines the video width of this program
72065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param width
72165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
72265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
723816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public Builder setVideoWidth(int width) {
724816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgram.mVideoWidth = width;
7253f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho            return this;
7263f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
7273f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho
72865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
72965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Defines the video height of this program
73065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param height
73165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
73265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
733816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public Builder setVideoHeight(int height) {
734816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgram.mVideoHeight = height;
7358f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo            return this;
7368f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo        }
7378f1ff2894363afbb6909a3a1edc1f3cbe8657c11Jae Seo
73865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
73965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the content ratings for this program
74065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param contentRatings the content ratings
74165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
74265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
7432be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim        public Builder setContentRatings(TvContentRating[] contentRatings) {
7442be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim            mProgram.mContentRatings = contentRatings;
7452be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim            return this;
7462be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim        }
7472be00440937254386dae3a1c0c02a7ac76ad92caSungsoo Lim
74865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
74965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the poster art URI
75065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param posterArtUri the poster art URI
75165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
75265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
753e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        public Builder setPosterArtUri(String posterArtUri) {
754e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok            mProgram.mPosterArtUri = posterArtUri;
755e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok            return this;
756e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        }
757e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok
75865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
75965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the thumbnail URI
76065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param thumbnailUri the thumbnail URI
76165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
76265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
763e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        public Builder setThumbnailUri(String thumbnailUri) {
764e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok            mProgram.mThumbnailUri = thumbnailUri;
765e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok            return this;
766e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok        }
767e29e3903054c63ba7e3a3be15f4e166dc6b822baJaekyun Seok
76865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
76965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the canonical genres by id
77065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param genres the genres
77165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
77265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
773816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public Builder setCanonicalGenres(String genres) {
77465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mCanonicalGenreIds = Utils.getCanonicalGenreIds(genres);
77565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
77665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
77765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
77865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
77965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the recording prohibited flag
78065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param recordingProhibited recording prohibited flag
78165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
78265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
78365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder setRecordingProhibited(boolean recordingProhibited) {
78465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mRecordingProhibited = recordingProhibited;
78565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
78665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
78765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
78865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
78965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Adds a critic score
79065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param criticScore the critic score
79165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this object
79265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
79365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder addCriticScore(CriticScore criticScore) {
79465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            if (criticScore.score != null) {
79565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if (mProgram.mCriticScores == null) {
79665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    mProgram.mCriticScores = new ArrayList<>();
797816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
79865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mProgram.mCriticScores.add(criticScore);
799816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
800816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return this;
801816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
802816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
80365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
80465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Sets the critic scores
80565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param criticScores the critic scores
80665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return a reference to this objects
80765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
80865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public Builder setCriticScores(List<CriticScore> criticScores) {
80965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgram.mCriticScores = criticScores;
81065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return this;
81165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
81265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
81365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
81465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Returns a reference to the Program object being constructed
81565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @return the Program object constructed
81665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
8173f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        public Program build() {
81865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            // Generate the series ID for the episodic program of other TV input.
8196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (TextUtils.isEmpty(mProgram.mTitle)) {
8206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                // If title is null, series cannot be generated for this program.
8216ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                setSeriesId(null);
8226ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            } else if (TextUtils.isEmpty(mProgram.mSeriesId)
82365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    && !TextUtils.isEmpty(mProgram.mEpisodeNumber)) {
8246ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                // If series ID is not set, generate it for the episodic program of other TV input.
82565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                setSeriesId(BaseProgram.generateSeriesId(mProgram.mPackageName, mProgram.mTitle));
82665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
827816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            Program program = new Program();
828816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            program.copyFrom(mProgram);
829816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return program;
830816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
831816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
832816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
833816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
834816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Prefetches the program poster art.<p>
835816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
836816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight) {
837816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mPosterArtUri == null) {
838816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return;
839816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
840816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        ImageLoader.prefetchBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight);
841816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
842816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
843816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
8446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     * Loads the program poster art and returns it via {@code callback}.
845816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * <p>
846816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Note that it may directly call {@code callback} if the program poster art already is loaded.
8476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     *
8486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     * @return {@code true} if the load is complete and the callback is executed.
849816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
850816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @UiThread
8516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public boolean loadPosterArt(Context context, int posterArtWidth, int posterArtHeight,
852ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            ImageLoader.ImageLoaderCallback callback) {
853816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mPosterArtUri == null) {
8546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return false;
8553f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho        }
8566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return ImageLoader.loadBitmap(
8576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
858ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    }
859ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
860ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    public static boolean isDuplicate(Program p1, Program p2) {
861ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        if (p1 == null || p2 == null) {
862ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            return false;
863ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        }
864ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        boolean isDuplicate = p1.getChannelId() == p2.getChannelId()
865ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
866ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
8672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        if (DEBUG && BuildConfig.ENG && isDuplicate) {
868ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            Log.w(TAG, "Duplicate programs detected! - \"" + p1.getTitle() + "\" and \""
869ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    + p2.getTitle() + "\"");
870ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        }
871ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        return isDuplicate;
8723f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho    }
87365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
87465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
87565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public int describeContents() {
87665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return 0;
87765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
87865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
87965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
88065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public void writeToParcel(Parcel out, int paramInt) {
88165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeLong(mId);
88265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mPackageName);
88365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeLong(mChannelId);
88465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mTitle);
88565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mSeriesId);
88665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mEpisodeTitle);
88765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mSeasonNumber);
88865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mSeasonTitle);
88965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mEpisodeNumber);
89065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeLong(mStartTimeUtcMillis);
89165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeLong(mEndTimeUtcMillis);
89265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mDescription);
89365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mLongDescription);
89465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeInt(mVideoWidth);
89565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeInt(mVideoHeight);
89665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeList(mCriticScores);
89765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mPosterArtUri);
89865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeString(mThumbnailUri);
89965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeIntArray(mCanonicalGenreIds);
90065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeInt(mContentRatings == null ? 0 : mContentRatings.length);
90165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (mContentRatings != null) {
90265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            for (TvContentRating rating : mContentRatings) {
90365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                out.writeString(rating.flattenToString());
90465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
90565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
90665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        out.writeByte((byte) (mRecordingProhibited ? 1 : 0));
90765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
90865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
90965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
91065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Holds one type of critic score and its source.
91165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
91265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static final class CriticScore implements Serializable, Parcelable {
91365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
91465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * The source of the rating.
91565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
91665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public final String source;
91765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
91865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * The score.
91965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
92065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public final String score;
92165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
92265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * The url of the logo image
92365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
92465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public final String logoUrl;
92565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
92665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public static final Parcelable.Creator<CriticScore> CREATOR =
92765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                new Parcelable.Creator<CriticScore>() {
92865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    @Override
92965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    public CriticScore createFromParcel(Parcel in) {
93065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        String source = in.readString();
93165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        String score = in.readString();
93265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        String logoUri  = in.readString();
93365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        return new CriticScore(source, score, logoUri);
93465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    }
93565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
93665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    @Override
93765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    public CriticScore[] newArray(int size) {
93865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        return new CriticScore[size];
93965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    }
94065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                };
94165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
94265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
94365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Constructor for this class.
94465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param source the source of the rating
94565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * @param score the score
94665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
94765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public CriticScore(String source, String score, String logoUrl) {
94865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            this.source = source;
94965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            this.score = score;
95065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            this.logoUrl = logoUrl;
95165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
95265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
95365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @Override
95465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public int describeContents() {
95565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return 0;
95665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
95765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
95865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @Override
95965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public void writeToParcel(Parcel out, int i) {
96065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            out.writeString(source);
96165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            out.writeString(score);
96265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            out.writeString(logoUrl);
96365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
96465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
9653f07ce6c09b77e0c9224a16a4c73c8750ff8a07bYoungsang Cho}
966