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.DvrUiHelper; 36 import com.android.tv.dvr.ScheduledRecording; 37 import com.android.tv.dvr.SeriesRecording; 38 import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment; 39 import com.android.tv.util.Utils; 40 41 import java.util.Collections; 42 import java.util.List; 43 44 /** 45 * A fragment which asks the user the type of the recording. 46 * <p> 47 * The program should be episodic and the series recording should not had been created yet. 48 */ 49 @TargetApi(Build.VERSION_CODES.N) 50 public class DvrScheduleFragment extends DvrGuidedStepFragment { 51 private static final String TAG = "DvrScheduleFragment"; 52 53 private static final int ACTION_RECORD_EPISODE = 1; 54 private static final int ACTION_RECORD_SERIES = 2; 55 56 private Program mProgram; 57 58 @Override onCreate(Bundle savedInstanceState)59 public void onCreate(Bundle savedInstanceState) { 60 Bundle args = getArguments(); 61 if (args != null) { 62 mProgram = args.getParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM); 63 } 64 DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager(); 65 SoftPreconditions.checkArgument(mProgram != null && mProgram.isEpisodic(), TAG, 66 "The program should be episodic: " + mProgram); 67 SeriesRecording seriesRecording = dvrManager.getSeriesRecording(mProgram); 68 SoftPreconditions.checkArgument(seriesRecording == null 69 || seriesRecording.isStopped(), TAG, 70 "The series recording should be stopped or null: " + seriesRecording); 71 super.onCreate(savedInstanceState); 72 } 73 74 @Override onProvideTheme()75 public int onProvideTheme() { 76 return R.style.Theme_TV_Dvr_GuidedStep_Twoline_Action; 77 } 78 79 @NonNull 80 @Override onCreateGuidance(Bundle savedInstanceState)81 public Guidance onCreateGuidance(Bundle savedInstanceState) { 82 String title = getString(R.string.dvr_schedule_dialog_title); 83 Drawable icon = getResources().getDrawable(R.drawable.ic_dvr, null); 84 return new Guidance(title, null, null, icon); 85 } 86 87 @Override onCreateActions(@onNull List<GuidedAction> actions, Bundle savedInstanceState)88 public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 89 Context context = getContext(); 90 String description; 91 if (mProgram.getStartTimeUtcMillis() <= System.currentTimeMillis()) { 92 description = getString(R.string.dvr_action_record_episode_from_now_description, 93 DateUtils.formatDateTime(context, mProgram.getEndTimeUtcMillis(), 94 DateUtils.FORMAT_SHOW_TIME)); 95 } else { 96 description = Utils.getDurationString(context, mProgram.getStartTimeUtcMillis(), 97 mProgram.getEndTimeUtcMillis(), true); 98 } 99 actions.add(new GuidedAction.Builder(context) 100 .id(ACTION_RECORD_EPISODE) 101 .title(R.string.dvr_action_record_episode) 102 .description(description) 103 .build()); 104 actions.add(new GuidedAction.Builder(context) 105 .id(ACTION_RECORD_SERIES) 106 .title(R.string.dvr_action_record_series) 107 .description(mProgram.getTitle()) 108 .build()); 109 } 110 111 @Override onGuidedActionClicked(GuidedAction action)112 public void onGuidedActionClicked(GuidedAction action) { 113 if (action.getId() == ACTION_RECORD_EPISODE) { 114 getDvrManager().addSchedule(mProgram); 115 List<ScheduledRecording> conflicts = getDvrManager().getConflictingSchedules(mProgram); 116 if (conflicts.isEmpty()) { 117 DvrUiHelper.showAddScheduleToast(getContext(), mProgram.getTitle(), 118 mProgram.getStartTimeUtcMillis(), mProgram.getEndTimeUtcMillis()); 119 dismissDialog(); 120 } else { 121 GuidedStepFragment fragment = new DvrProgramConflictFragment(); 122 Bundle args = new Bundle(); 123 args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, mProgram); 124 fragment.setArguments(args); 125 GuidedStepFragment.add(getFragmentManager(), fragment, 126 R.id.halfsized_dialog_host); 127 } 128 } else if (action.getId() == ACTION_RECORD_SERIES) { 129 SeriesRecording seriesRecording = TvApplication.getSingletons(getContext()) 130 .getDvrDataManager().getSeriesRecording(mProgram.getSeriesId()); 131 if (seriesRecording == null) { 132 seriesRecording = getDvrManager().addSeriesRecording(mProgram, 133 Collections.emptyList(), SeriesRecording.STATE_SERIES_STOPPED); 134 } else { 135 // Reset priority to the highest. 136 seriesRecording = SeriesRecording.buildFrom(seriesRecording) 137 .setPriority(TvApplication.getSingletons(getContext()) 138 .getDvrScheduleManager().suggestNewSeriesPriority()) 139 .build(); 140 getDvrManager().updateSeriesRecording(seriesRecording); 141 } 142 DvrUiHelper.startSeriesSettingsActivity(getContext(), 143 seriesRecording.getId(), null, true, true, true); 144 dismissDialog(); 145 } 146 } 147 } 148