1 /*
2  * Copyright (C) 2016 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.dvr.ui.list;
18 
19 import android.content.Context;
20 import android.support.annotation.Nullable;
21 
22 import com.android.tv.common.SoftPreconditions;
23 import com.android.tv.dvr.ScheduledRecording;
24 
25 /**
26  * A class for schedule recording row.
27  */
28 public class ScheduleRow {
29     private final SchedulesHeaderRow mHeaderRow;
30     @Nullable private ScheduledRecording mSchedule;
31     private boolean mStopRecordingRequested;
32     private boolean mStartRecordingRequested;
33 
ScheduleRow(@ullable ScheduledRecording recording, SchedulesHeaderRow headerRow)34     public ScheduleRow(@Nullable ScheduledRecording recording, SchedulesHeaderRow headerRow) {
35         mSchedule = recording;
36         mHeaderRow = headerRow;
37     }
38 
39     /**
40      * Gets which {@link SchedulesHeaderRow} this schedule row belongs to.
41      */
getHeaderRow()42     public SchedulesHeaderRow getHeaderRow() {
43         return mHeaderRow;
44     }
45 
46     /**
47      * Returns the recording schedule.
48      */
49     @Nullable
getSchedule()50     public ScheduledRecording getSchedule() {
51         return mSchedule;
52     }
53 
54     /**
55      * Checks if the stop recording has been requested or not.
56      */
isStopRecordingRequested()57     public boolean isStopRecordingRequested() {
58         return mStopRecordingRequested;
59     }
60 
61     /**
62      * Sets the flag of stop recording request.
63      */
setStopRecordingRequested(boolean stopRecordingRequested)64     public void setStopRecordingRequested(boolean stopRecordingRequested) {
65         SoftPreconditions.checkState(!mStartRecordingRequested);
66         mStopRecordingRequested = stopRecordingRequested;
67     }
68 
69     /**
70      * Checks if the start recording has been requested or not.
71      */
isStartRecordingRequested()72     public boolean isStartRecordingRequested() {
73         return mStartRecordingRequested;
74     }
75 
76     /**
77      * Sets the flag of start recording request.
78      */
setStartRecordingRequested(boolean startRecordingRequested)79     public void setStartRecordingRequested(boolean startRecordingRequested) {
80         SoftPreconditions.checkState(!mStopRecordingRequested);
81         mStartRecordingRequested = startRecordingRequested;
82     }
83 
84     /**
85      * Sets the recording schedule.
86      */
setSchedule(@ullable ScheduledRecording schedule)87     public void setSchedule(@Nullable ScheduledRecording schedule) {
88         mSchedule = schedule;
89     }
90 
91     /**
92      * Returns the channel ID.
93      */
getChannelId()94     public long getChannelId() {
95         return mSchedule != null ? mSchedule.getChannelId() : -1;
96     }
97 
98     /**
99      * Returns the start time.
100      */
getStartTimeMs()101     public long getStartTimeMs() {
102         return mSchedule != null ? mSchedule.getStartTimeMs() : -1;
103     }
104 
105     /**
106      * Returns the end time.
107      */
getEndTimeMs()108     public long getEndTimeMs() {
109         return mSchedule != null ? mSchedule.getEndTimeMs() : -1;
110     }
111 
112     /**
113      * Returns the duration.
114      */
getDuration()115     public final long getDuration() {
116         return getEndTimeMs() - getStartTimeMs();
117     }
118 
119     /**
120      * Checks if the program is on air.
121      */
isOnAir()122     public final boolean isOnAir() {
123         long currentTimeMs = System.currentTimeMillis();
124         return getStartTimeMs() <= currentTimeMs && getEndTimeMs() > currentTimeMs;
125     }
126 
127     /**
128      * Checks if the schedule is not started.
129      */
isRecordingNotStarted()130     public final boolean isRecordingNotStarted() {
131         return mSchedule != null
132                 && mSchedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED;
133     }
134 
135     /**
136      * Checks if the schedule is in progress.
137      */
isRecordingInProgress()138     public final boolean isRecordingInProgress() {
139         return mSchedule != null
140                 && mSchedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS;
141     }
142 
143     /**
144      * Checks if the schedule has been canceled or not.
145      */
isScheduleCanceled()146     public final boolean isScheduleCanceled() {
147         return mSchedule != null
148                 && mSchedule.getState() == ScheduledRecording.STATE_RECORDING_CANCELED;
149     }
150 
isRecordingFinished()151     public boolean isRecordingFinished() {
152         return mSchedule != null
153                 && (mSchedule.getState() == ScheduledRecording.STATE_RECORDING_FAILED
154                 || mSchedule.getState() == ScheduledRecording.STATE_RECORDING_CLIPPED
155                 || mSchedule.getState() == ScheduledRecording.STATE_RECORDING_FINISHED);
156     }
157 
158     /**
159      * Creates and returns the new schedule with the existing information.
160      */
createNewScheduleBuilder()161     public ScheduledRecording.Builder createNewScheduleBuilder() {
162         return mSchedule != null ? ScheduledRecording.buildFrom(mSchedule) : null;
163     }
164 
165     /**
166      * Returns the program title with episode number.
167      */
getProgramTitleWithEpisodeNumber(Context context)168     public String getProgramTitleWithEpisodeNumber(Context context) {
169         return mSchedule != null ? mSchedule.getProgramTitleWithEpisodeNumber(context) : null;
170     }
171 
172     /**
173      * Returns the program title including the season/episode number.
174      */
getEpisodeDisplayTitle(Context context)175     public String getEpisodeDisplayTitle(Context context) {
176         return mSchedule != null ? mSchedule.getEpisodeDisplayTitle(context) : null;
177     }
178 
179     @Override
toString()180     public String toString() {
181         return getClass().getSimpleName()
182                 + "(schedule=" + mSchedule
183                 + ",stopRecordingRequested=" + mStopRecordingRequested
184                 + ",startRecordingRequested=" + mStartRecordingRequested
185                 + ")";
186     }
187 
188     /**
189      * Checks if the {@code schedule} is for the program or channel.
190      */
matchSchedule(ScheduledRecording schedule)191     public boolean matchSchedule(ScheduledRecording schedule) {
192         if (mSchedule == null) {
193             return false;
194         }
195         if (mSchedule.getType() == ScheduledRecording.TYPE_TIMED) {
196             return mSchedule.getChannelId() == schedule.getChannelId()
197                     && mSchedule.getStartTimeMs() == schedule.getStartTimeMs()
198                     && mSchedule.getEndTimeMs() == schedule.getEndTimeMs();
199         } else {
200             return mSchedule.getProgramId() == schedule.getProgramId();
201         }
202     }
203 }
204