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