| /* |
| * Copyright (C) 2015 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 com.android.tv.testing.data; |
| |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.media.tv.TvContentRating; |
| import android.media.tv.TvContract; |
| import com.android.tv.testing.R; |
| import com.android.tv.testing.utils.Utils; |
| import java.util.Arrays; |
| import java.util.Objects; |
| import java.util.concurrent.TimeUnit; |
| |
| public final class ProgramInfo { |
| /** If this is specify for title, it will be generated by adding index. */ |
| public static final String GEN_TITLE = ""; |
| |
| /** |
| * If this is specify for episode title, it will be generated by adding index. Also, season and |
| * episode numbers would be generated, too. see: {@link #build} for detail. |
| */ |
| public static final String GEN_EPISODE = ""; |
| |
| private static final int SEASON_MAX = 10; |
| private static final int EPISODE_MAX = 12; |
| |
| /** |
| * If this is specify for poster art, it will be selected one of {@link #POSTER_ARTS_RES} in |
| * order. |
| */ |
| public static final String GEN_POSTER = "GEN"; |
| |
| private static final int[] POSTER_ARTS_RES = { |
| 0, |
| R.drawable.blue, |
| R.drawable.red_large, |
| R.drawable.green, |
| R.drawable.red, |
| R.drawable.green_large, |
| R.drawable.blue_small |
| }; |
| |
| /** |
| * If this is specified for duration, it will be selected one of {@link #DURATIONS_MS} in order. |
| */ |
| public static final int GEN_DURATION = -1; |
| |
| private static final long[] DURATIONS_MS = { |
| TimeUnit.MINUTES.toMillis(15), |
| TimeUnit.MINUTES.toMillis(45), |
| TimeUnit.MINUTES.toMillis(90), |
| TimeUnit.MINUTES.toMillis(60), |
| TimeUnit.MINUTES.toMillis(30), |
| TimeUnit.MINUTES.toMillis(45), |
| TimeUnit.MINUTES.toMillis(60), |
| TimeUnit.MINUTES.toMillis(90), |
| TimeUnit.HOURS.toMillis(5) |
| }; |
| private static long durationsSumMs; |
| |
| static { |
| durationsSumMs = 0; |
| for (long duration : DURATIONS_MS) { |
| durationsSumMs += duration; |
| } |
| } |
| |
| /** If this is specified for genre, it will be selected one of {@link #GENRES} in order. */ |
| public static final String GEN_GENRE = "GEN"; |
| |
| private static final String[] GENRES = { |
| "", |
| TvContract.Programs.Genres.SPORTS, |
| TvContract.Programs.Genres.NEWS, |
| TvContract.Programs.Genres.SHOPPING, |
| TvContract.Programs.Genres.DRAMA, |
| TvContract.Programs.Genres.ENTERTAINMENT |
| }; |
| |
| public final String title; |
| public final String episode; |
| public final int seasonNumber; |
| public final int episodeNumber; |
| public final String posterArtUri; |
| public final String description; |
| public final long durationMs; |
| public final String genre; |
| public final TvContentRating[] contentRatings; |
| public final String resourceUri; |
| |
| public static ProgramInfo fromCursor(Cursor c) { |
| // TODO: Fill other fields. |
| Builder builder = new Builder(); |
| int index = c.getColumnIndex(TvContract.Programs.COLUMN_TITLE); |
| if (index >= 0) { |
| builder.setTitle(c.getString(index)); |
| } |
| index = c.getColumnIndex(TvContract.Programs.COLUMN_SHORT_DESCRIPTION); |
| if (index >= 0) { |
| builder.setDescription(c.getString(index)); |
| } |
| index = c.getColumnIndex(TvContract.Programs.COLUMN_EPISODE_TITLE); |
| if (index >= 0) { |
| builder.setEpisode(c.getString(index)); |
| } |
| return builder.build(); |
| } |
| |
| public ProgramInfo( |
| String title, |
| String episode, |
| int seasonNumber, |
| int episodeNumber, |
| String posterArtUri, |
| String description, |
| long durationMs, |
| TvContentRating[] contentRatings, |
| String genre, |
| String resourceUri) { |
| this.title = title; |
| this.episode = episode; |
| this.seasonNumber = seasonNumber; |
| this.episodeNumber = episodeNumber; |
| this.posterArtUri = posterArtUri; |
| this.description = description; |
| this.durationMs = durationMs; |
| this.contentRatings = contentRatings; |
| this.genre = genre; |
| this.resourceUri = resourceUri; |
| } |
| |
| /** |
| * Create a instance of {@link ProgramInfo} whose content will be generated as much as possible. |
| */ |
| public static ProgramInfo create() { |
| return new Builder().build(); |
| } |
| |
| /** |
| * Get index of the program whose start time equals or less than {@code timeMs} and end time |
| * more than {@code timeMs}. |
| * |
| * @param timeMs target time in millis to find a program. |
| * @param channelId used to add complexity to the index between two consequence channels. |
| */ |
| public int getIndex(long timeMs, long channelId) { |
| if (durationMs != GEN_DURATION) { |
| return Math.max((int) (timeMs / durationMs), 0); |
| } |
| long startTimeMs = channelId * DURATIONS_MS[((int) (channelId % DURATIONS_MS.length))]; |
| int index = (int) ((timeMs - startTimeMs) / durationsSumMs) * DURATIONS_MS.length; |
| startTimeMs += (index / DURATIONS_MS.length) * durationsSumMs; |
| while (startTimeMs + DURATIONS_MS[index % DURATIONS_MS.length] < timeMs) { |
| startTimeMs += DURATIONS_MS[index % DURATIONS_MS.length]; |
| index++; |
| } |
| return index; |
| } |
| |
| /** |
| * Returns the start time for the program with the position. |
| * |
| * @param index index returned by {@link #getIndex} |
| */ |
| public long getStartTimeMs(int index, long channelId) { |
| if (durationMs != GEN_DURATION) { |
| return index * durationMs; |
| } |
| long startTimeMs = |
| channelId * DURATIONS_MS[((int) (channelId % DURATIONS_MS.length))] |
| + (index / DURATIONS_MS.length) * durationsSumMs; |
| for (int i = 0; i < index % DURATIONS_MS.length; i++) { |
| startTimeMs += DURATIONS_MS[i]; |
| } |
| return startTimeMs; |
| } |
| |
| /** |
| * Return complete {@link ProgramInfo} with the generated value. See: {@link #GEN_TITLE}, {@link |
| * #GEN_EPISODE}, {@link #GEN_POSTER}, {@link #GEN_DURATION}, {@link #GEN_GENRE}. |
| * |
| * @param index index returned by {@link #getIndex} |
| */ |
| public ProgramInfo build(Context context, int index) { |
| if (!GEN_TITLE.equals(title) |
| && episode == null |
| && !GEN_POSTER.equals(posterArtUri) |
| && durationMs != GEN_DURATION |
| && !GEN_GENRE.equals(genre)) { |
| return this; |
| } |
| return new ProgramInfo( |
| GEN_TITLE.equals(title) ? "Title(" + index + ")" : title, |
| GEN_EPISODE.equals(episode) ? "Episode(" + index + ")" : episode, |
| episode != null ? (index % SEASON_MAX + 1) : seasonNumber, |
| episode != null ? (index % EPISODE_MAX + 1) : episodeNumber, |
| GEN_POSTER.equals(posterArtUri) |
| ? Utils.getUriStringForResource( |
| context, POSTER_ARTS_RES[index % POSTER_ARTS_RES.length]) |
| : posterArtUri, |
| description, |
| durationMs == GEN_DURATION ? DURATIONS_MS[index % DURATIONS_MS.length] : durationMs, |
| contentRatings, |
| GEN_GENRE.equals(genre) ? GENRES[index % GENRES.length] : genre, |
| resourceUri); |
| } |
| |
| @Override |
| public String toString() { |
| return "ProgramInfo{title=" |
| + title |
| + ", episode=" |
| + episode |
| + ", durationMs=" |
| + durationMs |
| + "}"; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (o == null || getClass() != o.getClass()) { |
| return false; |
| } |
| ProgramInfo that = (ProgramInfo) o; |
| return Objects.equals(seasonNumber, that.seasonNumber) |
| && Objects.equals(episodeNumber, that.episodeNumber) |
| && Objects.equals(durationMs, that.durationMs) |
| && Objects.equals(title, that.title) |
| && Objects.equals(episode, that.episode) |
| && Objects.equals(posterArtUri, that.posterArtUri) |
| && Objects.equals(description, that.description) |
| && Objects.equals(genre, that.genre) |
| && Arrays.equals(contentRatings, that.contentRatings) |
| && Objects.equals(resourceUri, that.resourceUri); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(title, episode, seasonNumber, episodeNumber); |
| } |
| |
| public static class Builder { |
| private String mTitle = GEN_TITLE; |
| private String mEpisode = GEN_EPISODE; |
| private int mSeasonNumber; |
| private int mEpisodeNumber; |
| private String mPosterArtUri = GEN_POSTER; |
| private String mDescription; |
| private long mDurationMs = GEN_DURATION; |
| private TvContentRating[] mContentRatings; |
| private String mGenre = GEN_GENRE; |
| private String mResourceUri; |
| |
| public Builder setTitle(String title) { |
| mTitle = title; |
| return this; |
| } |
| |
| public Builder setEpisode(String episode) { |
| mEpisode = episode; |
| return this; |
| } |
| |
| public Builder setSeasonNumber(int seasonNumber) { |
| mSeasonNumber = seasonNumber; |
| return this; |
| } |
| |
| public Builder setEpisodeNumber(int episodeNumber) { |
| mEpisodeNumber = episodeNumber; |
| return this; |
| } |
| |
| public Builder setPosterArtUri(String posterArtUri) { |
| mPosterArtUri = posterArtUri; |
| return this; |
| } |
| |
| public Builder setDescription(String description) { |
| mDescription = description; |
| return this; |
| } |
| |
| public Builder setDurationMs(long durationMs) { |
| mDurationMs = durationMs; |
| return this; |
| } |
| |
| public Builder setContentRatings(TvContentRating[] contentRatings) { |
| mContentRatings = contentRatings; |
| return this; |
| } |
| |
| public Builder setGenre(String genre) { |
| mGenre = genre; |
| return this; |
| } |
| |
| public Builder setResourceUri(String resourceUri) { |
| mResourceUri = resourceUri; |
| return this; |
| } |
| |
| public ProgramInfo build() { |
| return new ProgramInfo( |
| mTitle, |
| mEpisode, |
| mSeasonNumber, |
| mEpisodeNumber, |
| mPosterArtUri, |
| mDescription, |
| mDurationMs, |
| mContentRatings, |
| mGenre, |
| mResourceUri); |
| } |
| } |
| } |