11abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/* 21abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Copyright (C) 2015 The Android Open Source Project 31abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 41abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 51abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * you may not use this file except in compliance with the License. 61abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * You may obtain a copy of the License at 71abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 81abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 91abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Unless required by applicable law or agreed to in writing, software 111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * See the License for the specific language governing permissions and 141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * limitations under the License. 151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 171abddd9f6225298066094e20a6c29061b6af4590Nick Chalkopackage com.android.tv.dvr; 181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.annotation.TargetApi; 20d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.content.ContentProviderOperation; 212e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.content.ContentResolver; 2265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.ContentUris; 231abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.content.Context; 24d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.content.OperationApplicationException; 2565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.tv.TvContract; 262e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.media.tv.TvInputInfo; 2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.net.Uri; 28d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.AsyncTask; 2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.Build; 302e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.os.Handler; 31d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.RemoteException; 32ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.support.annotation.MainThread; 33ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.support.annotation.NonNull; 3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.Nullable; 3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.VisibleForTesting; 362e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.support.annotation.WorkerThread; 371abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.util.Log; 38d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.util.Range; 39944779887775bd950cf1abf348d2df461593f6abLive Channels Teamimport com.android.tv.TvSingletons; 402e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport com.android.tv.common.SoftPreconditions; 41ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.feature.CommonFeatures; 42944779887775bd950cf1abf348d2df461593f6abLive Channels Teamimport com.android.tv.common.util.CommonUtils; 431abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport com.android.tv.data.Program; 440cc0713c1bf8027642987b750b80217569d2932aLive Channels Teamimport com.android.tv.data.api.Channel; 45d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener; 46d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.DvrDataManager.RecordedProgramListener; 47d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.DvrScheduleManager.OnInitializeListener; 48633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.dvr.data.RecordedProgram; 49633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.dvr.data.ScheduledRecording; 50633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.dvr.data.SeriesRecording; 512e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport com.android.tv.util.AsyncDbTask; 521abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport com.android.tv.util.Utils; 5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.io.File; 5465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.ArrayList; 5565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.Arrays; 56ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport java.util.Collections; 572e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport java.util.HashMap; 581abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport java.util.List; 592e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport java.util.Map; 602e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport java.util.Map.Entry; 610645b17e2818b69b996da48fd93731bc8a01f114Live Channels Teamimport java.util.concurrent.Executor; 621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/** 641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * DVR manager class to add and remove recordings. UI can modify recording list through this class, 651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * instead of modifying them directly through {@link DvrDataManager}. 661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 67ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko@MainThread 6865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko@TargetApi(Build.VERSION_CODES.N) 691abddd9f6225298066094e20a6c29061b6af4590Nick Chalkopublic class DvrManager { 7065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private static final String TAG = "DvrManager"; 7165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private static final boolean DEBUG = false; 7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private final WritableDvrDataManager mDataManager; 7465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final DvrScheduleManager mScheduleManager; 752e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko // @GuardedBy("mListener") 762e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko private final Map<Listener, Handler> mListener = new HashMap<>(); 772e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko private final Context mAppContext; 780645b17e2818b69b996da48fd93731bc8a01f114Live Channels Team private final Executor mDbExecutor; 791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public DvrManager(Context context) { 81ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG); 82d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mAppContext = context.getApplicationContext(); 83944779887775bd950cf1abf348d2df461593f6abLive Channels Team TvSingletons tvSingletons = TvSingletons.getSingletons(context); 840645b17e2818b69b996da48fd93731bc8a01f114Live Channels Team mDbExecutor = tvSingletons.getDbExecutor(); 85944779887775bd950cf1abf348d2df461593f6abLive Channels Team mDataManager = (WritableDvrDataManager) tvSingletons.getDvrDataManager(); 86944779887775bd950cf1abf348d2df461593f6abLive Channels Team mScheduleManager = tvSingletons.getDvrScheduleManager(); 87d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDataManager.isInitialized() && mScheduleManager.isInitialized()) { 88d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko createSeriesRecordingsForRecordedProgramsIfNeeded(mDataManager.getRecordedPrograms()); 89d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 90d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // No need to handle DVR schedule load finished because schedule manager is initialized 91d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // after the all the schedules are loaded. 92d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!mDataManager.isRecordedProgramLoadFinished()) { 93d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.addRecordedProgramLoadFinishedListener( 94d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko new OnRecordedProgramLoadFinishedListener() { 95d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 96d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void onRecordedProgramLoadFinished() { 97d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.removeRecordedProgramLoadFinishedListener(this); 98d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDataManager.isInitialized() 99d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko && mScheduleManager.isInitialized()) { 100d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko createSeriesRecordingsForRecordedProgramsIfNeeded( 101d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.getRecordedPrograms()); 102d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 103d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 104d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }); 105d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 106d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!mScheduleManager.isInitialized()) { 10795961816a768da387f0b5523cf4363ace2044089Nick Chalko mScheduleManager.addOnInitializeListener( 10895961816a768da387f0b5523cf4363ace2044089Nick Chalko new OnInitializeListener() { 10995961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 11095961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onInitialize() { 11195961816a768da387f0b5523cf4363ace2044089Nick Chalko mScheduleManager.removeOnInitializeListener(this); 11295961816a768da387f0b5523cf4363ace2044089Nick Chalko if (mDataManager.isInitialized() 11395961816a768da387f0b5523cf4363ace2044089Nick Chalko && mScheduleManager.isInitialized()) { 11495961816a768da387f0b5523cf4363ace2044089Nick Chalko createSeriesRecordingsForRecordedProgramsIfNeeded( 11595961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.getRecordedPrograms()); 11695961816a768da387f0b5523cf4363ace2044089Nick Chalko } 11795961816a768da387f0b5523cf4363ace2044089Nick Chalko } 11895961816a768da387f0b5523cf4363ace2044089Nick Chalko }); 11995961816a768da387f0b5523cf4363ace2044089Nick Chalko } 12095961816a768da387f0b5523cf4363ace2044089Nick Chalko } 12195961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.addRecordedProgramListener( 12295961816a768da387f0b5523cf4363ace2044089Nick Chalko new RecordedProgramListener() { 123d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 12495961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) { 12595961816a768da387f0b5523cf4363ace2044089Nick Chalko if (!mDataManager.isInitialized() || !mScheduleManager.isInitialized()) { 12695961816a768da387f0b5523cf4363ace2044089Nick Chalko return; 12795961816a768da387f0b5523cf4363ace2044089Nick Chalko } 12895961816a768da387f0b5523cf4363ace2044089Nick Chalko for (RecordedProgram recordedProgram : recordedPrograms) { 12995961816a768da387f0b5523cf4363ace2044089Nick Chalko createSeriesRecordingForRecordedProgramIfNeeded(recordedProgram); 130d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 131d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 132d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 13395961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 13495961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {} 135d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 13695961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 13795961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) { 13895961816a768da387f0b5523cf4363ace2044089Nick Chalko // Removing series recording is handled in the 13995961816a768da387f0b5523cf4363ace2044089Nick Chalko // SeriesRecordingDetailsFragment. 14095961816a768da387f0b5523cf4363ace2044089Nick Chalko } 14195961816a768da387f0b5523cf4363ace2044089Nick Chalko }); 142d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 143d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 144d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void createSeriesRecordingsForRecordedProgramsIfNeeded( 145d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko List<RecordedProgram> recordedPrograms) { 146d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (RecordedProgram recordedProgram : recordedPrograms) { 147d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko createSeriesRecordingForRecordedProgramIfNeeded(recordedProgram); 148d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 149d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 150d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 151d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void createSeriesRecordingForRecordedProgramIfNeeded(RecordedProgram recordedProgram) { 152633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (recordedProgram.isEpisodic()) { 153d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SeriesRecording seriesRecording = 154d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.getSeriesRecording(recordedProgram.getSeriesId()); 155d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (seriesRecording == null) { 156d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko addSeriesRecording(recordedProgram); 157d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 158d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 15965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 16065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 16195961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Schedules a recording for {@code program}. */ 162d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public ScheduledRecording addSchedule(Program program) { 16365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 164d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 16565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 16665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko SeriesRecording seriesRecording = getSeriesRecording(program); 16795961816a768da387f0b5523cf4363ace2044089Nick Chalko return addSchedule( 16895961816a768da387f0b5523cf4363ace2044089Nick Chalko program, 16995961816a768da387f0b5523cf4363ace2044089Nick Chalko seriesRecording == null 17095961816a768da387f0b5523cf4363ace2044089Nick Chalko ? mScheduleManager.suggestNewPriority() 17195961816a768da387f0b5523cf4363ace2044089Nick Chalko : seriesRecording.getPriority()); 1721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 17595961816a768da387f0b5523cf4363ace2044089Nick Chalko * Schedules a recording for {@code program} with the highest priority so that the schedule can 17695961816a768da387f0b5523cf4363ace2044089Nick Chalko * be recorded. 1771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 178d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public ScheduledRecording addScheduleWithHighestPriority(Program program) { 17965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 180d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 18165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 182d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SeriesRecording seriesRecording = getSeriesRecording(program); 18395961816a768da387f0b5523cf4363ace2044089Nick Chalko return addSchedule( 18495961816a768da387f0b5523cf4363ace2044089Nick Chalko program, 18595961816a768da387f0b5523cf4363ace2044089Nick Chalko seriesRecording == null 18695961816a768da387f0b5523cf4363ace2044089Nick Chalko ? mScheduleManager.suggestNewPriority() 18795961816a768da387f0b5523cf4363ace2044089Nick Chalko : mScheduleManager.suggestHighestPriority( 18895961816a768da387f0b5523cf4363ace2044089Nick Chalko seriesRecording.getInputId(), 18995961816a768da387f0b5523cf4363ace2044089Nick Chalko new Range( 19095961816a768da387f0b5523cf4363ace2044089Nick Chalko program.getStartTimeUtcMillis(), 19195961816a768da387f0b5523cf4363ace2044089Nick Chalko program.getEndTimeUtcMillis()), 19295961816a768da387f0b5523cf4363ace2044089Nick Chalko seriesRecording.getPriority())); 193d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 194d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 195d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private ScheduledRecording addSchedule(Program program, long priority) { 19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TvInputInfo input = Utils.getTvInputInfoForProgram(mAppContext, program); 19765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (input == null) { 19865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.e(TAG, "Can't find input for program: " + program); 199d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 20065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 201d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ScheduledRecording schedule; 202d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SeriesRecording seriesRecording = getSeriesRecording(program); 20395961816a768da387f0b5523cf4363ace2044089Nick Chalko schedule = 20495961816a768da387f0b5523cf4363ace2044089Nick Chalko createScheduledRecordingBuilder(input.getId(), program) 20595961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(priority) 20695961816a768da387f0b5523cf4363ace2044089Nick Chalko .setSeriesRecordingId( 20795961816a768da387f0b5523cf4363ace2044089Nick Chalko seriesRecording == null 20895961816a768da387f0b5523cf4363ace2044089Nick Chalko ? SeriesRecording.ID_NOT_SET 20995961816a768da387f0b5523cf4363ace2044089Nick Chalko : seriesRecording.getId()) 21095961816a768da387f0b5523cf4363ace2044089Nick Chalko .build(); 211d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.addScheduledRecording(schedule); 212d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return schedule; 2131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 21595961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Adds a recording schedule with a time range. */ 2161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public void addSchedule(Channel channel, long startTime, long endTime) { 21795961816a768da387f0b5523cf4363ace2044089Nick Chalko Log.i( 21895961816a768da387f0b5523cf4363ace2044089Nick Chalko TAG, 21995961816a768da387f0b5523cf4363ace2044089Nick Chalko "Adding scheduled recording of channel " 22095961816a768da387f0b5523cf4363ace2044089Nick Chalko + channel 22195961816a768da387f0b5523cf4363ace2044089Nick Chalko + " starting at " 22295961816a768da387f0b5523cf4363ace2044089Nick Chalko + Utils.toTimeString(startTime) 22395961816a768da387f0b5523cf4363ace2044089Nick Chalko + " and ending at " 22495961816a768da387f0b5523cf4363ace2044089Nick Chalko + Utils.toTimeString(endTime)); 22565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 22665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 22765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 22865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TvInputInfo input = Utils.getTvInputInfoForChannelId(mAppContext, channel.getId()); 22965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (input == null) { 23065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.e(TAG, "Can't find input for channel: " + channel); 23165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 23265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko addScheduleInternal(input.getId(), channel.getId(), startTime, endTime); 23465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 23695961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Adds the schedule. */ 237d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void addSchedule(ScheduledRecording schedule) { 238d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDataManager.isDvrScheduleLoadFinished()) { 239d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.addScheduledRecording(schedule); 240d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 241d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 242d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 24365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private void addScheduleInternal(String inputId, long channelId, long startTime, long endTime) { 24495961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.addScheduledRecording( 24595961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording.builder(inputId, channelId, startTime, endTime) 24695961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(mScheduleManager.suggestNewPriority()) 24795961816a768da387f0b5523cf4363ace2044089Nick Chalko .build()); 24865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 24965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 25095961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Adds a new series recording and schedules for the programs with the initial state. */ 25195961816a768da387f0b5523cf4363ace2044089Nick Chalko public SeriesRecording addSeriesRecording( 25295961816a768da387f0b5523cf4363ace2044089Nick Chalko Program selectedProgram, 25395961816a768da387f0b5523cf4363ace2044089Nick Chalko List<Program> programsToSchedule, 25495961816a768da387f0b5523cf4363ace2044089Nick Chalko @SeriesRecording.SeriesState int initialState) { 25595961816a768da387f0b5523cf4363ace2044089Nick Chalko Log.i( 25695961816a768da387f0b5523cf4363ace2044089Nick Chalko TAG, 25795961816a768da387f0b5523cf4363ace2044089Nick Chalko "Adding series recording for program " 25895961816a768da387f0b5523cf4363ace2044089Nick Chalko + selectedProgram 25995961816a768da387f0b5523cf4363ace2044089Nick Chalko + ", and schedules: " 26095961816a768da387f0b5523cf4363ace2044089Nick Chalko + programsToSchedule); 26165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized())) { 26265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 26365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 26465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TvInputInfo input = Utils.getTvInputInfoForProgram(mAppContext, selectedProgram); 26565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (input == null) { 26665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.e(TAG, "Can't find input for program: " + selectedProgram); 26765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 26865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 26995961816a768da387f0b5523cf4363ace2044089Nick Chalko SeriesRecording seriesRecording = 27095961816a768da387f0b5523cf4363ace2044089Nick Chalko SeriesRecording.builder(input.getId(), selectedProgram) 27195961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(mScheduleManager.suggestNewSeriesPriority()) 27295961816a768da387f0b5523cf4363ace2044089Nick Chalko .setState(initialState) 27395961816a768da387f0b5523cf4363ace2044089Nick Chalko .build(); 27465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.addSeriesRecording(seriesRecording); 27565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // The schedules for the recorded programs should be added not to create the schedule the 27665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // duplicate episodes. 27765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko addRecordedProgramToSeriesRecording(seriesRecording); 27865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko addScheduleToSeriesRecording(seriesRecording, programsToSchedule); 27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return seriesRecording; 28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 28165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 282d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void addSeriesRecording(RecordedProgram recordedProgram) { 283d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SeriesRecording seriesRecording = 284d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SeriesRecording.builder(recordedProgram.getInputId(), recordedProgram) 285d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setPriority(mScheduleManager.suggestNewSeriesPriority()) 286d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setState(SeriesRecording.STATE_SERIES_STOPPED) 287d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .build(); 288d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.addSeriesRecording(seriesRecording); 289d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // The schedules for the recorded programs should be added not to create the schedule the 290d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // duplicate episodes. 291d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko addRecordedProgramToSeriesRecording(seriesRecording); 292d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 293d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 29465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private void addRecordedProgramToSeriesRecording(SeriesRecording series) { 29565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko List<ScheduledRecording> toAdd = new ArrayList<>(); 29665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (RecordedProgram recordedProgram : mDataManager.getRecordedPrograms()) { 29765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (series.getSeriesId().equals(recordedProgram.getSeriesId()) 29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && !recordedProgram.isClipped()) { 29965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // Duplicate schedules can exist, but they will be deleted in a few days. And it's 30065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // also guaranteed that the schedules don't belong to any series recordings because 30165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // there are no more than one series recordings which have the same program title. 30295961816a768da387f0b5523cf4363ace2044089Nick Chalko toAdd.add( 30395961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording.builder(recordedProgram) 30495961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(series.getPriority()) 30595961816a768da387f0b5523cf4363ace2044089Nick Chalko .setSeriesRecordingId(series.getId()) 30695961816a768da387f0b5523cf4363ace2044089Nick Chalko .build()); 30765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!toAdd.isEmpty()) { 31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.addScheduledRecording(ScheduledRecording.toArray(toAdd)); 31165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 31265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 31365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 31465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 31565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Adds {@link ScheduledRecording}s for the series recording. 31695961816a768da387f0b5523cf4363ace2044089Nick Chalko * 31795961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>This method doesn't add the series recording. 31865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 31995961816a768da387f0b5523cf4363ace2044089Nick Chalko public void addScheduleToSeriesRecording( 32095961816a768da387f0b5523cf4363ace2044089Nick Chalko SeriesRecording series, List<Program> programsToSchedule) { 32165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 32265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 32365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 32465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TvInputInfo input = Utils.getTvInputInfoForInputId(mAppContext, series.getInputId()); 32565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (input == null) { 32665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.e(TAG, "Can't find input with ID: " + series.getInputId()); 32765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 32865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 32965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko List<ScheduledRecording> toAdd = new ArrayList<>(); 33065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko List<ScheduledRecording> toUpdate = new ArrayList<>(); 33165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (Program program : programsToSchedule) { 33265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko ScheduledRecording scheduleWithSameProgram = 33365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.getScheduledRecordingForProgramId(program.getId()); 33465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (scheduleWithSameProgram != null) { 335633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (scheduleWithSameProgram.isNotStarted()) { 33695961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording r = 33795961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording.buildFrom(scheduleWithSameProgram) 33895961816a768da387f0b5523cf4363ace2044089Nick Chalko .setSeriesRecordingId(series.getId()) 33995961816a768da387f0b5523cf4363ace2044089Nick Chalko .build(); 34065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!r.equals(scheduleWithSameProgram)) { 34165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko toUpdate.add(r); 34265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 34365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 34465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 34595961816a768da387f0b5523cf4363ace2044089Nick Chalko toAdd.add( 34695961816a768da387f0b5523cf4363ace2044089Nick Chalko createScheduledRecordingBuilder(input.getId(), program) 34795961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(series.getPriority()) 34895961816a768da387f0b5523cf4363ace2044089Nick Chalko .setSeriesRecordingId(series.getId()) 34995961816a768da387f0b5523cf4363ace2044089Nick Chalko .build()); 35065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!toAdd.isEmpty()) { 35365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.addScheduledRecording(ScheduledRecording.toArray(toAdd)); 35465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!toUpdate.isEmpty()) { 35665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.updateScheduledRecording(ScheduledRecording.toArray(toUpdate)); 35765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 36095961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Updates the series recording. */ 36165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void updateSeriesRecording(SeriesRecording series) { 36265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 36365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko SeriesRecording previousSeries = mDataManager.getSeriesRecording(series.getId()); 36465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (previousSeries != null) { 365633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko // If the channel option of series changed, remove the existing schedules. The new 366633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko // schedules will be added by SeriesRecordingScheduler or by SeriesSettingsFragment. 367d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (previousSeries.getChannelOption() != series.getChannelOption() 368d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko || (previousSeries.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE 36995961816a768da387f0b5523cf4363ace2044089Nick Chalko && previousSeries.getChannelId() != series.getChannelId())) { 370d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko List<ScheduledRecording> schedules = 371d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.getScheduledRecordings(series.getId()); 372d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko List<ScheduledRecording> schedulesToRemove = new ArrayList<>(); 373d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (ScheduledRecording schedule : schedules) { 374d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (schedule.isNotStarted()) { 375d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko schedulesToRemove.add(schedule); 376633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } else if (schedule.isInProgress() 377633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && series.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE 378633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && schedule.getChannelId() != series.getChannelId()) { 379633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko stopRecording(schedule); 380633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 381633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 382633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko List<ScheduledRecording> deletedSchedules = 383633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko new ArrayList<>(mDataManager.getDeletedSchedules()); 384633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko for (ScheduledRecording deletedSchedule : deletedSchedules) { 385633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (deletedSchedule.getSeriesRecordingId() == series.getId() 386633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && deletedSchedule.getEndTimeMs() > System.currentTimeMillis()) { 387633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko schedulesToRemove.add(deletedSchedule); 388d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 389d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 39095961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.removeScheduledRecording( 39195961816a768da387f0b5523cf4363ace2044089Nick Chalko true, ScheduledRecording.toArray(schedulesToRemove)); 392d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 39365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 39465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.updateSeriesRecording(series); 39595961816a768da387f0b5523cf4363ace2044089Nick Chalko if (previousSeries == null || previousSeries.getPriority() != series.getPriority()) { 39665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko long priority = series.getPriority(); 39765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko List<ScheduledRecording> schedulesToUpdate = new ArrayList<>(); 39895961816a768da387f0b5523cf4363ace2044089Nick Chalko for (ScheduledRecording schedule : 39995961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.getScheduledRecordings(series.getId())) { 400633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (schedule.isNotStarted() || schedule.isInProgress()) { 40195961816a768da387f0b5523cf4363ace2044089Nick Chalko schedulesToUpdate.add( 40295961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording.buildFrom(schedule) 40395961816a768da387f0b5523cf4363ace2044089Nick Chalko .setPriority(priority) 40495961816a768da387f0b5523cf4363ace2044089Nick Chalko .build()); 40565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 40665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 40765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!schedulesToUpdate.isEmpty()) { 40865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.updateScheduledRecording( 40965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko ScheduledRecording.toArray(schedulesToUpdate)); 41065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 41165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 41265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 41365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 41465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 41565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 41665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Removes the series recording and all the corresponding schedules which are not started yet. 41765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 41865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void removeSeriesRecording(long seriesRecordingId) { 41965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 42065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 42165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 42265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko SeriesRecording series = mDataManager.getSeriesRecording(seriesRecordingId); 42365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (series == null) { 42465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 42565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 42665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (ScheduledRecording schedule : mDataManager.getAllScheduledRecordings()) { 42765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (schedule.getSeriesRecordingId() == seriesRecordingId) { 42865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) { 42965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko stopRecording(schedule); 43065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko break; 43165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 43265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 43365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 43465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.removeSeriesRecording(series); 4351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 4361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 43795961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Stops the currently recorded program */ 4382e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko public void stopRecording(final ScheduledRecording recording) { 43965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 44065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 44165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 4422e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko synchronized (mListener) { 4432e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko for (final Entry<Listener, Handler> entry : mListener.entrySet()) { 44495961816a768da387f0b5523cf4363ace2044089Nick Chalko entry.getValue() 44595961816a768da387f0b5523cf4363ace2044089Nick Chalko .post( 44695961816a768da387f0b5523cf4363ace2044089Nick Chalko new Runnable() { 44795961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 44895961816a768da387f0b5523cf4363ace2044089Nick Chalko public void run() { 44995961816a768da387f0b5523cf4363ace2044089Nick Chalko entry.getKey().onStopRecordingRequested(recording); 45095961816a768da387f0b5523cf4363ace2044089Nick Chalko } 45195961816a768da387f0b5523cf4363ace2044089Nick Chalko }); 4522e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 4532e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 4542e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 4552e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko 45695961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Removes scheduled recordings or an existing recordings. */ 45765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void removeScheduledRecording(ScheduledRecording... schedules) { 45865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.i(TAG, "Removing " + Arrays.asList(schedules)); 45965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 46065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 46165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 46265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (ScheduledRecording r : schedules) { 46365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (r.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) { 46465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko stopRecording(r); 46565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 46665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.removeScheduledRecording(r); 46765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 46865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 46965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 47065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 47195961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Removes scheduled recordings without changing to the DELETED state. */ 472d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void forceRemoveScheduledRecording(ScheduledRecording... schedules) { 473d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Log.i(TAG, "Force removing " + Arrays.asList(schedules)); 474d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 475d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 476d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 477d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (ScheduledRecording r : schedules) { 478d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (r.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) { 479d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko stopRecording(r); 480d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 481d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.removeScheduledRecording(true, r); 482d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 483d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 484d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 485d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 48695961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Removes the recorded program. It deletes the file if possible. */ 48765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void removeRecordedProgram(Uri recordedProgramUri) { 48865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized())) { 48965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 49065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 49165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko removeRecordedProgram(ContentUris.parseId(recordedProgramUri)); 49265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 49365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 49495961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Removes the recorded program. It deletes the file if possible. */ 49565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void removeRecordedProgram(long recordedProgramId) { 49665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized())) { 49765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 49865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 49965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko RecordedProgram recordedProgram = mDataManager.getRecordedProgram(recordedProgramId); 50065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (recordedProgram != null) { 50165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko removeRecordedProgram(recordedProgram); 50265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 5032e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 5042e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko 50595961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Removes the recorded program. It deletes the file if possible. */ 5062e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko public void removeRecordedProgram(final RecordedProgram recordedProgram) { 50765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized())) { 50865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 50965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 5100645b17e2818b69b996da48fd93731bc8a01f114Live Channels Team new AsyncDbTask<Void, Void, Integer>(mDbExecutor) { 5112e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko @Override 512633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected Integer doInBackground(Void... params) { 5132e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko ContentResolver resolver = mAppContext.getContentResolver(); 514633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return resolver.delete(recordedProgram.getUri(), null, null); 515633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 516633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko 517633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko @Override 518633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected void onPostExecute(Integer deletedCounts) { 519d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (deletedCounts > 0) { 520d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko new AsyncTask<Void, Void, Void>() { 521d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 522d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected Void doInBackground(Void... params) { 523d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko removeRecordedData(recordedProgram.getDataUri()); 524d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 52565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 526d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 52765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 5282e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 52965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }.executeOnDbThread(); 5301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 5311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 532d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void removeRecordedPrograms(List<Long> recordedProgramIds) { 533d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko final ArrayList<ContentProviderOperation> dbOperations = new ArrayList<>(); 534d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko final List<Uri> dataUris = new ArrayList<>(); 535d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (Long rId : recordedProgramIds) { 536d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko RecordedProgram r = mDataManager.getRecordedProgram(rId); 537d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (r != null) { 538d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko dataUris.add(r.getDataUri()); 539d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko dbOperations.add(ContentProviderOperation.newDelete(r.getUri()).build()); 540d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 54165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 5420645b17e2818b69b996da48fd93731bc8a01f114Live Channels Team new AsyncDbTask<Void, Void, Boolean>(mDbExecutor) { 54365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 544633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected Boolean doInBackground(Void... params) { 54565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko ContentResolver resolver = mAppContext.getContentResolver(); 546d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko try { 547d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko resolver.applyBatch(TvContract.AUTHORITY, dbOperations); 548633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } catch (RemoteException | OperationApplicationException e) { 549633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko Log.w(TAG, "Remove recorded programs from DB failed.", e); 550633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return false; 551633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 552633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return true; 553633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 554633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko 555633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko @Override 556633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected void onPostExecute(Boolean success) { 557633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (success) { 558d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko new AsyncTask<Void, Void, Void>() { 559d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 560d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected Void doInBackground(Void... params) { 561d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (Uri dataUri : dataUris) { 562d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko removeRecordedData(dataUri); 563d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 564d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 565d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 566d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 567d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 56865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 56965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }.executeOnDbThread(); 57065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 57165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 57295961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Updates the scheduled recording. */ 57365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void updateScheduledRecording(ScheduledRecording recording) { 57465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 57565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDataManager.updateScheduledRecording(recording); 57665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 57765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 57865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 57965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 58095961816a768da387f0b5523cf4363ace2044089Nick Chalko * Returns priority ordered list of all scheduled recordings that will not be recorded if this 58195961816a768da387f0b5523cf4363ace2044089Nick Chalko * program is. 582ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 58365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * @see DvrScheduleManager#getConflictingSchedules(Program) 58465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 58565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public List<ScheduledRecording> getConflictingSchedules(Program program) { 58665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 58765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return Collections.emptyList(); 58865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 58965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mScheduleManager.getConflictingSchedules(program); 59065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 59165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 59265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 59395961816a768da387f0b5523cf4363ace2044089Nick Chalko * Returns priority ordered list of all scheduled recordings that will not be recorded if this 59495961816a768da387f0b5523cf4363ace2044089Nick Chalko * channel is. 59565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 59665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * @see DvrScheduleManager#getConflictingSchedules(long, long, long) 59765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 59895961816a768da387f0b5523cf4363ace2044089Nick Chalko public List<ScheduledRecording> getConflictingSchedules( 59995961816a768da387f0b5523cf4363ace2044089Nick Chalko long channelId, long startTimeMs, long endTimeMs) { 60065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 60165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return Collections.emptyList(); 60265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 60365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mScheduleManager.getConflictingSchedules(channelId, startTimeMs, endTimeMs); 60465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 60565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 60665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 60765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Checks if the schedule is conflicting. 60865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 60995961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>Note that the {@code schedule} should be the existing one. If not, this returns {@code 61095961816a768da387f0b5523cf4363ace2044089Nick Chalko * false}. 61165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 61265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public boolean isConflicting(ScheduledRecording schedule) { 613d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return schedule != null 614d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko && SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished()) 615d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko && mScheduleManager.isConflicting(schedule); 61665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 61765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 61865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 61995961816a768da387f0b5523cf4363ace2044089Nick Chalko * Returns priority ordered list of all scheduled recording that will not be recorded if this 62095961816a768da387f0b5523cf4363ace2044089Nick Chalko * channel is tuned to. 62165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 62265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * @see DvrScheduleManager#getConflictingSchedulesForTune 62365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 62465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public List<ScheduledRecording> getConflictingSchedulesForTune(long channelId) { 62565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 62665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return Collections.emptyList(); 62765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 62865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mScheduleManager.getConflictingSchedulesForTune(channelId); 62965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 63065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 63195961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Sets the highest priority to the schedule. */ 632d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void setHighestPriority(ScheduledRecording schedule) { 633d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 634d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko long newPriority = mScheduleManager.suggestHighestPriority(schedule); 635d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (newPriority != schedule.getPriority()) { 63695961816a768da387f0b5523cf4363ace2044089Nick Chalko mDataManager.updateScheduledRecording( 63795961816a768da387f0b5523cf4363ace2044089Nick Chalko ScheduledRecording.buildFrom(schedule).setPriority(newPriority).build()); 638ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 639ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 640d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 641d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 64295961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Suggests the higher priority than the schedules which overlap with {@code schedule}. */ 643d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public long suggestHighestPriority(ScheduledRecording schedule) { 644d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 645d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return mScheduleManager.suggestHighestPriority(schedule); 646d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 647d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return DvrScheduleManager.DEFAULT_PRIORITY; 648ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 649ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 65065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 65165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns {@code true} if the channel can be recorded. 65295961816a768da387f0b5523cf4363ace2044089Nick Chalko * 65395961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>Note that this method doesn't check the conflict of the schedule or available tuners. This 65495961816a768da387f0b5523cf4363ace2044089Nick Chalko * can be called from the UI before the schedules are loaded. 65565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 65665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public boolean isChannelRecordable(Channel channel) { 65765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!mDataManager.isDvrScheduleLoadFinished() || channel == null) { 65865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return false; 65965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 660633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (channel.isRecordingProhibited()) { 661633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return false; 662633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 66365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TvInputInfo info = Utils.getTvInputInfoForChannelId(mAppContext, channel.getId()); 66465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (info == null) { 66565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.w(TAG, "Could not find TvInputInfo for " + channel); 66665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return false; 66765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 66865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!info.canRecord()) { 66965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return false; 67065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 67195961816a768da387f0b5523cf4363ace2044089Nick Chalko Program program = 672944779887775bd950cf1abf348d2df461593f6abLive Channels Team TvSingletons.getSingletons(mAppContext) 67395961816a768da387f0b5523cf4363ace2044089Nick Chalko .getProgramDataManager() 67495961816a768da387f0b5523cf4363ace2044089Nick Chalko .getCurrentProgram(channel.getId()); 67565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return program == null || !program.isRecordingProhibited(); 6761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 6771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 6781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 67965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns {@code true} if the program can be recorded. 68095961816a768da387f0b5523cf4363ace2044089Nick Chalko * 68195961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>Note that this method doesn't check the conflict of the schedule or available tuners. This 68295961816a768da387f0b5523cf4363ace2044089Nick Chalko * can be called from the UI before the schedules are loaded. 6831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 68465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public boolean isProgramRecordable(Program program) { 68565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!mDataManager.isInitialized()) { 68665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return false; 68765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 68895961816a768da387f0b5523cf4363ace2044089Nick Chalko Channel channel = 689944779887775bd950cf1abf348d2df461593f6abLive Channels Team TvSingletons.getSingletons(mAppContext) 69095961816a768da387f0b5523cf4363ace2044089Nick Chalko .getChannelDataManager() 69195961816a768da387f0b5523cf4363ace2044089Nick Chalko .getChannel(program.getChannelId()); 692633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (channel == null || channel.isRecordingProhibited()) { 693633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return false; 694633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 695633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko TvInputInfo info = Utils.getTvInputInfoForChannelId(mAppContext, channel.getId()); 69665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (info == null) { 69765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Log.w(TAG, "Could not find TvInputInfo for " + program); 69865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return false; 69965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 70065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return info.canRecord() && !program.isRecordingProhibited(); 7011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 702ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 703ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 70465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns the current recording for the channel. 70595961816a768da387f0b5523cf4363ace2044089Nick Chalko * 70695961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>This can be called from the UI before the schedules are loaded. 707ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 70865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public ScheduledRecording getCurrentRecording(long channelId) { 70965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!mDataManager.isDvrScheduleLoadFinished()) { 71065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 71165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 71265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (ScheduledRecording recording : mDataManager.getStartedRecordings()) { 71365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (recording.getChannelId() == channelId) { 71465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return recording; 71565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 71665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 71765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 71865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 71965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 72065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 72195961816a768da387f0b5523cf4363ace2044089Nick Chalko * Returns schedules which is available (i.e., isNotStarted or isInProgress) and belongs to the 72295961816a768da387f0b5523cf4363ace2044089Nick Chalko * series recording {@code seriesRecordingId}. 723d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko */ 724d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public List<ScheduledRecording> getAvailableScheduledRecording(long seriesRecordingId) { 725d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!mDataManager.isDvrScheduleLoadFinished()) { 726d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return Collections.emptyList(); 727d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 728d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko List<ScheduledRecording> schedules = new ArrayList<>(); 729d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (ScheduledRecording schedule : mDataManager.getScheduledRecordings(seriesRecordingId)) { 730d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (schedule.isInProgress() || schedule.isNotStarted()) { 731d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko schedules.add(schedule); 732d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 733d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 734d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return schedules; 735d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 736d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 73795961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns the series recording related to the program. */ 73865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Nullable 73965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public SeriesRecording getSeriesRecording(Program program) { 74065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) { 74165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 74265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 74365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mDataManager.getSeriesRecording(program.getSeriesId()); 7442e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 7452e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko 746633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko /** 74795961816a768da387f0b5523cf4363ace2044089Nick Chalko * Returns if there are valid items. Valid item contains {@link RecordedProgram}, available 74895961816a768da387f0b5523cf4363ace2044089Nick Chalko * {@link ScheduledRecording} and {@link SeriesRecording}. 749633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko */ 750633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko public boolean hasValidItems() { 751633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return !(mDataManager.getRecordedPrograms().isEmpty() 752633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && mDataManager.getStartedRecordings().isEmpty() 753633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && mDataManager.getNonStartedScheduledRecordings().isEmpty() 754633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && mDataManager.getSeriesRecordings().isEmpty()); 755633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 756633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko 7572e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko @WorkerThread 75865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @VisibleForTesting 75965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // Should be public to use mock DvrManager object. 76065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void addListener(Listener listener, @NonNull Handler handler) { 7612e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko SoftPreconditions.checkNotNull(handler); 7622e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko synchronized (mListener) { 7632e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko mListener.put(listener, handler); 7642e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 7652e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 7662e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko 7672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko @WorkerThread 76865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @VisibleForTesting 76965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // Should be public to use mock DvrManager object. 77065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void removeListener(Listener listener) { 7712e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko synchronized (mListener) { 7722e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko mListener.remove(listener); 7732e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 7742e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko } 7752e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko 7762e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko /** 77765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns ScheduledRecording.builder based on {@code program}. If program is already started, 77865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * recording started time is clipped to the current time. 77965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 78095961816a768da387f0b5523cf4363ace2044089Nick Chalko private ScheduledRecording.Builder createScheduledRecordingBuilder( 78195961816a768da387f0b5523cf4363ace2044089Nick Chalko String inputId, Program program) { 78265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko ScheduledRecording.Builder builder = ScheduledRecording.builder(inputId, program); 78365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko long time = System.currentTimeMillis(); 78465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (program.getStartTimeUtcMillis() < time && time < program.getEndTimeUtcMillis()) { 78565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko builder.setStartTimeMs(time); 78665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 78765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return builder; 78865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 78965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 79095961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns a schedule which matches to the given episode. */ 79195961816a768da387f0b5523cf4363ace2044089Nick Chalko public ScheduledRecording getScheduledRecording( 79295961816a768da387f0b5523cf4363ace2044089Nick Chalko String title, String seasonNumber, String episodeNumber) { 79395961816a768da387f0b5523cf4363ace2044089Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized()) 79495961816a768da387f0b5523cf4363ace2044089Nick Chalko || title == null 79595961816a768da387f0b5523cf4363ace2044089Nick Chalko || seasonNumber == null 79695961816a768da387f0b5523cf4363ace2044089Nick Chalko || episodeNumber == null) { 79765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 79865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 79965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (ScheduledRecording r : mDataManager.getAllScheduledRecordings()) { 80065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (title.equals(r.getProgramTitle()) 80165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && seasonNumber.equals(r.getSeasonNumber()) 80265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && episodeNumber.equals(r.getEpisodeNumber())) { 80365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return r; 80465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 80565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 80665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 80765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 80865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 80995961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns a recorded program which is the same episode as the given {@code program}. */ 81095961816a768da387f0b5523cf4363ace2044089Nick Chalko public RecordedProgram getRecordedProgram( 81195961816a768da387f0b5523cf4363ace2044089Nick Chalko String title, String seasonNumber, String episodeNumber) { 81295961816a768da387f0b5523cf4363ace2044089Nick Chalko if (!SoftPreconditions.checkState(mDataManager.isInitialized()) 81395961816a768da387f0b5523cf4363ace2044089Nick Chalko || title == null 81495961816a768da387f0b5523cf4363ace2044089Nick Chalko || seasonNumber == null 81595961816a768da387f0b5523cf4363ace2044089Nick Chalko || episodeNumber == null) { 81665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 81765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 81865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko for (RecordedProgram r : mDataManager.getRecordedPrograms()) { 81965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (title.equals(r.getTitle()) 82065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && seasonNumber.equals(r.getSeasonNumber()) 82165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && episodeNumber.equals(r.getEpisodeNumber()) 82265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && !r.isClipped()) { 82365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return r; 82465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 82565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 82665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return null; 82765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 82865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 829d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @WorkerThread 830d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void removeRecordedData(Uri dataUri) { 831d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko try { 83295961816a768da387f0b5523cf4363ace2044089Nick Chalko if (dataUri != null 83395961816a768da387f0b5523cf4363ace2044089Nick Chalko && ContentResolver.SCHEME_FILE.equals(dataUri.getScheme()) 834d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko && dataUri.getPath() != null) { 835d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko File recordedProgramPath = new File(dataUri.getPath()); 836d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!recordedProgramPath.exists()) { 837d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (DEBUG) Log.d(TAG, "File to delete not exist: " + recordedProgramPath); 838d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 839944779887775bd950cf1abf348d2df461593f6abLive Channels Team CommonUtils.deleteDirOrFile(recordedProgramPath); 840d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (DEBUG) { 841d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Log.d(TAG, "Sucessfully deleted files of the recorded program: " + dataUri); 842d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 843d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 844d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 845d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } catch (SecurityException e) { 846d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (DEBUG) { 84795961816a768da387f0b5523cf4363ace2044089Nick Chalko Log.d( 84895961816a768da387f0b5523cf4363ace2044089Nick Chalko TAG, 84995961816a768da387f0b5523cf4363ace2044089Nick Chalko "To delete this recorded program, please manually delete video data at" 85095961816a768da387f0b5523cf4363ace2044089Nick Chalko + "\nadb shell rm -rf " 85195961816a768da387f0b5523cf4363ace2044089Nick Chalko + dataUri); 852d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 853d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 854d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 855d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 856d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** 857d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Remove all the records related to the input. 85895961816a768da387f0b5523cf4363ace2044089Nick Chalko * 85995961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>Note that this should be called after the input was removed. 860d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko */ 861d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void forgetStorage(String inputId) { 862d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDataManager.isInitialized()) { 863d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDataManager.forgetStorage(inputId); 864d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 865d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 866d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 86765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 868633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko * Listener to stop recording request. Should only be internally used inside dvr and its 869633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko * sub-package. 8702e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko */ 871633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko public interface Listener { 8722e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko void onStopRecordingRequested(ScheduledRecording scheduledRecording); 873ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 8741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 875