| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.tv.dvr; |
| |
| import android.content.Context; |
| import android.support.annotation.NonNull; |
| import android.support.annotation.Nullable; |
| import android.text.TextUtils; |
| import android.util.Log; |
| import android.util.Range; |
| |
| import com.android.tv.common.SoftPreconditions; |
| import com.android.tv.dvr.ScheduledRecording.RecordingState; |
| import com.android.tv.util.Clock; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.atomic.AtomicLong; |
| |
| /** |
| * A DVR Data manager that stores values in memory suitable for testing. |
| */ |
| final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager { |
| private final static String TAG = "DvrDataManagerInMemory"; |
| private final AtomicLong mNextId = new AtomicLong(1); |
| private final Map<Long, ScheduledRecording> mScheduledRecordings = new HashMap<>(); |
| private final Map<Long, RecordedProgram> mRecordedPrograms = new HashMap<>(); |
| private final Map<Long, SeriesRecording> mSeriesRecordings = new HashMap<>(); |
| |
| public DvrDataManagerInMemoryImpl(Context context, Clock clock) { |
| super(context, clock); |
| } |
| |
| @Override |
| public boolean isInitialized() { |
| return true; |
| } |
| |
| @Override |
| public boolean isDvrScheduleLoadFinished() { |
| return true; |
| } |
| |
| @Override |
| public boolean isRecordedProgramLoadFinished() { |
| return true; |
| } |
| |
| private List<ScheduledRecording> getScheduledRecordingsPrograms() { |
| return new ArrayList<>(mScheduledRecordings.values()); |
| } |
| |
| @Override |
| public List<RecordedProgram> getRecordedPrograms() { |
| return new ArrayList<>(mRecordedPrograms.values()); |
| } |
| |
| @Override |
| public List<ScheduledRecording> getAllScheduledRecordings() { |
| return new ArrayList<>(mScheduledRecordings.values()); |
| } |
| |
| public List<SeriesRecording> getSeriesRecordings() { |
| return new ArrayList<>(mSeriesRecordings.values()); |
| } |
| |
| @Override |
| public List<SeriesRecording> getSeriesRecordings(String inputId) { |
| List<SeriesRecording> result = new ArrayList<>(); |
| for (SeriesRecording r : mSeriesRecordings.values()) { |
| if (TextUtils.equals(r.getInputId(), inputId)) { |
| result.add(r); |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public long getNextScheduledStartTimeAfter(long startTime) { |
| |
| List<ScheduledRecording> temp = getNonStartedScheduledRecordings(); |
| Collections.sort(temp, ScheduledRecording.START_TIME_COMPARATOR); |
| for (ScheduledRecording r : temp) { |
| if (r.getStartTimeMs() > startTime) { |
| return r.getStartTimeMs(); |
| } |
| } |
| return DvrDataManager.NEXT_START_TIME_NOT_FOUND; |
| } |
| |
| @Override |
| public List<ScheduledRecording> getScheduledRecordings(Range<Long> period, |
| @RecordingState int state) { |
| List<ScheduledRecording> temp = getScheduledRecordingsPrograms(); |
| List<ScheduledRecording> result = new ArrayList<>(); |
| for (ScheduledRecording r : temp) { |
| if (r.isOverLapping(period) && r.getState() == state) { |
| result.add(r); |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public List<ScheduledRecording> getScheduledRecordings(long seriesRecordingId) { |
| List<ScheduledRecording> result = new ArrayList<>(); |
| for (ScheduledRecording r : mScheduledRecordings.values()) { |
| if (r.getSeriesRecordingId() == seriesRecordingId) { |
| result.add(r); |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public List<ScheduledRecording> getScheduledRecordings(String inputId) { |
| List<ScheduledRecording> result = new ArrayList<>(); |
| for (ScheduledRecording r : mScheduledRecordings.values()) { |
| if (TextUtils.equals(r.getInputId(), inputId)) { |
| result.add(r); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Add a new scheduled recording. |
| */ |
| @Override |
| public void addScheduledRecording(ScheduledRecording... scheduledRecordings) { |
| for (ScheduledRecording r : scheduledRecordings) { |
| addScheduledRecordingInternal(r); |
| } |
| } |
| |
| |
| public void addRecordedProgram(RecordedProgram recordedProgram) { |
| addRecordedProgramInternal(recordedProgram); |
| } |
| |
| public void updateRecordedProgram(RecordedProgram r) { |
| long id = r.getId(); |
| if (mRecordedPrograms.containsKey(id)) { |
| mRecordedPrograms.put(id, r); |
| notifyRecordedProgramsChanged(r); |
| } else { |
| throw new IllegalArgumentException("Recording not found:" + r); |
| } |
| } |
| |
| public void removeRecordedProgram(RecordedProgram scheduledRecording) { |
| mRecordedPrograms.remove(scheduledRecording.getId()); |
| notifyRecordedProgramsRemoved(scheduledRecording); |
| } |
| |
| |
| public ScheduledRecording addScheduledRecordingInternal(ScheduledRecording scheduledRecording) { |
| SoftPreconditions |
| .checkState(scheduledRecording.getId() == ScheduledRecording.ID_NOT_SET, TAG, |
| "expected id of " + ScheduledRecording.ID_NOT_SET + " but was " |
| + scheduledRecording); |
| scheduledRecording = ScheduledRecording.buildFrom(scheduledRecording) |
| .setId(mNextId.incrementAndGet()) |
| .build(); |
| mScheduledRecordings.put(scheduledRecording.getId(), scheduledRecording); |
| notifyScheduledRecordingAdded(scheduledRecording); |
| return scheduledRecording; |
| } |
| |
| public RecordedProgram addRecordedProgramInternal(RecordedProgram recordedProgram) { |
| SoftPreconditions.checkState(recordedProgram.getId() == RecordedProgram.ID_NOT_SET, TAG, |
| "expected id of " + RecordedProgram.ID_NOT_SET + " but was " + recordedProgram); |
| recordedProgram = RecordedProgram.buildFrom(recordedProgram) |
| .setId(mNextId.incrementAndGet()) |
| .build(); |
| mRecordedPrograms.put(recordedProgram.getId(), recordedProgram); |
| notifyRecordedProgramsAdded(recordedProgram); |
| return recordedProgram; |
| } |
| |
| @Override |
| public void addSeriesRecording(SeriesRecording... seriesRecordings) { |
| for (SeriesRecording r : seriesRecordings) { |
| mSeriesRecordings.put(r.getId(), r); |
| } |
| notifySeriesRecordingAdded(seriesRecordings); |
| } |
| |
| @Override |
| public void removeScheduledRecording(ScheduledRecording... scheduledRecordings) { |
| for (ScheduledRecording r : scheduledRecordings) { |
| mScheduledRecordings.remove(r.getId()); |
| } |
| notifyScheduledRecordingRemoved(scheduledRecordings); |
| } |
| |
| @Override |
| public void removeScheduledRecording(boolean forceRemove, ScheduledRecording... schedule) { |
| removeScheduledRecording(schedule); |
| } |
| |
| @Override |
| public void removeSeriesRecording(SeriesRecording... seriesRecordings) { |
| for (SeriesRecording r : seriesRecordings) { |
| mSeriesRecordings.remove(r.getId()); |
| } |
| notifySeriesRecordingRemoved(seriesRecordings); |
| } |
| |
| @Override |
| public void updateScheduledRecording(ScheduledRecording... scheduledRecordings) { |
| for (ScheduledRecording r : scheduledRecordings) { |
| long id = r.getId(); |
| if (mScheduledRecordings.containsKey(id)) { |
| mScheduledRecordings.put(id, r); |
| } else { |
| Log.d(TAG, "Recording not found:" + r); |
| } |
| } |
| notifyScheduledRecordingStatusChanged(scheduledRecordings); |
| } |
| |
| @Override |
| public void updateSeriesRecording(SeriesRecording... seriesRecordings) { |
| for (SeriesRecording r : seriesRecordings) { |
| long id = r.getId(); |
| if (mSeriesRecordings.containsKey(id)) { |
| mSeriesRecordings.put(id, r); |
| } else { |
| throw new IllegalArgumentException("Recording not found:" + r); |
| } |
| } |
| notifySeriesRecordingChanged(seriesRecordings); |
| } |
| |
| @Nullable |
| @Override |
| public ScheduledRecording getScheduledRecording(long id) { |
| return mScheduledRecordings.get(id); |
| } |
| |
| @Nullable |
| @Override |
| public ScheduledRecording getScheduledRecordingForProgramId(long programId) { |
| for (ScheduledRecording r : mScheduledRecordings.values()) { |
| if (r.getProgramId() == programId) { |
| return r; |
| } |
| } |
| return null; |
| } |
| |
| @Nullable |
| @Override |
| public SeriesRecording getSeriesRecording(long seriesRecordingId) { |
| return mSeriesRecordings.get(seriesRecordingId); |
| } |
| |
| @Nullable |
| @Override |
| public SeriesRecording getSeriesRecording(String seriesId) { |
| for (SeriesRecording r : mSeriesRecordings.values()) { |
| if (r.getSeriesId().equals(seriesId)) { |
| return r; |
| } |
| } |
| return null; |
| } |
| |
| @Nullable |
| @Override |
| public RecordedProgram getRecordedProgram(long recordingId) { |
| return mRecordedPrograms.get(recordingId); |
| } |
| |
| @Override |
| @NonNull |
| protected List<ScheduledRecording> getRecordingsWithState(int... states) { |
| ArrayList<ScheduledRecording> result = new ArrayList<>(); |
| for (ScheduledRecording r : mScheduledRecordings.values()) { |
| for (int state : states) { |
| if (r.getState() == state) { |
| result.add(r); |
| break; |
| } |
| } |
| } |
| return result; |
| } |
| } |