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; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.media.tv.TvContract; 22 import android.media.tv.TvInputManager; 23 import android.text.TextUtils; 24 import android.view.ViewGroup; 25 26 import com.android.tv.ApplicationSingletons; 27 import com.android.tv.R; 28 import com.android.tv.TvApplication; 29 import com.android.tv.data.Channel; 30 import com.android.tv.data.ChannelDataManager; 31 import com.android.tv.dvr.DvrDataManager; 32 import com.android.tv.dvr.DvrDataManager.RecordedProgramListener; 33 import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener; 34 import com.android.tv.dvr.DvrManager; 35 import com.android.tv.dvr.DvrWatchedPositionManager; 36 import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener; 37 import com.android.tv.dvr.RecordedProgram; 38 import com.android.tv.dvr.ScheduledRecording; 39 import com.android.tv.dvr.SeriesRecording; 40 41 import java.util.List; 42 43 /** 44 * Presents a {@link SeriesRecording} in {@link DvrBrowseFragment}. 45 */ 46 public class SeriesRecordingPresenter extends DvrItemPresenter { 47 private final ChannelDataManager mChannelDataManager; 48 private final DvrDataManager mDvrDataManager; 49 private final DvrManager mDvrManager; 50 private final DvrWatchedPositionManager mWatchedPositionManager; 51 52 private static final class SeriesRecordingViewHolder extends ViewHolder implements 53 WatchedPositionChangedListener, ScheduledRecordingListener, RecordedProgramListener { 54 private SeriesRecording mSeriesRecording; 55 private RecordingCardView mCardView; 56 private DvrDataManager mDvrDataManager; 57 private DvrManager mDvrManager; 58 private DvrWatchedPositionManager mWatchedPositionManager; 59 60 SeriesRecordingViewHolder(RecordingCardView view, DvrDataManager dvrDataManager, 61 DvrManager dvrManager, DvrWatchedPositionManager watchedPositionManager) { 62 super(view); 63 mCardView = view; 64 mDvrDataManager = dvrDataManager; 65 mDvrManager = dvrManager; 66 mWatchedPositionManager = watchedPositionManager; 67 } 68 69 @Override 70 public void onWatchedPositionChanged(long recordedProgramId, long positionMs) { 71 if (positionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) { 72 mWatchedPositionManager.removeListener(this, recordedProgramId); 73 updateCardViewContent(); 74 } 75 } 76 77 @Override 78 public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) { 79 for (ScheduledRecording scheduledRecording : scheduledRecordings) { 80 if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) { 81 updateCardViewContent(); 82 return; 83 } 84 } 85 } 86 87 @Override 88 public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) { 89 for (ScheduledRecording scheduledRecording : scheduledRecordings) { 90 if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) { 91 updateCardViewContent(); 92 return; 93 } 94 } 95 } 96 97 @Override 98 public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) { 99 boolean needToUpdateCardView = false; 100 for (RecordedProgram recordedProgram : recordedPrograms) { 101 if (TextUtils.equals(recordedProgram.getSeriesId(), 102 mSeriesRecording.getSeriesId())) { 103 mDvrDataManager.removeScheduledRecordingListener(this); 104 mWatchedPositionManager.addListener(this, recordedProgram.getId()); 105 needToUpdateCardView = true; 106 } 107 } 108 if (needToUpdateCardView) { 109 updateCardViewContent(); 110 } 111 } 112 113 @Override 114 public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) { 115 boolean needToUpdateCardView = false; 116 for (RecordedProgram recordedProgram : recordedPrograms) { 117 if (TextUtils.equals(recordedProgram.getSeriesId(), 118 mSeriesRecording.getSeriesId())) { 119 if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId()) 120 == TvInputManager.TIME_SHIFT_INVALID_TIME) { 121 mWatchedPositionManager.removeListener(this, recordedProgram.getId()); 122 } 123 needToUpdateCardView = true; 124 } 125 } 126 if (needToUpdateCardView) { 127 updateCardViewContent(); 128 } 129 } 130 131 @Override 132 public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) { 133 // Do nothing 134 } 135 136 @Override 137 public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) { 138 // Do nothing 139 } 140 141 public void onBound(SeriesRecording seriesRecording) { 142 mSeriesRecording = seriesRecording; 143 mDvrDataManager.addScheduledRecordingListener(this); 144 mDvrDataManager.addRecordedProgramListener(this); 145 for (RecordedProgram recordedProgram : 146 mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId())) { 147 if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId()) 148 == TvInputManager.TIME_SHIFT_INVALID_TIME) { 149 mWatchedPositionManager.addListener(this, recordedProgram.getId()); 150 } 151 } 152 updateCardViewContent(); 153 } 154 155 public void onUnbound() { 156 mDvrDataManager.removeScheduledRecordingListener(this); 157 mDvrDataManager.removeRecordedProgramListener(this); 158 mWatchedPositionManager.removeListener(this); 159 } 160 161 private void updateCardViewContent() { 162 int count = 0; 163 int quantityStringID; 164 List<RecordedProgram> recordedPrograms = 165 mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId()); 166 if (recordedPrograms.size() == 0) { 167 count = mDvrManager.getAvailableScheduledRecording(mSeriesRecording.getId()).size(); 168 quantityStringID = R.plurals.dvr_count_scheduled_recordings; 169 } else { 170 for (RecordedProgram recordedProgram : recordedPrograms) { 171 if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId()) 172 == TvInputManager.TIME_SHIFT_INVALID_TIME) { 173 count++; 174 } 175 } 176 if (count == 0) { 177 count = recordedPrograms.size(); 178 quantityStringID = R.plurals.dvr_count_recordings; 179 } else { 180 quantityStringID = R.plurals.dvr_count_new_recordings; 181 } 182 } 183 mCardView.setContent(mCardView.getResources() 184 .getQuantityString(quantityStringID, count, count), null); 185 } 186 } 187 188 public SeriesRecordingPresenter(Context context) { 189 ApplicationSingletons singletons = TvApplication.getSingletons(context); 190 mChannelDataManager = singletons.getChannelDataManager(); 191 mDvrDataManager = singletons.getDvrDataManager(); 192 mDvrManager = singletons.getDvrManager(); 193 mWatchedPositionManager = singletons.getDvrWatchedPositionManager(); 194 } 195 196 @Override 197 public ViewHolder onCreateViewHolder(ViewGroup parent) { 198 Context context = parent.getContext(); 199 RecordingCardView view = new RecordingCardView(context); 200 return new SeriesRecordingViewHolder(view, mDvrDataManager, mDvrManager, 201 mWatchedPositionManager); 202 } 203 204 @Override 205 public void onBindViewHolder(ViewHolder baseHolder, Object o) { 206 final SeriesRecordingViewHolder viewHolder = (SeriesRecordingViewHolder) baseHolder; 207 final SeriesRecording seriesRecording = (SeriesRecording) o; 208 final RecordingCardView cardView = (RecordingCardView) viewHolder.view; 209 viewHolder.onBound(seriesRecording); 210 setTitleAndImage(cardView, seriesRecording); 211 super.onBindViewHolder(baseHolder, o); 212 } 213 214 @Override 215 public void onUnbindViewHolder(ViewHolder viewHolder) { 216 ((RecordingCardView) viewHolder.view).reset(); 217 ((SeriesRecordingViewHolder) viewHolder).onUnbound(); 218 super.onUnbindViewHolder(viewHolder); 219 } 220 221 private void setTitleAndImage(RecordingCardView cardView, SeriesRecording recording) { 222 cardView.setTitle(recording.getTitle()); 223 if (recording.getPosterUri() != null) { 224 cardView.setImageUri(recording.getPosterUri(), false); 225 } else { 226 Channel channel = mChannelDataManager.getChannel(recording.getChannelId()); 227 String imageUri = null; 228 if (channel != null) { 229 imageUri = TvContract.buildChannelLogoUri(channel.getId()).toString(); 230 } 231 cardView.setImageUri(imageUri, true); 232 } 233 } 234 } 235