10c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang/*
20c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * Copyright (C) 2017 The Android Open Source Project
30c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
40c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * Licensed under the Apache License, Version 2.0 (the "License");
50c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * you may not use this file except in compliance with the License.
60c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * You may obtain a copy of the License at
70c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
80c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *      http://www.apache.org/licenses/LICENSE-2.0
90c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
100c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * Unless required by applicable law or agreed to in writing, software
110c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * distributed under the License is distributed on an "AS IS" BASIS,
120c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * See the License for the specific language governing permissions and
140c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * limitations under the License.
150c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang */
16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.tvprovider.media.tv;
170c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
18ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
190c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
200c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kangimport android.content.ContentValues;
210c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kangimport android.database.Cursor;
22b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kangimport android.os.Build;
23757f518fcb66e82116697d5a226798ae22c14a95Aurimas Liutikas
24ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.IntDef;
25ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo;
26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms;
275b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang
285b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubangimport java.lang.annotation.Retention;
295b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubangimport java.lang.annotation.RetentionPolicy;
30aba04fbe586f159d6625a202f02c815d51b55b2aisaidimport java.util.Objects;
31aba04fbe586f159d6625a202f02c815d51b55b2aisaidimport java.util.Set;
320c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
330c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang/**
340c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * A convenience class to access {@link WatchNextPrograms} entries in the system content
350c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * provider.
360c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
370c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * <p>This class makes it easy to insert or retrieve a program from the system content provider,
380c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * which is defined in {@link TvContractCompat}.
390c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
400c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * <p>Usage example when inserting a "watch next" program:
410c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * <pre>
420c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * WatchNextProgram watchNextProgram = new WatchNextProgram.Builder()
430c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .setWatchNextType(WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE)
440c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .setType(PreviewPrograms.TYPE_MOVIE)
450c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .setTitle("Program Title")
460c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .setDescription("Program Description")
470c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .setPosterArtUri(Uri.parse("http://example.com/poster_art.png"))
480c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         // Set more attributes...
490c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         .build();
500c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * Uri watchNextProgramUri = getContentResolver().insert(WatchNextPrograms.CONTENT_URI,
510c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         watchNextProgram.toContentValues());
520c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * </pre>
530c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *
540c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * <p>Usage example when retrieving a "watch next" program:
550c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * <pre>
560c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * WatchNextProgram watchNextProgram;
570c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * try (Cursor cursor = resolver.query(watchNextProgramUri, null, null, null, null)) {
580c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *     if (cursor != null && cursor.getCount() != 0) {
590c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         cursor.moveToNext();
600c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *         watchNextProgram = WatchNextProgram.fromCursor(cursor);
610c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang *     }
620c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * }
630c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang * </pre>
64b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *
65b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * <p>Usage example when updating an existing "watch next" program:
66b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * <pre>
67b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * WatchNextProgram updatedProgram = new WatchNextProgram.Builder(watchNextProgram)
68b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *         .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
69b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *         .build();
70b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * getContentResolver().update(TvContractCompat.buildWatchNextProgramUri(updatedProgram.getId()),
71b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *         updatedProgram.toContentValues(), null, null);
72b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * </pre>
73b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *
74b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * <p>Usage example when deleting a "watch next" program:
75b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * <pre>
76b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * getContentResolver().delete(TvContractCompat.buildWatchNextProgramUri(existingProgram.getId()),
77b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang *         null, null);
78b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang * </pre>
790c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang */
800c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kangpublic final class WatchNextProgram extends BasePreviewProgram {
810c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
820c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * @hide
830c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
840c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    @RestrictTo(LIBRARY_GROUP)
850c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public static final String[] PROJECTION = getProjection();
860c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
870c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    private static final long INVALID_LONG_VALUE = -1;
880c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    private static final int INVALID_INT_VALUE = -1;
890c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
905b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    /** @hide */
915b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    @IntDef({
925b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang            WATCH_NEXT_TYPE_UNKNOWN,
935b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang            WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE,
945b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang            WatchNextPrograms.WATCH_NEXT_TYPE_NEXT,
955b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang            WatchNextPrograms.WATCH_NEXT_TYPE_NEW,
965b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang            WatchNextPrograms.WATCH_NEXT_TYPE_WATCHLIST,
975b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    })
985b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    @Retention(RetentionPolicy.SOURCE)
995b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    @RestrictTo(LIBRARY_GROUP)
100aba04fbe586f159d6625a202f02c815d51b55b2aisaid    public @interface WatchNextType {
101aba04fbe586f159d6625a202f02c815d51b55b2aisaid    }
1025b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang
1035b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    /**
1045b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang     * The unknown watch next type. Use this type when the actual type is not known.
1055b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang     */
1065b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang    public static final int WATCH_NEXT_TYPE_UNKNOWN = -1;
1075b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang
1080c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    private WatchNextProgram(Builder builder) {
1090c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        super(builder);
1100c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1110c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
1120c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
1135b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang     * @return The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for the program,
1145b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang     * or {@link #WATCH_NEXT_TYPE_UNKNOWN} if it's unknown.
1150c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
116407fc323df9cff9ad90eec812bb6299a2d8c8558Dongwon Kang    public @WatchNextType int getWatchNextType() {
117b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        Integer i = mValues.getAsInteger(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE);
1185b90aea55ed4661ef4dd2b7ee6575242f50fbf36Shubang        return i == null ? WATCH_NEXT_TYPE_UNKNOWN : i;
1190c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1200c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
1210c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
1220c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * @return The value of {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS} for the
1230c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * program.
1240c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
1250c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public long getLastEngagementTimeUtcMillis() {
126b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        Long l = mValues.getAsLong(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS);
127b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        return l == null ? INVALID_LONG_VALUE : l;
1280c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1290c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
1300c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    @Override
1310c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public boolean equals(Object other) {
1320c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        if (!(other instanceof WatchNextProgram)) {
1330c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang            return false;
1340c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
135b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        return mValues.equals(((WatchNextProgram) other).mValues);
1360c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1370c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
138aba04fbe586f159d6625a202f02c815d51b55b2aisaid    /**
139aba04fbe586f159d6625a202f02c815d51b55b2aisaid     * Indicates whether some other WatchNextProgram has any set attribute that is different from
140aba04fbe586f159d6625a202f02c815d51b55b2aisaid     * this WatchNextProgram's respective attributes. An attribute is considered "set" if its key
141aba04fbe586f159d6625a202f02c815d51b55b2aisaid     * is present in the ContentValues vector.
142aba04fbe586f159d6625a202f02c815d51b55b2aisaid     */
143aba04fbe586f159d6625a202f02c815d51b55b2aisaid    public boolean hasAnyUpdatedValues(WatchNextProgram update) {
144aba04fbe586f159d6625a202f02c815d51b55b2aisaid        Set<String> updateKeys = update.mValues.keySet();
145aba04fbe586f159d6625a202f02c815d51b55b2aisaid        for (String key : updateKeys) {
146aba04fbe586f159d6625a202f02c815d51b55b2aisaid            Object updateValue = update.mValues.get(key);
147aba04fbe586f159d6625a202f02c815d51b55b2aisaid            Object currValue = mValues.get(key);
148aba04fbe586f159d6625a202f02c815d51b55b2aisaid            if (!Objects.deepEquals(updateValue, currValue)) {
149aba04fbe586f159d6625a202f02c815d51b55b2aisaid                return true;
150aba04fbe586f159d6625a202f02c815d51b55b2aisaid            }
151aba04fbe586f159d6625a202f02c815d51b55b2aisaid        }
152aba04fbe586f159d6625a202f02c815d51b55b2aisaid        return false;
153aba04fbe586f159d6625a202f02c815d51b55b2aisaid    }
154aba04fbe586f159d6625a202f02c815d51b55b2aisaid
1550c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    @Override
1560c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public String toString() {
157b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        return "WatchNextProgram{" + mValues.toString() + "}";
1580c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1590c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
1600c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
1610c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * @return The fields of the Program in the ContentValues format to be easily inserted into the
1620c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * TV Input Framework database.
1630c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
16498ec0d5b378c8417156037af6389e90f0074a26eAurimas Liutikas    @Override
1650c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public ContentValues toContentValues() {
166d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang        return toContentValues(false);
167d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang    }
168d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang
169d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang    /**
170d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     * Returns fields of the WatchNextProgram in the ContentValues format to be easily inserted
171d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     * into the TV Input Framework database.
172d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     *
173d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     * @param includeProtectedFields Whether the fields protected by system is included or not.
174d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     * @hide
175d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang     */
176d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang    @RestrictTo(LIBRARY_GROUP)
17798ec0d5b378c8417156037af6389e90f0074a26eAurimas Liutikas    @Override
178d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang    public ContentValues toContentValues(boolean includeProtectedFields) {
179d5806e8a47c37fb3a7f2b95b7465a3d6a1ef2fceDongwon Kang        ContentValues values = super.toContentValues(includeProtectedFields);
180b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
181b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang            values.remove(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE);
182b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang            values.remove(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS);
1830c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
1840c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        return values;
1850c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
1860c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
1870c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
1880c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * Creates a WatchNextProgram object from a cursor including the fields defined in
1890c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * {@link WatchNextPrograms}.
1900c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     *
1910c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * @param cursor A row from the TV Input Framework database.
1920c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * @return A Program with the values taken from the cursor.
1930c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
1940c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public static WatchNextProgram fromCursor(Cursor cursor) {
1950c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        // TODO: Add additional API which does not use costly getColumnIndex().
1960c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        Builder builder = new Builder();
1970c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        BasePreviewProgram.setFieldsFromCursor(cursor, builder);
1980c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        int index;
1990c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        if ((index = cursor.getColumnIndex(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE)) >= 0
2000c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang                && !cursor.isNull(index)) {
201407fc323df9cff9ad90eec812bb6299a2d8c8558Dongwon Kang            builder.setWatchNextType(cursor.getInt(index));
2020c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2030c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        if ((index = cursor.getColumnIndex(
2040c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang                WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS)) >= 0
2050c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang                && !cursor.isNull(index)) {
2060c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang            builder.setLastEngagementTimeUtcMillis(cursor.getLong(index));
2070c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2080c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        return builder.build();
2090c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
2100c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2110c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    private static String[] getProjection() {
212aba04fbe586f159d6625a202f02c815d51b55b2aisaid        String[] oColumns = new String[]{
2130c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang                WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE,
2140c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang                WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS,
2150c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        };
2160c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        return CollectionUtils.concatAll(BasePreviewProgram.PROJECTION, oColumns);
2170c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
2180c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2190c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    /**
2200c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     * This Builder class simplifies the creation of a {@link WatchNextProgram} object.
2210c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang     */
2220c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    public static final class Builder extends BasePreviewProgram.Builder<Builder> {
2230c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2240c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        /**
2250c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * Creates a new Builder object.
2260c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         */
2270c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        public Builder() {
2280c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2290c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2300c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        /**
2310c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * Creates a new Builder object with values copied from another Program.
232aba04fbe586f159d6625a202f02c815d51b55b2aisaid         *
2330c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @param other The Program you're copying from.
2340c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         */
2350c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        public Builder(WatchNextProgram other) {
236b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang            mValues = new ContentValues(other.mValues);
2370c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2380c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2390c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        /**
2400c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * Sets the "watch next" type of this program content.
2410c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         *
2420c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * <p>The value should match one of the followings:
2430c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * {@link WatchNextPrograms#WATCH_NEXT_TYPE_CONTINUE},
2440c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEXT}, and
2450c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEW}.
2460c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         *
2470c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @param watchNextType The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for
2480c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         *                      the program.
2490c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @return This Builder object to allow for chaining of calls to builder methods.
2500c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         */
251407fc323df9cff9ad90eec812bb6299a2d8c8558Dongwon Kang        public Builder setWatchNextType(@WatchNextType int watchNextType) {
252b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang            mValues.put(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE, watchNextType);
2530c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang            return this;
2540c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2550c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2560c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        /**
2570c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * Sets the time when the program is going to begin in milliseconds since the epoch.
2580c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         *
2590c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @param lastEngagementTimeUtcMillis The value of
260aba04fbe586f159d6625a202f02c815d51b55b2aisaid         *      {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS}
261aba04fbe586f159d6625a202f02c815d51b55b2aisaid         *      for the program.
2620c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @return This Builder object to allow for chaining of calls to builder methods.
2630c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         */
2640c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        public Builder setLastEngagementTimeUtcMillis(long lastEngagementTimeUtcMillis) {
265b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang            mValues.put(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS,
266b30fefbedf4564400015b61f991607eae61d16d0Dongwon Kang                    lastEngagementTimeUtcMillis);
2670c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang            return this;
2680c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2690c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang
2700c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        /**
2710c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         * @return A new Program with values supplied by the Builder.
2720c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang         */
2730c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        public WatchNextProgram build() {
2740c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang            return new WatchNextProgram(this);
2750c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang        }
2760c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang    }
2770c89a1312d7df71bec4a66a68001df26d16649d5Dongwon Kang}
278