WatchNextProgram.java revision 98ec0d5b378c8417156037af6389e90f0074a26e
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.media.tv; 17 18import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 19 20import android.annotation.TargetApi; 21import android.content.ContentValues; 22import android.database.Cursor; 23import android.support.annotation.RestrictTo; 24import android.support.media.tv.TvContractCompat.WatchNextPrograms; 25import android.support.media.tv.TvContractCompat.WatchNextPrograms.WatchNextType; 26import android.text.TextUtils; 27 28import java.util.Objects; 29 30/** 31 * A convenience class to access {@link WatchNextPrograms} entries in the system content 32 * provider. 33 * 34 * <p>This class makes it easy to insert or retrieve a program from the system content provider, 35 * which is defined in {@link TvContractCompat}. 36 * 37 * <p>Usage example when inserting a "watch next" program: 38 * <pre> 39 * WatchNextProgram watchNextProgram = new WatchNextProgram.Builder() 40 * .setWatchNextType(WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE) 41 * .setType(PreviewPrograms.TYPE_MOVIE) 42 * .setTitle("Program Title") 43 * .setDescription("Program Description") 44 * .setPosterArtUri(Uri.parse("http://example.com/poster_art.png")) 45 * // Set more attributes... 46 * .build(); 47 * Uri watchNextProgramUri = getContentResolver().insert(WatchNextPrograms.CONTENT_URI, 48 * watchNextProgram.toContentValues()); 49 * </pre> 50 * 51 * <p>Usage example when retrieving a "watch next" program: 52 * <pre> 53 * WatchNextProgram watchNextProgram; 54 * try (Cursor cursor = resolver.query(watchNextProgramUri, null, null, null, null)) { 55 * if (cursor != null && cursor.getCount() != 0) { 56 * cursor.moveToNext(); 57 * watchNextProgram = WatchNextProgram.fromCursor(cursor); 58 * } 59 * } 60 * </pre> 61 */ 62@TargetApi(26) 63public final class WatchNextProgram extends BasePreviewProgram { 64 /** 65 * @hide 66 */ 67 @RestrictTo(LIBRARY_GROUP) 68 public static final String[] PROJECTION = getProjection(); 69 70 private static final long INVALID_LONG_VALUE = -1; 71 private static final int INVALID_INT_VALUE = -1; 72 73 private final String mWatchNextType; 74 private final long mLastEngagementTimeUtcMillis; 75 76 private WatchNextProgram(Builder builder) { 77 super(builder); 78 mWatchNextType = builder.mWatchNextType; 79 mLastEngagementTimeUtcMillis = builder.mLastEngagementTimeUtcMillis; 80 } 81 82 /** 83 * @return The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for the program. 84 */ 85 public @WatchNextType String getWatchNextType() { 86 return mWatchNextType; 87 } 88 89 /** 90 * @return The value of {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS} for the 91 * program. 92 */ 93 public long getLastEngagementTimeUtcMillis() { 94 return mLastEngagementTimeUtcMillis; 95 } 96 97 @Override 98 public boolean equals(Object other) { 99 if (!(other instanceof WatchNextProgram)) { 100 return false; 101 } 102 if (!super.equals(other)) { 103 return false; 104 } 105 WatchNextProgram program = (WatchNextProgram) other; 106 return Objects.equals(mWatchNextType, program.mWatchNextType) 107 && mLastEngagementTimeUtcMillis == program.mLastEngagementTimeUtcMillis; 108 } 109 110 @Override 111 public String toString() { 112 return "Program{" 113 + ", watchNextType=" + mWatchNextType 114 + ", lastEngagementTimeUtcMillis=" + mLastEngagementTimeUtcMillis 115 + "}"; 116 } 117 118 /** 119 * @return The fields of the Program in the ContentValues format to be easily inserted into the 120 * TV Input Framework database. 121 */ 122 @Override 123 public ContentValues toContentValues() { 124 return toContentValues(false); 125 } 126 127 /** 128 * Returns fields of the WatchNextProgram in the ContentValues format to be easily inserted 129 * into the TV Input Framework database. 130 * 131 * @param includeProtectedFields Whether the fields protected by system is included or not. 132 * @hide 133 */ 134 @RestrictTo(LIBRARY_GROUP) 135 @Override 136 public ContentValues toContentValues(boolean includeProtectedFields) { 137 ContentValues values = super.toContentValues(includeProtectedFields); 138 if (!TextUtils.isEmpty(mWatchNextType)) { 139 values.put(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE, mWatchNextType); 140 } 141 if (mLastEngagementTimeUtcMillis != INVALID_LONG_VALUE) { 142 values.put(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS, 143 mLastEngagementTimeUtcMillis); 144 } 145 return values; 146 } 147 148 /** 149 * Creates a WatchNextProgram object from a cursor including the fields defined in 150 * {@link WatchNextPrograms}. 151 * 152 * @param cursor A row from the TV Input Framework database. 153 * @return A Program with the values taken from the cursor. 154 */ 155 public static WatchNextProgram fromCursor(Cursor cursor) { 156 // TODO: Add additional API which does not use costly getColumnIndex(). 157 Builder builder = new Builder(); 158 BasePreviewProgram.setFieldsFromCursor(cursor, builder); 159 int index; 160 if ((index = cursor.getColumnIndex(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE)) >= 0 161 && !cursor.isNull(index)) { 162 builder.setWatchNextType(cursor.getString(index)); 163 } 164 if ((index = cursor.getColumnIndex( 165 WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS)) >= 0 166 && !cursor.isNull(index)) { 167 builder.setLastEngagementTimeUtcMillis(cursor.getLong(index)); 168 } 169 return builder.build(); 170 } 171 172 private static String[] getProjection() { 173 String[] oColumns = new String[] { 174 WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE, 175 WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS, 176 }; 177 return CollectionUtils.concatAll(BasePreviewProgram.PROJECTION, oColumns); 178 } 179 180 /** 181 * This Builder class simplifies the creation of a {@link WatchNextProgram} object. 182 */ 183 public static final class Builder extends BasePreviewProgram.Builder<Builder> { 184 private String mWatchNextType; 185 private long mLastEngagementTimeUtcMillis = INVALID_LONG_VALUE; 186 187 /** 188 * Creates a new Builder object. 189 */ 190 public Builder() { 191 } 192 193 /** 194 * Creates a new Builder object with values copied from another Program. 195 * @param other The Program you're copying from. 196 */ 197 public Builder(WatchNextProgram other) { 198 super(other); 199 mWatchNextType = other.mWatchNextType; 200 mLastEngagementTimeUtcMillis = other.mLastEngagementTimeUtcMillis; 201 } 202 203 /** 204 * Sets the "watch next" type of this program content. 205 * 206 * <p>The value should match one of the followings: 207 * {@link WatchNextPrograms#WATCH_NEXT_TYPE_CONTINUE}, 208 * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEXT}, and 209 * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEW}. 210 * 211 * @param watchNextType The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for 212 * the program. 213 * @return This Builder object to allow for chaining of calls to builder methods. 214 */ 215 public Builder setWatchNextType(@WatchNextType String watchNextType) { 216 mWatchNextType = watchNextType; 217 return this; 218 } 219 220 /** 221 * Sets the time when the program is going to begin in milliseconds since the epoch. 222 * 223 * @param lastEngagementTimeUtcMillis The value of 224 * {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS} for the program. 225 * @return This Builder object to allow for chaining of calls to builder methods. 226 */ 227 public Builder setLastEngagementTimeUtcMillis(long lastEngagementTimeUtcMillis) { 228 mLastEngagementTimeUtcMillis = lastEngagementTimeUtcMillis; 229 return this; 230 } 231 232 /** 233 * @return A new Program with values supplied by the Builder. 234 */ 235 public WatchNextProgram build() { 236 return new WatchNextProgram(this); 237 } 238 } 239} 240