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