1 /* 2 * Copyright (C) 2015 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.testing.data; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.database.Cursor; 22 import android.media.tv.TvContract; 23 import android.net.Uri; 24 import android.support.annotation.Nullable; 25 import android.util.SparseArray; 26 import java.util.Objects; 27 28 /** Channel Information. */ 29 public final class ChannelInfo { 30 private static final SparseArray<String> VIDEO_HEIGHT_TO_FORMAT_MAP = new SparseArray<>(); 31 32 static { 33 VIDEO_HEIGHT_TO_FORMAT_MAP.put(480, TvContract.Channels.VIDEO_FORMAT_480P); 34 VIDEO_HEIGHT_TO_FORMAT_MAP.put(576, TvContract.Channels.VIDEO_FORMAT_576P); 35 VIDEO_HEIGHT_TO_FORMAT_MAP.put(720, TvContract.Channels.VIDEO_FORMAT_720P); 36 VIDEO_HEIGHT_TO_FORMAT_MAP.put(1080, TvContract.Channels.VIDEO_FORMAT_1080P); 37 VIDEO_HEIGHT_TO_FORMAT_MAP.put(2160, TvContract.Channels.VIDEO_FORMAT_2160P); 38 VIDEO_HEIGHT_TO_FORMAT_MAP.put(4320, TvContract.Channels.VIDEO_FORMAT_4320P); 39 } 40 41 public static final String[] PROJECTION = { 42 TvContract.Channels.COLUMN_DISPLAY_NUMBER, 43 TvContract.Channels.COLUMN_DISPLAY_NAME, 44 TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID, 45 }; 46 47 public final String number; 48 public final String name; 49 public final String logoUrl; 50 public final int originalNetworkId; 51 public final int videoWidth; 52 public final int videoHeight; 53 public final float videoPixelAspectRatio; 54 public final int audioChannel; 55 public final int audioLanguageCount; 56 public final boolean hasClosedCaption; 57 public final ProgramInfo program; 58 public final String appLinkText; 59 public final int appLinkColor; 60 public final String appLinkIconUri; 61 public final String appLinkPosterArtUri; 62 public final String appLinkIntentUri; 63 64 /** 65 * Create a channel info for TVTestInput. 66 * 67 * @param context a context to insert logo. It can be null if logo isn't needed. 68 * @param channelNumber a channel number to be use as an identifier. {@link #originalNetworkId} 69 * will be assigned the same value, too. 70 */ create(@ullable Context context, int channelNumber)71 public static ChannelInfo create(@Nullable Context context, int channelNumber) { 72 Builder builder = 73 new Builder() 74 .setNumber(String.valueOf(channelNumber)) 75 .setName("Channel " + channelNumber) 76 .setOriginalNetworkId(channelNumber); 77 if (context != null) { 78 // tests/input/tools/get_test_logos.sh only stores 1000 logos. 79 builder.setLogoUrl(getUriStringForChannelLogo(context, channelNumber)); 80 } 81 return builder.build(); 82 } 83 getUriStringForChannelLogo(Context context, int logoIndex)84 public static String getUriStringForChannelLogo(Context context, int logoIndex) { 85 int index = (logoIndex % 1000) + 1; 86 return new Uri.Builder() 87 .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 88 .authority(context.getPackageName()) 89 .path("drawable") 90 .appendPath("ch_" + index + "_logo") 91 .build() 92 .toString(); 93 } 94 fromCursor(Cursor c)95 public static ChannelInfo fromCursor(Cursor c) { 96 // TODO: Fill other fields. 97 Builder builder = new Builder(); 98 int index = c.getColumnIndex(TvContract.Channels.COLUMN_DISPLAY_NUMBER); 99 if (index >= 0) { 100 builder.setNumber(c.getString(index)); 101 } 102 index = c.getColumnIndex(TvContract.Channels.COLUMN_DISPLAY_NAME); 103 if (index >= 0) { 104 builder.setName(c.getString(index)); 105 } 106 index = c.getColumnIndex(TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID); 107 if (index >= 0) { 108 builder.setOriginalNetworkId(c.getInt(index)); 109 } 110 return builder.build(); 111 } 112 ChannelInfo( String number, String name, String logoUrl, int originalNetworkId, int videoWidth, int videoHeight, float videoPixelAspectRatio, int audioChannel, int audioLanguageCount, boolean hasClosedCaption, ProgramInfo program, String appLinkText, int appLinkColor, String appLinkIconUri, String appLinkPosterArtUri, String appLinkIntentUri)113 private ChannelInfo( 114 String number, 115 String name, 116 String logoUrl, 117 int originalNetworkId, 118 int videoWidth, 119 int videoHeight, 120 float videoPixelAspectRatio, 121 int audioChannel, 122 int audioLanguageCount, 123 boolean hasClosedCaption, 124 ProgramInfo program, 125 String appLinkText, 126 int appLinkColor, 127 String appLinkIconUri, 128 String appLinkPosterArtUri, 129 String appLinkIntentUri) { 130 this.number = number; 131 this.name = name; 132 this.logoUrl = logoUrl; 133 this.originalNetworkId = originalNetworkId; 134 this.videoWidth = videoWidth; 135 this.videoHeight = videoHeight; 136 this.videoPixelAspectRatio = videoPixelAspectRatio; 137 this.audioChannel = audioChannel; 138 this.audioLanguageCount = audioLanguageCount; 139 this.hasClosedCaption = hasClosedCaption; 140 this.program = program; 141 this.appLinkText = appLinkText; 142 this.appLinkColor = appLinkColor; 143 this.appLinkIconUri = appLinkIconUri; 144 this.appLinkPosterArtUri = appLinkPosterArtUri; 145 this.appLinkIntentUri = appLinkIntentUri; 146 } 147 getVideoFormat()148 public String getVideoFormat() { 149 return VIDEO_HEIGHT_TO_FORMAT_MAP.get(videoHeight); 150 } 151 152 @Override toString()153 public String toString() { 154 return "Channel{" 155 + "number=" 156 + number 157 + ", name=" 158 + name 159 + ", logoUri=" 160 + logoUrl 161 + ", originalNetworkId=" 162 + originalNetworkId 163 + ", videoWidth=" 164 + videoWidth 165 + ", videoHeight=" 166 + videoHeight 167 + ", audioChannel=" 168 + audioChannel 169 + ", audioLanguageCount=" 170 + audioLanguageCount 171 + ", hasClosedCaption=" 172 + hasClosedCaption 173 + ", appLinkText=" 174 + appLinkText 175 + ", appLinkColor=" 176 + appLinkColor 177 + ", appLinkIconUri=" 178 + appLinkIconUri 179 + ", appLinkPosterArtUri=" 180 + appLinkPosterArtUri 181 + ", appLinkIntentUri=" 182 + appLinkIntentUri 183 + "}"; 184 } 185 186 @Override equals(Object o)187 public boolean equals(Object o) { 188 if (this == o) { 189 return true; 190 } 191 if (o == null || getClass() != o.getClass()) { 192 return false; 193 } 194 ChannelInfo that = (ChannelInfo) o; 195 return Objects.equals(originalNetworkId, that.originalNetworkId) 196 && Objects.equals(videoWidth, that.videoWidth) 197 && Objects.equals(videoHeight, that.videoHeight) 198 && Objects.equals(audioChannel, that.audioChannel) 199 && Objects.equals(audioLanguageCount, that.audioLanguageCount) 200 && Objects.equals(hasClosedCaption, that.hasClosedCaption) 201 && Objects.equals(appLinkColor, that.appLinkColor) 202 && Objects.equals(number, that.number) 203 && Objects.equals(name, that.name) 204 && Objects.equals(logoUrl, that.logoUrl) 205 && Objects.equals(program, that.program) 206 && Objects.equals(appLinkText, that.appLinkText) 207 && Objects.equals(appLinkIconUri, that.appLinkIconUri) 208 && Objects.equals(appLinkPosterArtUri, that.appLinkPosterArtUri) 209 && Objects.equals(appLinkIntentUri, that.appLinkIntentUri); 210 } 211 212 @Override hashCode()213 public int hashCode() { 214 return Objects.hash(number, name, originalNetworkId); 215 } 216 217 /** Builder class for {@code ChannelInfo}. */ 218 public static class Builder { 219 private String mNumber; 220 private String mName; 221 private String mLogoUrl = null; 222 private int mOriginalNetworkId; 223 private int mVideoWidth = 1920; // Width for HD video. 224 private int mVideoHeight = 1080; // Height for HD video. 225 private float mVideoPixelAspectRatio = 1.0f; // default value 226 private int mAudioChannel; 227 private int mAudioLanguageCount; 228 private boolean mHasClosedCaption; 229 private ProgramInfo mProgram; 230 private String mAppLinkText; 231 private int mAppLinkColor; 232 private String mAppLinkIconUri; 233 private String mAppLinkPosterArtUri; 234 private String mAppLinkIntentUri; 235 Builder()236 public Builder() {} 237 Builder(ChannelInfo other)238 public Builder(ChannelInfo other) { 239 mNumber = other.number; 240 mName = other.name; 241 mLogoUrl = other.name; 242 mOriginalNetworkId = other.originalNetworkId; 243 mVideoWidth = other.videoWidth; 244 mVideoHeight = other.videoHeight; 245 mVideoPixelAspectRatio = other.videoPixelAspectRatio; 246 mAudioChannel = other.audioChannel; 247 mAudioLanguageCount = other.audioLanguageCount; 248 mHasClosedCaption = other.hasClosedCaption; 249 mProgram = other.program; 250 } 251 setName(String name)252 public Builder setName(String name) { 253 mName = name; 254 return this; 255 } 256 setNumber(String number)257 public Builder setNumber(String number) { 258 mNumber = number; 259 return this; 260 } 261 setLogoUrl(String logoUrl)262 public Builder setLogoUrl(String logoUrl) { 263 mLogoUrl = logoUrl; 264 return this; 265 } 266 setOriginalNetworkId(int originalNetworkId)267 public Builder setOriginalNetworkId(int originalNetworkId) { 268 mOriginalNetworkId = originalNetworkId; 269 return this; 270 } 271 setVideoWidth(int videoWidth)272 public Builder setVideoWidth(int videoWidth) { 273 mVideoWidth = videoWidth; 274 return this; 275 } 276 setVideoHeight(int videoHeight)277 public Builder setVideoHeight(int videoHeight) { 278 mVideoHeight = videoHeight; 279 return this; 280 } 281 setVideoPixelAspectRatio(float videoPixelAspectRatio)282 public Builder setVideoPixelAspectRatio(float videoPixelAspectRatio) { 283 mVideoPixelAspectRatio = videoPixelAspectRatio; 284 return this; 285 } 286 setAudioChannel(int audioChannel)287 public Builder setAudioChannel(int audioChannel) { 288 mAudioChannel = audioChannel; 289 return this; 290 } 291 setAudioLanguageCount(int audioLanguageCount)292 public Builder setAudioLanguageCount(int audioLanguageCount) { 293 mAudioLanguageCount = audioLanguageCount; 294 return this; 295 } 296 setHasClosedCaption(boolean hasClosedCaption)297 public Builder setHasClosedCaption(boolean hasClosedCaption) { 298 mHasClosedCaption = hasClosedCaption; 299 return this; 300 } 301 setProgram(ProgramInfo program)302 public Builder setProgram(ProgramInfo program) { 303 mProgram = program; 304 return this; 305 } 306 setAppLinkText(String appLinkText)307 public Builder setAppLinkText(String appLinkText) { 308 mAppLinkText = appLinkText; 309 return this; 310 } 311 setAppLinkColor(int appLinkColor)312 public Builder setAppLinkColor(int appLinkColor) { 313 mAppLinkColor = appLinkColor; 314 return this; 315 } 316 setAppLinkIconUri(String appLinkIconUri)317 public Builder setAppLinkIconUri(String appLinkIconUri) { 318 mAppLinkIconUri = appLinkIconUri; 319 return this; 320 } 321 setAppLinkPosterArtUri(String appLinkPosterArtUri)322 public Builder setAppLinkPosterArtUri(String appLinkPosterArtUri) { 323 mAppLinkPosterArtUri = appLinkPosterArtUri; 324 return this; 325 } 326 setAppLinkIntentUri(String appLinkIntentUri)327 public Builder setAppLinkIntentUri(String appLinkIntentUri) { 328 mAppLinkIntentUri = appLinkIntentUri; 329 return this; 330 } 331 build()332 public ChannelInfo build() { 333 return new ChannelInfo( 334 mNumber, 335 mName, 336 mLogoUrl, 337 mOriginalNetworkId, 338 mVideoWidth, 339 mVideoHeight, 340 mVideoPixelAspectRatio, 341 mAudioChannel, 342 mAudioLanguageCount, 343 mHasClosedCaption, 344 mProgram, 345 mAppLinkText, 346 mAppLinkColor, 347 mAppLinkIconUri, 348 mAppLinkPosterArtUri, 349 mAppLinkIntentUri); 350 } 351 } 352 } 353