diff options
Diffstat (limited to 'src/com/android/tv/dvr/DvrScheduleManager.java')
-rw-r--r-- | src/com/android/tv/dvr/DvrScheduleManager.java | 596 |
1 files changed, 295 insertions, 301 deletions
diff --git a/src/com/android/tv/dvr/DvrScheduleManager.java b/src/com/android/tv/dvr/DvrScheduleManager.java index b72117aa..d5126b12 100644 --- a/src/com/android/tv/dvr/DvrScheduleManager.java +++ b/src/com/android/tv/dvr/DvrScheduleManager.java @@ -25,21 +25,18 @@ import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.util.ArraySet; import android.util.Range; - -import com.android.tv.ApplicationSingletons; -import com.android.tv.TvApplication; +import com.android.tv.TvSingletons; import com.android.tv.common.SoftPreconditions; -import com.android.tv.data.Channel; import com.android.tv.data.ChannelDataManager; import com.android.tv.data.Program; +import com.android.tv.data.api.Channel; import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener; import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener; -import com.android.tv.dvr.recorder.InputTaskScheduler; -import com.android.tv.util.CompositeComparator; import com.android.tv.dvr.data.ScheduledRecording; import com.android.tv.dvr.data.SeriesRecording; +import com.android.tv.dvr.recorder.InputTaskScheduler; +import com.android.tv.util.CompositeComparator; import com.android.tv.util.Utils; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -50,21 +47,16 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; -/** - * A class to manage the schedules. - */ +/** A class to manage the schedules. */ @TargetApi(Build.VERSION_CODES.N) @MainThread +@SuppressWarnings("AndroidApiChecker") // TODO(b/32513850) remove when error prone is updated public class DvrScheduleManager { private static final String TAG = "DvrScheduleManager"; - /** - * The default priority of scheduled recording. - */ + /** The default priority of scheduled recording. */ public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1; - /** - * The default priority of series recording. - */ + /** The default priority of series recording. */ public static final long DEFAULT_SERIES_PRIORITY = DEFAULT_PRIORITY >> 1; // The new priority will have the offset from the existing one. private static final long PRIORITY_OFFSET = 1024; @@ -102,9 +94,9 @@ public class DvrScheduleManager { public DvrScheduleManager(Context context) { mContext = context; - ApplicationSingletons appSingletons = TvApplication.getSingletons(context); - mDataManager = (DvrDataManagerImpl) appSingletons.getDvrDataManager(); - mChannelDataManager = appSingletons.getChannelDataManager(); + TvSingletons tvSingletons = TvSingletons.getSingletons(context); + mDataManager = (DvrDataManagerImpl) tvSingletons.getDvrDataManager(); + mChannelDataManager = tvSingletons.getChannelDataManager(); if (mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished()) { buildData(); } else { @@ -119,146 +111,151 @@ public class DvrScheduleManager { } }); } - ScheduledRecordingListener scheduledRecordingListener = new ScheduledRecordingListener() { - @Override - public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) { - if (!mInitialized) { - return; - } - for (ScheduledRecording schedule : scheduledRecordings) { - if (!schedule.isNotStarted() && !schedule.isInProgress()) { - continue; - } - TvInputInfo input = Utils - .getTvInputInfoForInputId(mContext, schedule.getInputId()); - if (!SoftPreconditions.checkArgument(input != null, TAG, - "Input was removed for : " + schedule)) { - // Input removed. - mInputScheduleMap.remove(schedule.getInputId()); - mInputConflictInfoMap.remove(schedule.getInputId()); - continue; - } - String inputId = input.getId(); - List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); - if (schedules == null) { - schedules = new ArrayList<>(); - mInputScheduleMap.put(inputId, schedules); + ScheduledRecordingListener scheduledRecordingListener = + new ScheduledRecordingListener() { + @Override + public void onScheduledRecordingAdded( + ScheduledRecording... scheduledRecordings) { + if (!mInitialized) { + return; + } + for (ScheduledRecording schedule : scheduledRecordings) { + if (!schedule.isNotStarted() && !schedule.isInProgress()) { + continue; + } + TvInputInfo input = + Utils.getTvInputInfoForInputId(mContext, schedule.getInputId()); + if (!SoftPreconditions.checkArgument( + input != null, TAG, "Input was removed for : %s", schedule)) { + // Input removed. + mInputScheduleMap.remove(schedule.getInputId()); + mInputConflictInfoMap.remove(schedule.getInputId()); + continue; + } + String inputId = input.getId(); + List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); + if (schedules == null) { + schedules = new ArrayList<>(); + mInputScheduleMap.put(inputId, schedules); + } + schedules.add(schedule); + } + onSchedulesChanged(); + notifyScheduledRecordingAdded(scheduledRecordings); } - schedules.add(schedule); - } - onSchedulesChanged(); - notifyScheduledRecordingAdded(scheduledRecordings); - } - @Override - public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) { - if (!mInitialized) { - return; - } - for (ScheduledRecording schedule : scheduledRecordings) { - TvInputInfo input = Utils - .getTvInputInfoForInputId(mContext, schedule.getInputId()); - if (input == null) { - // Input removed. - mInputScheduleMap.remove(schedule.getInputId()); - mInputConflictInfoMap.remove(schedule.getInputId()); - continue; - } - String inputId = input.getId(); - List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); - if (schedules != null) { - schedules.remove(schedule); - if (schedules.isEmpty()) { - mInputScheduleMap.remove(inputId); + @Override + public void onScheduledRecordingRemoved( + ScheduledRecording... scheduledRecordings) { + if (!mInitialized) { + return; } - } - Map<Long, ConflictInfo> conflictInfo = mInputConflictInfoMap.get(inputId); - if (conflictInfo != null) { - conflictInfo.remove(schedule.getId()); - if (conflictInfo.isEmpty()) { - mInputConflictInfoMap.remove(inputId); + for (ScheduledRecording schedule : scheduledRecordings) { + TvInputInfo input = + Utils.getTvInputInfoForInputId(mContext, schedule.getInputId()); + if (input == null) { + // Input removed. + mInputScheduleMap.remove(schedule.getInputId()); + mInputConflictInfoMap.remove(schedule.getInputId()); + continue; + } + String inputId = input.getId(); + List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); + if (schedules != null) { + schedules.remove(schedule); + if (schedules.isEmpty()) { + mInputScheduleMap.remove(inputId); + } + } + Map<Long, ConflictInfo> conflictInfo = + mInputConflictInfoMap.get(inputId); + if (conflictInfo != null) { + conflictInfo.remove(schedule.getId()); + if (conflictInfo.isEmpty()) { + mInputConflictInfoMap.remove(inputId); + } + } } + onSchedulesChanged(); + notifyScheduledRecordingRemoved(scheduledRecordings); } - } - onSchedulesChanged(); - notifyScheduledRecordingRemoved(scheduledRecordings); - } - @Override - public void onScheduledRecordingStatusChanged( - ScheduledRecording... scheduledRecordings) { - if (!mInitialized) { - return; - } - for (ScheduledRecording schedule : scheduledRecordings) { - TvInputInfo input = Utils - .getTvInputInfoForInputId(mContext, schedule.getInputId()); - if (!SoftPreconditions.checkArgument(input != null, TAG, - "Input was removed for : " + schedule)) { - // Input removed. - mInputScheduleMap.remove(schedule.getInputId()); - mInputConflictInfoMap.remove(schedule.getInputId()); - continue; - } - String inputId = input.getId(); - List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); - if (schedules == null) { - schedules = new ArrayList<>(); - mInputScheduleMap.put(inputId, schedules); - } - // Compare ID because ScheduledRecording.equals() doesn't work if the state - // is changed. - for (Iterator<ScheduledRecording> i = schedules.iterator(); i.hasNext(); ) { - if (i.next().getId() == schedule.getId()) { - i.remove(); - break; + @Override + public void onScheduledRecordingStatusChanged( + ScheduledRecording... scheduledRecordings) { + if (!mInitialized) { + return; } - } - if (schedule.isNotStarted() || schedule.isInProgress()) { - schedules.add(schedule); - } - if (schedules.isEmpty()) { - mInputScheduleMap.remove(inputId); - } - // Update conflict list as well - Map<Long, ConflictInfo> conflictInfo = mInputConflictInfoMap.get(inputId); - if (conflictInfo != null) { - ConflictInfo oldConflictInfo = conflictInfo.get(schedule.getId()); - if (oldConflictInfo != null) { - oldConflictInfo.schedule = schedule; + for (ScheduledRecording schedule : scheduledRecordings) { + TvInputInfo input = + Utils.getTvInputInfoForInputId(mContext, schedule.getInputId()); + if (!SoftPreconditions.checkArgument( + input != null, TAG, "Input was removed for : %s", schedule)) { + // Input removed. + mInputScheduleMap.remove(schedule.getInputId()); + mInputConflictInfoMap.remove(schedule.getInputId()); + continue; + } + String inputId = input.getId(); + List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); + if (schedules == null) { + schedules = new ArrayList<>(); + mInputScheduleMap.put(inputId, schedules); + } + // Compare ID because ScheduledRecording.equals() doesn't work if the + // state + // is changed. + for (Iterator<ScheduledRecording> i = schedules.iterator(); + i.hasNext(); ) { + if (i.next().getId() == schedule.getId()) { + i.remove(); + break; + } + } + if (schedule.isNotStarted() || schedule.isInProgress()) { + schedules.add(schedule); + } + if (schedules.isEmpty()) { + mInputScheduleMap.remove(inputId); + } + // Update conflict list as well + Map<Long, ConflictInfo> conflictInfo = + mInputConflictInfoMap.get(inputId); + if (conflictInfo != null) { + ConflictInfo oldConflictInfo = conflictInfo.get(schedule.getId()); + if (oldConflictInfo != null) { + oldConflictInfo.schedule = schedule; + } + } } + onSchedulesChanged(); + notifyScheduledRecordingStatusChanged(scheduledRecordings); } - } - onSchedulesChanged(); - notifyScheduledRecordingStatusChanged(scheduledRecordings); - } - }; + }; mDataManager.addScheduledRecordingListener(scheduledRecordingListener); - ChannelDataManager.Listener channelDataManagerListener = new ChannelDataManager.Listener() { - @Override - public void onLoadFinished() { - if (mDataManager.isDvrScheduleLoadFinished() && !mInitialized) { - buildData(); - } - } + ChannelDataManager.Listener channelDataManagerListener = + new ChannelDataManager.Listener() { + @Override + public void onLoadFinished() { + if (mDataManager.isDvrScheduleLoadFinished() && !mInitialized) { + buildData(); + } + } - @Override - public void onChannelListUpdated() { - if (mDataManager.isDvrScheduleLoadFinished()) { - buildData(); - } - } + @Override + public void onChannelListUpdated() { + if (mDataManager.isDvrScheduleLoadFinished()) { + buildData(); + } + } - @Override - public void onChannelBrowsableChanged() { - } - }; + @Override + public void onChannelBrowsableChanged() {} + }; mChannelDataManager.addListener(channelDataManagerListener); } - /** - * Returns the started recordings for the given input. - */ + /** Returns the started recordings for the given input. */ private List<ScheduledRecording> getStartedRecordings(String inputId) { if (!SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet")) { return Collections.emptyList(); @@ -337,39 +334,29 @@ public class DvrScheduleManager { } } - /** - * Returns {@code true} if this class has been initialized. - */ + /** Returns {@code true} if this class has been initialized. */ public boolean isInitialized() { return mInitialized; } - /** - * Adds a {@link ScheduledRecordingListener}. - */ + /** Adds a {@link ScheduledRecordingListener}. */ public final void addScheduledRecordingListener(ScheduledRecordingListener listener) { mScheduledRecordingListeners.add(listener); } - /** - * Removes a {@link ScheduledRecordingListener}. - */ + /** Removes a {@link ScheduledRecordingListener}. */ public final void removeScheduledRecordingListener(ScheduledRecordingListener listener) { mScheduledRecordingListeners.remove(listener); } - /** - * Calls {@link ScheduledRecordingListener#onScheduledRecordingAdded} for each listener. - */ + /** Calls {@link ScheduledRecordingListener#onScheduledRecordingAdded} for each listener. */ private void notifyScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) { for (ScheduledRecordingListener l : mScheduledRecordingListeners) { l.onScheduledRecordingAdded(scheduledRecordings); } } - /** - * Calls {@link ScheduledRecordingListener#onScheduledRecordingRemoved} for each listener. - */ + /** Calls {@link ScheduledRecordingListener#onScheduledRecordingRemoved} for each listener. */ private void notifyScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) { for (ScheduledRecordingListener l : mScheduledRecordingListeners) { l.onScheduledRecordingRemoved(scheduledRecordings); @@ -385,48 +372,36 @@ public class DvrScheduleManager { } } - /** - * Adds a {@link OnInitializeListener}. - */ + /** Adds a {@link OnInitializeListener}. */ public final void addOnInitializeListener(OnInitializeListener listener) { mOnInitializeListeners.add(listener); } - /** - * Removes a {@link OnInitializeListener}. - */ + /** Removes a {@link OnInitializeListener}. */ public final void removeOnInitializeListener(OnInitializeListener listener) { mOnInitializeListeners.remove(listener); } - /** - * Calls {@link OnInitializeListener#onInitialize} for each listener. - */ + /** Calls {@link OnInitializeListener#onInitialize} for each listener. */ private void notifyInitialize() { for (OnInitializeListener l : mOnInitializeListeners) { l.onInitialize(); } } - /** - * Adds a {@link OnConflictStateChangeListener}. - */ + /** Adds a {@link OnConflictStateChangeListener}. */ public final void addOnConflictStateChangeListener(OnConflictStateChangeListener listener) { mOnConflictStateChangeListeners.add(listener); } - /** - * Removes a {@link OnConflictStateChangeListener}. - */ + /** Removes a {@link OnConflictStateChangeListener}. */ public final void removeOnConflictStateChangeListener(OnConflictStateChangeListener listener) { mOnConflictStateChangeListeners.remove(listener); } - /** - * Calls {@link OnConflictStateChangeListener#onConflictStateChange} for each listener. - */ - private void notifyConflictStateChange(boolean conflict, - ScheduledRecording... scheduledRecordings) { + /** Calls {@link OnConflictStateChangeListener#onConflictStateChange} for each listener. */ + private void notifyConflictStateChange( + boolean conflict, ScheduledRecording... scheduledRecordings) { for (OnConflictStateChangeListener l : mOnConflictStateChangeListeners) { l.onConflictStateChange(conflict, scheduledRecordings); } @@ -434,8 +409,8 @@ public class DvrScheduleManager { /** * Returns the priority for the program if it is recorded. - * <p> - * The recording will have the higher priority than the existing ones. + * + * <p>The recording will have the higher priority than the existing ones. */ public long suggestNewPriority() { if (!SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet")) { @@ -454,9 +429,7 @@ public class DvrScheduleManager { return highestPriority + PRIORITY_OFFSET; } - /** - * Suggests the higher priority than the schedules which overlap with {@code schedule}. - */ + /** Suggests the higher priority than the schedules which overlap with {@code schedule}. */ public long suggestHighestPriority(ScheduledRecording schedule) { List<ScheduledRecording> schedules = mInputScheduleMap.get(schedule.getInputId()); if (schedules == null) { @@ -464,7 +437,8 @@ public class DvrScheduleManager { } long highestPriority = Long.MIN_VALUE; for (ScheduledRecording r : schedules) { - if (!r.equals(schedule) && r.isOverLapping(schedule) + if (!r.equals(schedule) + && r.isOverLapping(schedule) && r.getPriority() > highestPriority) { highestPriority = r.getPriority(); } @@ -475,9 +449,7 @@ public class DvrScheduleManager { return highestPriority + PRIORITY_OFFSET; } - /** - * Suggests the higher priority than the schedules which overlap with {@code schedule}. - */ + /** Suggests the higher priority than the schedules which overlap with {@code schedule}. */ public long suggestHighestPriority(String inputId, Range<Long> peroid, long basePriority) { List<ScheduledRecording> schedules = mInputScheduleMap.get(inputId); if (schedules == null) { @@ -497,8 +469,8 @@ public class DvrScheduleManager { /** * Returns the priority for a series recording. - * <p> - * The recording will have the higher priority than the existing series. + * + * <p>The recording will have the higher priority than the existing series. */ public long suggestNewSeriesPriority() { if (!SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet")) { @@ -510,7 +482,7 @@ public class DvrScheduleManager { /** * Returns the priority for a series recording by order of series recording priority. * - * Higher order will have higher priority. + * <p>Higher order will have higher priority. */ public static long suggestSeriesPriority(int order) { return DEFAULT_SERIES_PRIORITY + order * PRIORITY_OFFSET; @@ -527,21 +499,23 @@ public class DvrScheduleManager { } /** - * Returns a sorted list of all scheduled recordings that will not be recorded if - * this program is going to be recorded, with their priorities in decending order. - * <p> - * An empty list means there is no conflicts. If there is conflict, a priority higher than + * Returns a sorted list of all scheduled recordings that will not be recorded if this program + * is going to be recorded, with their priorities in decending order. + * + * <p>An empty list means there is no conflicts. If there is conflict, a priority higher than * the first recording in the returned list should be assigned to the new schedule of this * program to guarantee the program would be completely recorded. */ public List<ScheduledRecording> getConflictingSchedules(Program program) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); - SoftPreconditions.checkState(Program.isValid(program), TAG, - "Program is invalid: " + program); SoftPreconditions.checkState( - program.getStartTimeUtcMillis() < program.getEndTimeUtcMillis(), TAG, + Program.isProgramValid(program), TAG, "Program is invalid: " + program); + SoftPreconditions.checkState( + program.getStartTimeUtcMillis() < program.getEndTimeUtcMillis(), + TAG, "Program duration is empty: " + program); - if (!mInitialized || !Program.isValid(program) + if (!mInitialized + || !Program.isProgramValid(program) || program.getStartTimeUtcMillis() >= program.getEndTimeUtcMillis()) { return Collections.emptyList(); } @@ -549,17 +523,19 @@ public class DvrScheduleManager { if (input == null || !input.canRecord() || input.getTunerCount() <= 0) { return Collections.emptyList(); } - return getConflictingSchedules(input, Collections.singletonList( - ScheduledRecording.builder(input.getId(), program) - .setPriority(suggestHighestPriority()) - .build())); + return getConflictingSchedules( + input, + Collections.singletonList( + ScheduledRecording.builder(input.getId(), program) + .setPriority(suggestHighestPriority()) + .build())); } /** * Returns list of all conflicting scheduled recordings for the given {@code seriesRecording} * recording. - * <p> - * Any empty list means there is no conflicts. + * + * <p>Any empty list means there is no conflicts. */ public List<ScheduledRecording> getConflictingSchedules(SeriesRecording seriesRecording) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); @@ -571,8 +547,8 @@ public class DvrScheduleManager { if (input == null || !input.canRecord() || input.getTunerCount() <= 0) { return Collections.emptyList(); } - List<ScheduledRecording> scheduledRecordingForSeries = mDataManager.getScheduledRecordings( - seriesRecording.getId()); + List<ScheduledRecording> scheduledRecordingForSeries = + mDataManager.getScheduledRecordings(seriesRecording.getId()); List<ScheduledRecording> availableScheduledRecordingForSeries = new ArrayList<>(); for (ScheduledRecording scheduledRecording : scheduledRecordingForSeries) { if (scheduledRecording.isNotStarted() || scheduledRecording.isInProgress()) { @@ -586,15 +562,15 @@ public class DvrScheduleManager { } /** - * Returns a sorted list of all scheduled recordings that will not be recorded if - * this channel is going to be recorded, with their priority in decending order. - * <p> - * An empty list means there is no conflicts. If there is conflict, a priority higher than + * Returns a sorted list of all scheduled recordings that will not be recorded if this channel + * is going to be recorded, with their priority in decending order. + * + * <p>An empty list means there is no conflicts. If there is conflict, a priority higher than * the first recording in the returned list should be assigned to the new schedule of this * channel to guarantee the channel would be completely recorded in the designated time range. */ - public List<ScheduledRecording> getConflictingSchedules(long channelId, long startTimeMs, - long endTimeMs) { + public List<ScheduledRecording> getConflictingSchedules( + long channelId, long startTimeMs, long endTimeMs) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); SoftPreconditions.checkState(channelId != Channel.INVALID_ID, TAG, "Invalid channel ID"); SoftPreconditions.checkState(startTimeMs < endTimeMs, TAG, "Recording duration is empty."); @@ -605,10 +581,12 @@ public class DvrScheduleManager { if (input == null || !input.canRecord() || input.getTunerCount() <= 0) { return Collections.emptyList(); } - return getConflictingSchedules(input, Collections.singletonList( - ScheduledRecording.builder(input.getId(), channelId, startTimeMs, endTimeMs) - .setPriority(suggestHighestPriority()) - .build())); + return getConflictingSchedules( + input, + Collections.singletonList( + ScheduledRecording.builder(input.getId(), channelId, startTimeMs, endTimeMs) + .setPriority(suggestHighestPriority()) + .build())); } /** @@ -633,14 +611,14 @@ public class DvrScheduleManager { /** * Checks if the schedule is conflicting. * - * <p>Note that the {@code schedule} should be the existing one. If not, this returns - * {@code false}. + * <p>Note that the {@code schedule} should be the existing one. If not, this returns {@code + * false}. */ public boolean isConflicting(ScheduledRecording schedule) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); TvInputInfo input = Utils.getTvInputInfoForInputId(mContext, schedule.getInputId()); - SoftPreconditions.checkState(input != null, TAG, "Can't find input for channel ID : " - + schedule.getChannelId()); + SoftPreconditions.checkState( + input != null, TAG, "Can't find input for channel ID : " + schedule.getChannelId()); if (!mInitialized || input == null) { return false; } @@ -651,15 +629,15 @@ public class DvrScheduleManager { /** * Checks if the schedule is partially conflicting, i.e., part of the scheduled program might be * recorded even if the priority of the schedule is not raised. - * <p> - * If the given schedule is not conflicting or is totally conflicting, i.e., cannot be recorded - * at all, this method returns {@code false} in both cases. + * + * <p>If the given schedule is not conflicting or is totally conflicting, i.e., cannot be + * recorded at all, this method returns {@code false} in both cases. */ public boolean isPartiallyConflicting(@NonNull ScheduledRecording schedule) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); TvInputInfo input = Utils.getTvInputInfoForInputId(mContext, schedule.getInputId()); - SoftPreconditions.checkState(input != null, TAG, "Can't find input for channel ID : " - + schedule.getChannelId()); + SoftPreconditions.checkState( + input != null, TAG, "Can't find input for channel ID : " + schedule.getChannelId()); if (!mInitialized || input == null) { return false; } @@ -672,27 +650,35 @@ public class DvrScheduleManager { } /** - * Returns priority ordered list of all scheduled recordings that will not be recorded if - * this channel is tuned to. + * Returns priority ordered list of all scheduled recordings that will not be recorded if this + * channel is tuned to. */ public List<ScheduledRecording> getConflictingSchedulesForTune(long channelId) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); SoftPreconditions.checkState(channelId != Channel.INVALID_ID, TAG, "Invalid channel ID"); TvInputInfo input = Utils.getTvInputInfoForChannelId(mContext, channelId); - SoftPreconditions.checkState(input != null, TAG, "Can't find input for channel ID: " - + channelId); + SoftPreconditions.checkState( + input != null, TAG, "Can't find input for channel ID: " + channelId); if (!mInitialized || channelId == Channel.INVALID_ID || input == null) { return Collections.emptyList(); } - return getConflictingSchedulesForTune(input.getId(), channelId, System.currentTimeMillis(), - suggestHighestPriority(), getStartedRecordings(input.getId()), + return getConflictingSchedulesForTune( + input.getId(), + channelId, + System.currentTimeMillis(), + suggestHighestPriority(), + getStartedRecordings(input.getId()), input.getTunerCount()); } @VisibleForTesting - public static List<ScheduledRecording> getConflictingSchedulesForTune(String inputId, - long channelId, long currentTimeMs, long newPriority, - List<ScheduledRecording> startedRecordings, int tunerCount) { + public static List<ScheduledRecording> getConflictingSchedulesForTune( + String inputId, + long channelId, + long currentTimeMs, + long newPriority, + List<ScheduledRecording> startedRecordings, + int tunerCount) { boolean channelFound = false; for (ScheduledRecording schedule : startedRecordings) { if (schedule.getChannelId() == channelId) { @@ -704,10 +690,10 @@ public class DvrScheduleManager { if (!channelFound) { // The current channel is not being recorded. schedules = new ArrayList<>(startedRecordings); - schedules.add(ScheduledRecording - .builder(inputId, channelId, currentTimeMs, currentTimeMs + 1) - .setPriority(newPriority) - .build()); + schedules.add( + ScheduledRecording.builder(inputId, channelId, currentTimeMs, currentTimeMs + 1) + .setPriority(newPriority) + .build()); } else { schedules = startedRecordings; } @@ -715,17 +701,17 @@ public class DvrScheduleManager { } /** - * Returns priority ordered list of all scheduled recordings that will not be recorded if - * the user keeps watching this channel. - * <p> - * Note that if the user keeps watching the channel, the channel can be recorded. + * Returns priority ordered list of all scheduled recordings that will not be recorded if the + * user keeps watching this channel. + * + * <p>Note that if the user keeps watching the channel, the channel can be recorded. */ public List<ScheduledRecording> getConflictingSchedulesForWatching(long channelId) { SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet"); SoftPreconditions.checkState(channelId != Channel.INVALID_ID, TAG, "Invalid channel ID"); TvInputInfo input = Utils.getTvInputInfoForChannelId(mContext, channelId); - SoftPreconditions.checkState(input != null, TAG, "Can't find input for channel ID: " - + channelId); + SoftPreconditions.checkState( + input != null, TAG, "Can't find input for channel ID: " + channelId); if (!mInitialized || channelId == Channel.INVALID_ID || input == null) { return Collections.emptyList(); } @@ -733,12 +719,17 @@ public class DvrScheduleManager { if (schedules == null || schedules.isEmpty()) { return Collections.emptyList(); } - return getConflictingSchedulesForWatching(input.getId(), channelId, - System.currentTimeMillis(), suggestNewPriority(), schedules, input.getTunerCount()); + return getConflictingSchedulesForWatching( + input.getId(), + channelId, + System.currentTimeMillis(), + suggestNewPriority(), + schedules, + input.getTunerCount()); } - private List<ScheduledRecording> getConflictingSchedules(TvInputInfo input, - List<ScheduledRecording> schedulesToAdd) { + private List<ScheduledRecording> getConflictingSchedules( + TvInputInfo input, List<ScheduledRecording> schedulesToAdd) { SoftPreconditions.checkNotNull(input); if (input == null || !input.canRecord() || input.getTunerCount() <= 0) { return Collections.emptyList(); @@ -751,9 +742,13 @@ public class DvrScheduleManager { } @VisibleForTesting - static List<ScheduledRecording> getConflictingSchedulesForWatching(String inputId, - long channelId, long currentTimeMs, long newPriority, - @NonNull List<ScheduledRecording> schedules, int tunerCount) { + static List<ScheduledRecording> getConflictingSchedulesForWatching( + String inputId, + long channelId, + long currentTimeMs, + long newPriority, + @NonNull List<ScheduledRecording> schedules, + int tunerCount) { List<ScheduledRecording> schedulesToCheck = new ArrayList<>(schedules); List<ScheduledRecording> schedulesSameChannel = new ArrayList<>(); for (ScheduledRecording schedule : schedules) { @@ -763,10 +758,10 @@ public class DvrScheduleManager { } } // Assume that the user will watch the current channel forever. - schedulesToCheck.add(ScheduledRecording - .builder(inputId, channelId, currentTimeMs, Long.MAX_VALUE) - .setPriority(newPriority) - .build()); + schedulesToCheck.add( + ScheduledRecording.builder(inputId, channelId, currentTimeMs, Long.MAX_VALUE) + .setPriority(newPriority) + .build()); List<ScheduledRecording> result = new ArrayList<>(); result.addAll(getConflictingSchedules(schedulesSameChannel, 1)); result.addAll(getConflictingSchedules(schedulesToCheck, tunerCount)); @@ -775,8 +770,10 @@ public class DvrScheduleManager { } @VisibleForTesting - static List<ScheduledRecording> getConflictingSchedules(List<ScheduledRecording> schedulesToAdd, - List<ScheduledRecording> currentSchedules, int tunerCount) { + static List<ScheduledRecording> getConflictingSchedules( + List<ScheduledRecording> schedulesToAdd, + List<ScheduledRecording> currentSchedules, + int tunerCount) { List<ScheduledRecording> schedulesToCheck = new ArrayList<>(currentSchedules); // When the duplicate schedule is to be added, remove the current duplicate recording. for (Iterator<ScheduledRecording> iter = schedulesToCheck.iterator(); iter.hasNext(); ) { @@ -805,9 +802,7 @@ public class DvrScheduleManager { return getConflictingSchedules(schedulesToCheck, tunerCount, ranges); } - /** - * Returns all conflicting scheduled recordings for the given schedules and count of tuner. - */ + /** Returns all conflicting scheduled recordings for the given schedules and count of tuner. */ public static List<ScheduledRecording> getConflictingSchedules( List<ScheduledRecording> schedules, int tunerCount) { return getConflictingSchedules(schedules, tunerCount, null); @@ -825,21 +820,21 @@ public class DvrScheduleManager { } @VisibleForTesting - static List<ConflictInfo> getConflictingSchedulesInfo(List<ScheduledRecording> schedules, - int tunerCount) { + static List<ConflictInfo> getConflictingSchedulesInfo( + List<ScheduledRecording> schedules, int tunerCount) { return getConflictingSchedulesInfo(schedules, tunerCount, null); } /** * This is the core method to calculate all the conflicting schedules (in given periods). - * <p> - * Note that this method will ignore duplicated schedules with a same hash code. (Please refer - * to {@link ScheduledRecording#hashCode}.) + * + * <p>Note that this method will ignore duplicated schedules with a same hash code. (Please + * refer to {@link ScheduledRecording#hashCode}.) * * @return A {@link HashMap} from {@link ScheduledRecording} to {@link Boolean}. The boolean - * value denotes if the scheduled recording is partially conflicting, i.e., is possible - * to be partially recorded under the given schedules and tuner count {@code true}, - * or not {@code false}. + * value denotes if the scheduled recording is partially conflicting, i.e., is possible to + * be partially recorded under the given schedules and tuner count {@code true}, or not + * {@code false}. */ private static List<ConflictInfo> getConflictingSchedulesInfo( List<ScheduledRecording> schedules, int tunerCount, List<Range<Long>> periods) { @@ -886,14 +881,19 @@ public class DvrScheduleManager { if (earliestEndTime < schedule.getEndTimeMs()) { // The schedule can starts when other recording ends even though it's // clipped. - ScheduledRecording modifiedSchedule = ScheduledRecording.buildFrom(schedule) - .setStartTimeMs(earliestEndTime).build(); + ScheduledRecording modifiedSchedule = + ScheduledRecording.buildFrom(schedule) + .setStartTimeMs(earliestEndTime) + .build(); ScheduledRecording originalSchedule = modified2OriginalSchedules.getOrDefault(schedule, schedule); modified2OriginalSchedules.put(modifiedSchedule, originalSchedule); - int insertPosition = Collections.binarySearch(schedulesToCheck, - modifiedSchedule, - ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR); + int insertPosition = + Collections.binarySearch( + schedulesToCheck, + modifiedSchedule, + ScheduledRecording + .START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR); if (insertPosition >= 0) { schedulesToCheck.add(insertPosition, modifiedSchedule); } else { @@ -921,17 +921,19 @@ public class DvrScheduleManager { } } List<ConflictInfo> result = new ArrayList<>(conflicts.values()); - Collections.sort(result, new Comparator<ConflictInfo>() { - @Override - public int compare(ConflictInfo lhs, ConflictInfo rhs) { - return RESULT_COMPARATOR.compare(lhs.schedule, rhs.schedule); - } - }); + Collections.sort( + result, + new Comparator<ConflictInfo>() { + @Override + public int compare(ConflictInfo lhs, ConflictInfo rhs) { + return RESULT_COMPARATOR.compare(lhs.schedule, rhs.schedule); + } + }); return result; } - private static void removeFinishedRecordings(List<ScheduledRecording> recordings, - long currentTimeMs) { + private static void removeFinishedRecordings( + List<ScheduledRecording> recordings, long currentTimeMs) { for (Iterator<ScheduledRecording> iter = recordings.iterator(); iter.hasNext(); ) { if (iter.next().getEndTimeMs() <= currentTimeMs) { iter.remove(); @@ -939,11 +941,9 @@ public class DvrScheduleManager { } } - /** - * @see InputTaskScheduler#getReplacableTask - */ - private static ScheduledRecording findReplaceableRecording(List<ScheduledRecording> recordings, - ScheduledRecording schedule) { + /** @see InputTaskScheduler#getReplacableTask */ + private static ScheduledRecording findReplaceableRecording( + List<ScheduledRecording> recordings, ScheduledRecording schedule) { // Returns the recording with the following priority. // 1. The recording with the lowest priority is returned. // 2. If the priorities are the same, the recording which finishes early is returned. @@ -980,30 +980,24 @@ public class DvrScheduleManager { } } - /** - * A listener which is notified the initialization of schedule manager. - */ + /** A listener which is notified the initialization of schedule manager. */ public interface OnInitializeListener { - /** - * Called when the schedule manager has been initialized. - */ + /** Called when the schedule manager has been initialized. */ void onInitialize(); } - /** - * A listener which is notified the conflict state change of the schedules. - */ + /** A listener which is notified the conflict state change of the schedules. */ public interface OnConflictStateChangeListener { /** * Called when the conflicting schedules change. - * <p> - * Note that this can be called before - * {@link ScheduledRecordingListener#onScheduledRecordingAdded} is called. + * + * <p>Note that this can be called before {@link + * ScheduledRecordingListener#onScheduledRecordingAdded} is called. * * @param conflict {@code true} if the {@code schedules} are the new conflicts, otherwise - * {@code false}. + * {@code false}. * @param schedules the schedules */ void onConflictStateChange(boolean conflict, ScheduledRecording... schedules); } -}
\ No newline at end of file +} |