1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.dvr.ui; 18 19 import android.annotation.TargetApi; 20 import android.content.Context; 21 import android.graphics.drawable.Drawable; 22 import android.os.Build; 23 import android.os.Bundle; 24 import android.support.annotation.NonNull; 25 import android.support.v17.leanback.app.GuidedStepFragment; 26 import android.support.v17.leanback.widget.GuidanceStylist.Guidance; 27 import android.support.v17.leanback.widget.GuidedAction; 28 import android.text.format.DateUtils; 29 30 import com.android.tv.R; 31 import com.android.tv.TvApplication; 32 import com.android.tv.common.SoftPreconditions; 33 import com.android.tv.data.Program; 34 import com.android.tv.dvr.DvrManager; 35 import com.android.tv.dvr.data.ScheduledRecording; 36 import com.android.tv.dvr.data.SeriesRecording; 37 import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment; 38 import com.android.tv.util.Utils; 39 40 import java.util.Collections; 41 import java.util.List; 42 43 /** 44 * A fragment which asks the user the type of the recording. 45 * <p> 46 * The program should be episodic and the series recording should not had been created yet. 47 */ 48 @TargetApi(Build.VERSION_CODES.N) 49 public class DvrScheduleFragment extends DvrGuidedStepFragment { 50 /** 51 * Key for the whether to add the current program to series. 52 * Type: boolean 53 */ 54 public static final String KEY_ADD_CURRENT_PROGRAM_TO_SERIES = "add_current_program_to_series"; 55 56 private static final String TAG = "DvrScheduleFragment"; 57 58 private static final int ACTION_RECORD_EPISODE = 1; 59 private static final int ACTION_RECORD_SERIES = 2; 60 61 private Program mProgram; 62 private boolean mAddCurrentProgramToSeries; 63 64 @Override 65 public void onCreate(Bundle savedInstanceState) { 66 Bundle args = getArguments(); 67 if (args != null) { 68 mProgram = args.getParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM); 69 mAddCurrentProgramToSeries = args.getBoolean(KEY_ADD_CURRENT_PROGRAM_TO_SERIES, false); 70 } 71 DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager(); 72 SoftPreconditions.checkArgument(mProgram != null && mProgram.isEpisodic(), TAG, 73 "The program should be episodic: " + mProgram); 74 SeriesRecording seriesRecording = dvrManager.getSeriesRecording(mProgram); 75 SoftPreconditions.checkArgument(seriesRecording == null 76 || seriesRecording.isStopped(), TAG, 77 "The series recording should be stopped or null: " + seriesRecording); 78 super.onCreate(savedInstanceState); 79 } 80 81 @Override 82 public int onProvideTheme() { 83 return R.style.Theme_TV_Dvr_GuidedStep_Twoline_Action; 84 } 85 86 @NonNull 87 @Override 88 public Guidance onCreateGuidance(Bundle savedInstanceState) { 89 String title = getString(R.string.dvr_schedule_dialog_title); 90 Drawable icon = getResources().getDrawable(R.drawable.ic_dvr, null); 91 return new Guidance(title, null, null, icon); 92 } 93 94 @Override 95 public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 96 Context context = getContext(); 97 String description; 98 if (mProgram.getStartTimeUtcMillis() <= System.currentTimeMillis()) { 99 description = getString(R.string.dvr_action_record_episode_from_now_description, 100 DateUtils.formatDateTime(context, mProgram.getEndTimeUtcMillis(), 101 DateUtils.FORMAT_SHOW_TIME)); 102 } else { 103 description = Utils.getDurationString(context, mProgram.getStartTimeUtcMillis(), 104 mProgram.getEndTimeUtcMillis(), true); 105 } 106 actions.add(new GuidedAction.Builder(context) 107 .id(ACTION_RECORD_EPISODE) 108 .title(R.string.dvr_action_record_episode) 109 .description(description) 110 .build()); 111 actions.add(new GuidedAction.Builder(context) 112 .id(ACTION_RECORD_SERIES) 113 .title(R.string.dvr_action_record_series) 114 .description(mProgram.getTitle()) 115 .build()); 116 } 117 118 @Override 119 public void onTrackedGuidedActionClicked(GuidedAction action) { 120 if (action.getId() == ACTION_RECORD_EPISODE) { 121 getDvrManager().addSchedule(mProgram); 122 List<ScheduledRecording> conflicts = getDvrManager().getConflictingSchedules(mProgram); 123 if (conflicts.isEmpty()) { 124 DvrUiHelper.showAddScheduleToast(getContext(), mProgram.getTitle(), 125 mProgram.getStartTimeUtcMillis(), mProgram.getEndTimeUtcMillis()); 126 dismissDialog(); 127 } else { 128 GuidedStepFragment fragment = new DvrProgramConflictFragment(); 129 Bundle args = new Bundle(); 130 args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, mProgram); 131 fragment.setArguments(args); 132 GuidedStepFragment.add(getFragmentManager(), fragment, 133 R.id.halfsized_dialog_host); 134 } 135 } else if (action.getId() == ACTION_RECORD_SERIES) { 136 SeriesRecording seriesRecording = TvApplication.getSingletons(getContext()) 137 .getDvrDataManager().getSeriesRecording(mProgram.getSeriesId()); 138 if (seriesRecording == null) { 139 seriesRecording = getDvrManager().addSeriesRecording(mProgram, 140 Collections.emptyList(), SeriesRecording.STATE_SERIES_STOPPED); 141 } else { 142 // Reset priority to the highest. 143 seriesRecording = SeriesRecording.buildFrom(seriesRecording) 144 .setPriority(TvApplication.getSingletons(getContext()) 145 .getDvrScheduleManager().suggestNewSeriesPriority()) 146 .build(); 147 getDvrManager().updateSeriesRecording(seriesRecording); 148 } 149 150 DvrUiHelper.startSeriesSettingsActivity(getContext(), 151 seriesRecording.getId(), null, true, true, true, 152 mAddCurrentProgramToSeries ? mProgram : null); 153 dismissDialog(); 154 } 155 } 156 157 @Override 158 public String getTrackerPrefix() { 159 return "DvrSmallSizedStorageErrorFragment"; 160 } 161 162 @Override 163 public String getTrackerLabelForGuidedAction(GuidedAction action) { 164 long actionId = action.getId(); 165 if (actionId == ACTION_RECORD_EPISODE) { 166 return "record-episode"; 167 } else if (actionId == ACTION_RECORD_SERIES) { 168 return "record-series"; 169 } else { 170 return super.getTrackerLabelForGuidedAction(action); 171 } 172 } 173 } 174