/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package androidx.tvprovider.media.tv; import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; import android.content.ContentValues; import android.database.Cursor; import android.os.Build; import androidx.annotation.IntDef; import androidx.annotation.RestrictTo; import androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; import java.util.Set; /** * A convenience class to access {@link WatchNextPrograms} entries in the system content * provider. * *
This class makes it easy to insert or retrieve a program from the system content provider, * which is defined in {@link TvContractCompat}. * *
Usage example when inserting a "watch next" program: *
* WatchNextProgram watchNextProgram = new WatchNextProgram.Builder() * .setWatchNextType(WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE) * .setType(PreviewPrograms.TYPE_MOVIE) * .setTitle("Program Title") * .setDescription("Program Description") * .setPosterArtUri(Uri.parse("http://example.com/poster_art.png")) * // Set more attributes... * .build(); * Uri watchNextProgramUri = getContentResolver().insert(WatchNextPrograms.CONTENT_URI, * watchNextProgram.toContentValues()); ** *
Usage example when retrieving a "watch next" program: *
* WatchNextProgram watchNextProgram; * try (Cursor cursor = resolver.query(watchNextProgramUri, null, null, null, null)) { * if (cursor != null && cursor.getCount() != 0) { * cursor.moveToNext(); * watchNextProgram = WatchNextProgram.fromCursor(cursor); * } * } ** *
Usage example when updating an existing "watch next" program: *
* WatchNextProgram updatedProgram = new WatchNextProgram.Builder(watchNextProgram) * .setLastEngagementTimeUtcMillis(System.currentTimeMillis()) * .build(); * getContentResolver().update(TvContractCompat.buildWatchNextProgramUri(updatedProgram.getId()), * updatedProgram.toContentValues(), null, null); ** *
Usage example when deleting a "watch next" program: *
* getContentResolver().delete(TvContractCompat.buildWatchNextProgramUri(existingProgram.getId()), * null, null); **/ public final class WatchNextProgram extends BasePreviewProgram { /** * @hide */ @RestrictTo(LIBRARY_GROUP) public static final String[] PROJECTION = getProjection(); private static final long INVALID_LONG_VALUE = -1; private static final int INVALID_INT_VALUE = -1; /** @hide */ @IntDef({ WATCH_NEXT_TYPE_UNKNOWN, WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE, WatchNextPrograms.WATCH_NEXT_TYPE_NEXT, WatchNextPrograms.WATCH_NEXT_TYPE_NEW, WatchNextPrograms.WATCH_NEXT_TYPE_WATCHLIST, }) @Retention(RetentionPolicy.SOURCE) @RestrictTo(LIBRARY_GROUP) public @interface WatchNextType { } /** * The unknown watch next type. Use this type when the actual type is not known. */ public static final int WATCH_NEXT_TYPE_UNKNOWN = -1; private WatchNextProgram(Builder builder) { super(builder); } /** * @return The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for the program, * or {@link #WATCH_NEXT_TYPE_UNKNOWN} if it's unknown. */ public @WatchNextType int getWatchNextType() { Integer i = mValues.getAsInteger(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE); return i == null ? WATCH_NEXT_TYPE_UNKNOWN : i; } /** * @return The value of {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS} for the * program. */ public long getLastEngagementTimeUtcMillis() { Long l = mValues.getAsLong(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS); return l == null ? INVALID_LONG_VALUE : l; } @Override public boolean equals(Object other) { if (!(other instanceof WatchNextProgram)) { return false; } return mValues.equals(((WatchNextProgram) other).mValues); } /** * Indicates whether some other WatchNextProgram has any set attribute that is different from * this WatchNextProgram's respective attributes. An attribute is considered "set" if its key * is present in the ContentValues vector. */ public boolean hasAnyUpdatedValues(WatchNextProgram update) { Set
The value should match one of the followings: * {@link WatchNextPrograms#WATCH_NEXT_TYPE_CONTINUE}, * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEXT}, and * {@link WatchNextPrograms#WATCH_NEXT_TYPE_NEW}. * * @param watchNextType The value of {@link WatchNextPrograms#COLUMN_WATCH_NEXT_TYPE} for * the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setWatchNextType(@WatchNextType int watchNextType) { mValues.put(WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE, watchNextType); return this; } /** * Sets the time when the program is going to begin in milliseconds since the epoch. * * @param lastEngagementTimeUtcMillis The value of * {@link WatchNextPrograms#COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS} * for the program. * @return This Builder object to allow for chaining of calls to builder methods. */ public Builder setLastEngagementTimeUtcMillis(long lastEngagementTimeUtcMillis) { mValues.put(WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS, lastEngagementTimeUtcMillis); return this; } /** * @return A new Program with values supplied by the Builder. */ public WatchNextProgram build() { return new WatchNextProgram(this); } } }