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