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