1 /*
2  * Copyright (C) 2017 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.net.Uri;
21 import android.support.annotation.VisibleForTesting;
22 import android.text.TextUtils;
23 import android.util.Pair;
24 
25 import androidx.tvprovider.media.tv.TvContractCompat;
26 
27 import com.android.tv.TvSingletons;
28 import com.android.tv.data.api.Channel;
29 import com.android.tv.data.api.Program;
30 import com.android.tv.dvr.data.RecordedProgram;
31 
32 import java.util.Objects;
33 
34 /** A class to store the content of preview programs. */
35 public class PreviewProgramContent {
36     @VisibleForTesting static final String PARAM_INPUT = "input";
37 
38     private long mId;
39     private long mPreviewChannelId;
40     private int mType;
41     private boolean mLive;
42     private String mTitle;
43     private String mDescription;
44     private Uri mPosterArtUri;
45     private Uri mIntentUri;
46     private Uri mPreviewVideoUri;
47 
48     /** Create preview program content from {@link ProgramImpl} */
createFromProgram( Context context, long previewChannelId, Program program)49     public static PreviewProgramContent createFromProgram(
50             Context context, long previewChannelId, Program program) {
51         Channel channel =
52                 TvSingletons.getSingletons(context)
53                         .getChannelDataManager()
54                         .getChannel(program.getChannelId());
55         return channel == null ? null : createFromProgram(previewChannelId, program, channel);
56     }
57 
58     /** Create preview program content from {@link RecordedProgram} */
createFromRecordedProgram( Context context, long previewChannelId, RecordedProgram recordedProgram)59     public static PreviewProgramContent createFromRecordedProgram(
60             Context context, long previewChannelId, RecordedProgram recordedProgram) {
61         Channel channel =
62                 TvSingletons.getSingletons(context)
63                         .getChannelDataManager()
64                         .getChannel(recordedProgram.getChannelId());
65         return createFromRecordedProgram(previewChannelId, recordedProgram, channel);
66     }
67 
68     @VisibleForTesting
createFromProgram( long previewChannelId, Program program, Channel channel)69     static PreviewProgramContent createFromProgram(
70             long previewChannelId, Program program, Channel channel) {
71         String channelDisplayName = channel.getDisplayName();
72         return new PreviewProgramContent.Builder()
73                 .setId(program.getId())
74                 .setPreviewChannelId(previewChannelId)
75                 .setType(TvContractCompat.PreviewPrograms.TYPE_CHANNEL)
76                 .setLive(true)
77                 .setTitle(program.getTitle())
78                 .setDescription(
79                         !TextUtils.isEmpty(channelDisplayName)
80                                 ? channelDisplayName
81                                 : channel.getDisplayNumber())
82                 .setPosterArtUri(Uri.parse(program.getPosterArtUri()))
83                 .setIntentUri(channel.getUri())
84                 .setPreviewVideoUri(
85                         PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
86                                 channel.getUri(), Pair.create(PARAM_INPUT, channel.getInputId())))
87                 .build();
88     }
89 
90     @VisibleForTesting
createFromRecordedProgram( long previewChannelId, RecordedProgram recordedProgram, Channel channel)91     static PreviewProgramContent createFromRecordedProgram(
92             long previewChannelId, RecordedProgram recordedProgram, Channel channel) {
93         String channelDisplayName = channel == null ? null : channel.getDisplayName();
94         Uri recordedProgramUri = TvContractCompat.buildRecordedProgramUri(recordedProgram.getId());
95         return new PreviewProgramContent.Builder()
96                 .setId(recordedProgram.getId())
97                 .setPreviewChannelId(previewChannelId)
98                 .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
99                 .setTitle(recordedProgram.getTitle())
100                 .setDescription(channelDisplayName != null ? channelDisplayName : "")
101                 .setPosterArtUri(Uri.parse(recordedProgram.getPosterArtUri()))
102                 .setIntentUri(recordedProgramUri)
103                 .setPreviewVideoUri(
104                         PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
105                                 recordedProgramUri,
106                                 Pair.create(PARAM_INPUT, recordedProgram.getInputId())))
107                 .build();
108     }
109 
PreviewProgramContent()110     private PreviewProgramContent() {}
111 
112     @SuppressWarnings("ReferenceEquality")
copyFrom(PreviewProgramContent other)113     public void copyFrom(PreviewProgramContent other) {
114         if (this == other) {
115             return;
116         }
117         mId = other.mId;
118         mPreviewChannelId = other.mPreviewChannelId;
119         mType = other.mType;
120         mLive = other.mLive;
121         mTitle = other.mTitle;
122         mDescription = other.mDescription;
123         mPosterArtUri = other.mPosterArtUri;
124         mIntentUri = other.mIntentUri;
125         mPreviewVideoUri = other.mPreviewVideoUri;
126     }
127 
128     /**
129      * Returns the id, which is an identification. It usually comes from the original data which
130      * create the {@PreviewProgramContent}.
131      */
getId()132     public long getId() {
133         return mId;
134     }
135 
136     /** Returns the preview channel id which the preview program belongs to. */
getPreviewChannelId()137     public long getPreviewChannelId() {
138         return mPreviewChannelId;
139     }
140 
141     /** Returns the type of the preview program. */
getType()142     public int getType() {
143         return mType;
144     }
145 
146     /** Returns whether the preview program is live or not. */
getLive()147     public boolean getLive() {
148         return mLive;
149     }
150 
151     /** Returns the title of the preview program. */
getTitle()152     public String getTitle() {
153         return mTitle;
154     }
155 
156     /** Returns the description of the preview program. */
getDescription()157     public String getDescription() {
158         return mDescription;
159     }
160 
161     /** Returns the poster art uri of the preview program. */
getPosterArtUri()162     public Uri getPosterArtUri() {
163         return mPosterArtUri;
164     }
165 
166     /** Returns the intent uri of the preview program. */
getIntentUri()167     public Uri getIntentUri() {
168         return mIntentUri;
169     }
170 
171     /** Returns the preview video uri of the preview program. */
getPreviewVideoUri()172     public Uri getPreviewVideoUri() {
173         return mPreviewVideoUri;
174     }
175 
176     @Override
equals(Object other)177     public boolean equals(Object other) {
178         if (!(other instanceof PreviewProgramContent)) {
179             return false;
180         }
181         PreviewProgramContent previewProgramContent = (PreviewProgramContent) other;
182         return previewProgramContent.mId == mId
183                 && previewProgramContent.mPreviewChannelId == mPreviewChannelId
184                 && previewProgramContent.mType == mType
185                 && previewProgramContent.mLive == mLive
186                 && Objects.equals(previewProgramContent.mTitle, mTitle)
187                 && Objects.equals(previewProgramContent.mDescription, mDescription)
188                 && Objects.equals(previewProgramContent.mPosterArtUri, mPosterArtUri)
189                 && Objects.equals(previewProgramContent.mIntentUri, mIntentUri)
190                 && Objects.equals(previewProgramContent.mPreviewVideoUri, mPreviewVideoUri);
191     }
192 
193     @Override
hashCode()194     public int hashCode() {
195         return Objects.hash(
196                 mId,
197                 mPreviewChannelId,
198                 mType,
199                 mLive,
200                 mTitle,
201                 mDescription,
202                 mPosterArtUri,
203                 mIntentUri,
204                 mPreviewVideoUri);
205     }
206 
207     public static final class Builder {
208         private final PreviewProgramContent mPreviewProgramContent;
209 
Builder()210         public Builder() {
211             mPreviewProgramContent = new PreviewProgramContent();
212         }
213 
setId(long id)214         public Builder setId(long id) {
215             mPreviewProgramContent.mId = id;
216             return this;
217         }
218 
setPreviewChannelId(long previewChannelId)219         public Builder setPreviewChannelId(long previewChannelId) {
220             mPreviewProgramContent.mPreviewChannelId = previewChannelId;
221             return this;
222         }
223 
setType(int type)224         public Builder setType(int type) {
225             mPreviewProgramContent.mType = type;
226             return this;
227         }
228 
setLive(boolean live)229         public Builder setLive(boolean live) {
230             mPreviewProgramContent.mLive = live;
231             return this;
232         }
233 
setTitle(String title)234         public Builder setTitle(String title) {
235             mPreviewProgramContent.mTitle = title;
236             return this;
237         }
238 
setDescription(String description)239         public Builder setDescription(String description) {
240             mPreviewProgramContent.mDescription = description;
241             return this;
242         }
243 
setPosterArtUri(Uri posterArtUri)244         public Builder setPosterArtUri(Uri posterArtUri) {
245             mPreviewProgramContent.mPosterArtUri = posterArtUri;
246             return this;
247         }
248 
setIntentUri(Uri intentUri)249         public Builder setIntentUri(Uri intentUri) {
250             mPreviewProgramContent.mIntentUri = intentUri;
251             return this;
252         }
253 
setPreviewVideoUri(Uri previewVideoUri)254         public Builder setPreviewVideoUri(Uri previewVideoUri) {
255             mPreviewProgramContent.mPreviewVideoUri = previewVideoUri;
256             return this;
257         }
258 
build()259         public PreviewProgramContent build() {
260             PreviewProgramContent previewProgramContent = new PreviewProgramContent();
261             previewProgramContent.copyFrom(mPreviewProgramContent);
262             return previewProgramContent;
263         }
264     }
265 }
266