1 /* 2 * Copyright (C) 2016 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 */ 16 17 package com.android.tv.data; 18 19 import android.content.Context; 20 import android.media.tv.TvContentRating; 21 import android.support.annotation.Nullable; 22 import android.text.TextUtils; 23 24 import com.android.tv.R; 25 26 import java.util.Comparator; 27 28 /** 29 * Base class for {@link com.android.tv.data.Program} and 30 * {@link com.android.tv.dvr.data.RecordedProgram}. 31 */ 32 public abstract class BaseProgram { 33 /** 34 * Comparator used to compare {@link BaseProgram} according to its season and episodes number. 35 * If a program's season or episode number is null, it will be consider "smaller" than programs 36 * with season or episode numbers. 37 */ 38 public static final Comparator<BaseProgram> EPISODE_COMPARATOR = 39 new EpisodeComparator(false); 40 41 /** 42 * Comparator used to compare {@link BaseProgram} according to its season and episodes number 43 * with season numbers in a reversed order. If a program's season or episode number is null, it 44 * will be consider "smaller" than programs with season or episode numbers. 45 */ 46 public static final Comparator<BaseProgram> SEASON_REVERSED_EPISODE_COMPARATOR = 47 new EpisodeComparator(true); 48 49 private static class EpisodeComparator implements Comparator<BaseProgram> { 50 private final boolean mReversedSeason; 51 EpisodeComparator(boolean reversedSeason)52 EpisodeComparator(boolean reversedSeason) { 53 mReversedSeason = reversedSeason; 54 } 55 56 @Override compare(BaseProgram lhs, BaseProgram rhs)57 public int compare(BaseProgram lhs, BaseProgram rhs) { 58 if (lhs == rhs) { 59 return 0; 60 } 61 int seasonNumberCompare = 62 numberCompare(lhs.getSeasonNumber(), rhs.getSeasonNumber()); 63 if (seasonNumberCompare != 0) { 64 return mReversedSeason ? -seasonNumberCompare : seasonNumberCompare; 65 } else { 66 return numberCompare(lhs.getEpisodeNumber(), rhs.getEpisodeNumber()); 67 } 68 } 69 } 70 71 /** 72 * Compares two strings represent season numbers or episode numbers of programs. 73 */ numberCompare(String s1, String s2)74 public static int numberCompare(String s1, String s2) { 75 if (s1 == s2) { 76 return 0; 77 } else if (s1 == null) { 78 return -1; 79 } else if (s2 == null) { 80 return 1; 81 } else if (s1.equals(s2)) { 82 return 0; 83 } 84 try { 85 return Integer.compare(Integer.parseInt(s1), Integer.parseInt(s2)); 86 } catch (NumberFormatException e) { 87 return s1.compareTo(s2); 88 } 89 } 90 91 /** 92 * Returns ID of the program. 93 */ getId()94 abstract public long getId(); 95 96 /** 97 * Returns the title of the program. 98 */ getTitle()99 abstract public String getTitle(); 100 101 /** 102 * Returns the episode title. 103 */ getEpisodeTitle()104 abstract public String getEpisodeTitle(); 105 106 /** 107 * Returns the displayed title of the program episode. 108 */ getEpisodeDisplayTitle(Context context)109 public String getEpisodeDisplayTitle(Context context) { 110 if (!TextUtils.isEmpty(getEpisodeNumber())) { 111 String episodeTitle = getEpisodeTitle() == null ? "" : getEpisodeTitle(); 112 if (TextUtils.equals(getSeasonNumber(), "0")) { 113 // Do not show "S0: ". 114 return String.format(context.getResources().getString( 115 R.string.display_episode_title_format_no_season_number), 116 getEpisodeNumber(), episodeTitle); 117 } else { 118 return String.format(context.getResources().getString( 119 R.string.display_episode_title_format), 120 getSeasonNumber(), getEpisodeNumber(), episodeTitle); 121 } 122 } 123 return getEpisodeTitle(); 124 } 125 126 /** 127 * Returns the description of the program. 128 */ getDescription()129 abstract public String getDescription(); 130 131 /** 132 * Returns the long description of the program. 133 */ getLongDescription()134 abstract public String getLongDescription(); 135 136 /** 137 * Returns the start time of the program in Milliseconds. 138 */ getStartTimeUtcMillis()139 abstract public long getStartTimeUtcMillis(); 140 141 /** 142 * Returns the end time of the program in Milliseconds. 143 */ getEndTimeUtcMillis()144 abstract public long getEndTimeUtcMillis(); 145 146 /** 147 * Returns the duration of the program in Milliseconds. 148 */ getDurationMillis()149 abstract public long getDurationMillis(); 150 151 /** 152 * Returns the series ID. 153 */ getSeriesId()154 abstract public String getSeriesId(); 155 156 /** 157 * Returns the season number. 158 */ getSeasonNumber()159 abstract public String getSeasonNumber(); 160 161 /** 162 * Returns the episode number. 163 */ getEpisodeNumber()164 abstract public String getEpisodeNumber(); 165 166 /** 167 * Returns URI of the program's poster. 168 */ getPosterArtUri()169 abstract public String getPosterArtUri(); 170 171 /** 172 * Returns URI of the program's thumbnail. 173 */ getThumbnailUri()174 abstract public String getThumbnailUri(); 175 176 /** 177 * Returns the array of the ID's of the canonical genres. 178 */ getCanonicalGenreIds()179 abstract public int[] getCanonicalGenreIds(); 180 181 /** Returns the array of content ratings. */ 182 @Nullable getContentRatings()183 abstract public TvContentRating[] getContentRatings(); 184 185 /** 186 * Returns channel's ID of the program. 187 */ getChannelId()188 abstract public long getChannelId(); 189 190 /** 191 * Returns if the program is valid. 192 */ isValid()193 abstract public boolean isValid(); 194 195 /** 196 * Checks whether the program is episodic or not. 197 */ isEpisodic()198 public boolean isEpisodic() { 199 return getSeriesId() != null; 200 } 201 202 /** 203 * Generates the series ID for the other inputs than the tuner TV input. 204 */ generateSeriesId(String packageName, String title)205 public static String generateSeriesId(String packageName, String title) { 206 return packageName + "/" + title; 207 } 208 }