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.dvr; 18 19 import android.annotation.TargetApi; 20 import android.content.Context; 21 import android.os.Build; 22 import android.support.annotation.MainThread; 23 import android.util.ArraySet; 24 import android.util.Log; 25 26 import com.android.tv.common.SoftPreconditions; 27 import com.android.tv.common.feature.CommonFeatures; 28 import com.android.tv.common.recording.RecordedProgram; 29 import com.android.tv.util.Clock; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 import java.util.Set; 34 35 /** 36 * Base implementation of @{link DataManagerInternal}. 37 */ 38 @MainThread 39 @TargetApi(Build.VERSION_CODES.N) 40 public abstract class BaseDvrDataManager implements WritableDvrDataManager { 41 private final static String TAG = "BaseDvrDataManager"; 42 private final static boolean DEBUG = false; 43 protected final Clock mClock; 44 45 private final Set<ScheduledRecordingListener> mScheduledRecordingListeners = new ArraySet<>(); 46 private final Set<RecordedProgramListener> mRecordedProgramListeners = new ArraySet<>(); 47 BaseDvrDataManager(Context context, Clock clock)48 BaseDvrDataManager(Context context, Clock clock) { 49 SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG); 50 mClock = clock; 51 } 52 53 @Override addScheduledRecordingListener(ScheduledRecordingListener listener)54 public final void addScheduledRecordingListener(ScheduledRecordingListener listener) { 55 mScheduledRecordingListeners.add(listener); 56 } 57 58 @Override removeScheduledRecordingListener(ScheduledRecordingListener listener)59 public final void removeScheduledRecordingListener(ScheduledRecordingListener listener) { 60 mScheduledRecordingListeners.remove(listener); 61 } 62 63 @Override addRecordedProgramListener(RecordedProgramListener listener)64 public final void addRecordedProgramListener(RecordedProgramListener listener) { 65 mRecordedProgramListeners.add(listener); 66 } 67 68 @Override removeRecordedProgramListener(RecordedProgramListener listener)69 public final void removeRecordedProgramListener(RecordedProgramListener listener) { 70 mRecordedProgramListeners.remove(listener); 71 } 72 73 /** 74 * Calls {@link RecordedProgramListener#onRecordedProgramAdded(RecordedProgram)} 75 * for each listener. 76 */ notifyRecordedProgramAdded(RecordedProgram recordedProgram)77 protected final void notifyRecordedProgramAdded(RecordedProgram recordedProgram) { 78 for (RecordedProgramListener l : mRecordedProgramListeners) { 79 if (DEBUG) Log.d(TAG, "notify " + l + "added " + recordedProgram); 80 l.onRecordedProgramAdded(recordedProgram); 81 } 82 } 83 84 /** 85 * Calls {@link RecordedProgramListener#onRecordedProgramChanged(RecordedProgram)} 86 * for each listener. 87 */ notifyRecordedProgramChanged(RecordedProgram recordedProgram)88 protected final void notifyRecordedProgramChanged(RecordedProgram recordedProgram) { 89 for (RecordedProgramListener l : mRecordedProgramListeners) { 90 if (DEBUG) Log.d(TAG, "notify " + l + "changed " + recordedProgram); 91 l.onRecordedProgramChanged(recordedProgram); 92 } 93 } 94 95 /** 96 * Calls {@link RecordedProgramListener#onRecordedProgramRemoved(RecordedProgram)} 97 * for each listener. 98 */ notifyRecordedProgramRemoved(RecordedProgram recordedProgram)99 protected final void notifyRecordedProgramRemoved(RecordedProgram recordedProgram) { 100 for (RecordedProgramListener l : mRecordedProgramListeners) { 101 if (DEBUG) Log.d(TAG, "notify " + l + "removed " + recordedProgram); 102 l.onRecordedProgramRemoved(recordedProgram); 103 } 104 } 105 106 /** 107 * Calls {@link ScheduledRecordingListener#onScheduledRecordingAdded(ScheduledRecording)} 108 * for each listener. 109 */ notifyScheduledRecordingAdded(ScheduledRecording scheduledRecording)110 protected final void notifyScheduledRecordingAdded(ScheduledRecording scheduledRecording) { 111 for (ScheduledRecordingListener l : mScheduledRecordingListeners) { 112 if (DEBUG) Log.d(TAG, "notify " + l + "added " + scheduledRecording); 113 l.onScheduledRecordingAdded(scheduledRecording); 114 } 115 } 116 117 /** 118 * Calls {@link ScheduledRecordingListener#onScheduledRecordingRemoved(ScheduledRecording)} 119 * for each listener. 120 */ notifyScheduledRecordingRemoved(ScheduledRecording scheduledRecording)121 protected final void notifyScheduledRecordingRemoved(ScheduledRecording scheduledRecording) { 122 for (ScheduledRecordingListener l : mScheduledRecordingListeners) { 123 if (DEBUG) { 124 Log.d(TAG, "notify " + l + "removed " + scheduledRecording); 125 } 126 l.onScheduledRecordingRemoved(scheduledRecording); 127 } 128 } 129 130 /** 131 * Calls 132 * {@link ScheduledRecordingListener#onScheduledRecordingStatusChanged(ScheduledRecording)} 133 * for each listener. 134 */ notifyScheduledRecordingStatusChanged( ScheduledRecording scheduledRecording)135 protected final void notifyScheduledRecordingStatusChanged( 136 ScheduledRecording scheduledRecording) { 137 for (ScheduledRecordingListener l : mScheduledRecordingListeners) { 138 if (DEBUG) Log.d(TAG, "notify " + l + "changed " + scheduledRecording); 139 l.onScheduledRecordingStatusChanged(scheduledRecording); 140 } 141 } 142 143 /** 144 * Returns a new list with only {@link ScheduledRecording} with a {@link 145 * ScheduledRecording#getEndTimeMs() endTime} after now. 146 */ filterEndTimeIsPast(List<ScheduledRecording> originals)147 private List<ScheduledRecording> filterEndTimeIsPast(List<ScheduledRecording> originals) { 148 List<ScheduledRecording> results = new ArrayList<>(originals.size()); 149 for (ScheduledRecording r : originals) { 150 if (r.getEndTimeMs() > mClock.currentTimeMillis()) { 151 results.add(r); 152 } 153 } 154 return results; 155 } 156 157 @Override getStartedRecordings()158 public List<ScheduledRecording> getStartedRecordings() { 159 return filterEndTimeIsPast( 160 getRecordingsWithState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS)); 161 } 162 163 @Override getNonStartedScheduledRecordings()164 public List<ScheduledRecording> getNonStartedScheduledRecordings() { 165 return filterEndTimeIsPast( 166 getRecordingsWithState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)); 167 } 168 getRecordingsWithState(int state)169 protected abstract List<ScheduledRecording> getRecordingsWithState(int state); 170 } 171