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