1 /* 2 * Copyright (C) 2015 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.menu; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.res.Resources; 23 import android.util.AttributeSet; 24 import android.widget.ImageView; 25 import android.widget.TextView; 26 27 import com.android.tv.MainActivity; 28 import com.android.tv.R; 29 import com.android.tv.TvApplication; 30 import com.android.tv.data.Channel; 31 import com.android.tv.data.Program; 32 import com.android.tv.dvr.DvrDataManager; 33 import com.android.tv.dvr.DvrManager; 34 import com.android.tv.dvr.ScheduledRecording; 35 36 import java.util.ArrayList; 37 import java.util.List; 38 import java.util.concurrent.TimeUnit; 39 40 /** 41 * A view to render an item of TV options. 42 */ 43 public class RecordCardView extends SimpleCardView implements 44 DvrDataManager.ScheduledRecordingListener { 45 private static final String TAG = MenuView.TAG; 46 private static final boolean DEBUG = MenuView.DEBUG; 47 private static final long MIN_PROGRAM_RECORD_DURATION = TimeUnit.MINUTES.toMillis(5); 48 49 private ImageView mIconView; 50 private TextView mLabelView; 51 private Channel mCurrentChannel; 52 private final DvrManager mDvrManager; 53 private final DvrDataManager mDvrDataManager; 54 private boolean mIsRecording; 55 private ScheduledRecording mCurrentRecording; 56 57 public RecordCardView(Context context) { 58 this(context, null); 59 } 60 61 public RecordCardView(Context context, AttributeSet attrs) { 62 this(context, attrs, 0); 63 } 64 65 public RecordCardView(Context context, AttributeSet attrs, int defStyle) { 66 super(context, attrs, defStyle); 67 mDvrManager = TvApplication.getSingletons(context).getDvrManager(); 68 mDvrDataManager = TvApplication.getSingletons(context).getDvrDataManager(); 69 } 70 71 @Override 72 public void onBind(Channel channel, boolean selected) { 73 super.onBind(channel, selected); 74 mIconView = (ImageView) findViewById(R.id.record_icon); 75 mLabelView = (TextView) findViewById(R.id.record_label); 76 mCurrentChannel = channel; 77 mCurrentRecording = null; 78 for (ScheduledRecording recording : mDvrDataManager.getStartedRecordings()) { 79 if (recording.getChannelId() == channel.getId()) { 80 mIsRecording = true; 81 mCurrentRecording = recording; 82 } 83 } 84 mDvrDataManager.addScheduledRecordingListener(this); 85 updateCardView(); 86 } 87 88 @Override 89 public void onRecycled() { 90 super.onRecycled(); 91 mDvrDataManager.removeScheduledRecordingListener(this); 92 } 93 94 public boolean isRecording() { 95 return mIsRecording; 96 } 97 98 public void startRecording() { 99 showStartRecordingDialog(); 100 } 101 102 public void stopRecording() { 103 mDvrManager.stopRecording(mCurrentRecording); 104 } 105 106 private void updateCardView() { 107 if (mIsRecording) { 108 mIconView.setImageResource(R.drawable.ic_record_stop); 109 mLabelView.setText(R.string.channels_item_record_stop); 110 } else { 111 mIconView.setImageResource(R.drawable.ic_record_start); 112 mLabelView.setText(R.string.channels_item_record_start); 113 } 114 } 115 116 private void showStartRecordingDialog() { 117 final long endOfProgram = -1; 118 119 final List<CharSequence> items = new ArrayList<>(); 120 final List<Long> durations = new ArrayList<>(); 121 Resources res = getResources(); 122 items.add(res.getString(R.string.recording_start_dialog_10_min_duration)); 123 durations.add(TimeUnit.MINUTES.toMillis(10)); 124 items.add(res.getString(R.string.recording_start_dialog_30_min_duration)); 125 durations.add(TimeUnit.MINUTES.toMillis(30)); 126 items.add(res.getString(R.string.recording_start_dialog_1_hour_duration)); 127 durations.add(TimeUnit.HOURS.toMillis(1)); 128 items.add(res.getString(R.string.recording_start_dialog_3_hours_duration)); 129 durations.add(TimeUnit.HOURS.toMillis(3)); 130 131 Program currenProgram = ((MainActivity) getContext()).getCurrentProgram(false); 132 if (currenProgram != null) { 133 long duration = currenProgram.getEndTimeUtcMillis() - System.currentTimeMillis(); 134 if (duration > MIN_PROGRAM_RECORD_DURATION) { 135 items.add(res.getString(R.string.recording_start_dialog_till_end_of_program)); 136 durations.add(duration); 137 } 138 } 139 140 DialogInterface.OnClickListener onClickListener 141 = new DialogInterface.OnClickListener() { 142 @Override 143 public void onClick(final DialogInterface dialog, int which) { 144 long startTime = System.currentTimeMillis(); 145 long endTime = System.currentTimeMillis() + durations.get(which); 146 mDvrManager.addSchedule(mCurrentChannel, startTime, endTime); 147 dialog.dismiss(); 148 } 149 }; 150 new AlertDialog.Builder(getContext()) 151 .setItems(items.toArray(new CharSequence[items.size()]), onClickListener) 152 .create() 153 .show(); 154 } 155 156 @Override 157 public void onScheduledRecordingAdded(ScheduledRecording recording) { 158 } 159 160 @Override 161 public void onScheduledRecordingRemoved(ScheduledRecording recording) { 162 if (recording.getChannelId() != mCurrentChannel.getId()) { 163 return; 164 } 165 if (mIsRecording) { 166 mIsRecording = false; 167 mCurrentRecording = null; 168 updateCardView(); 169 } 170 } 171 172 @Override 173 public void onScheduledRecordingStatusChanged(ScheduledRecording recording) { 174 if (recording.getChannelId() != mCurrentChannel.getId()) { 175 return; 176 } 177 int state = recording.getState(); 178 if (state == ScheduledRecording.STATE_RECORDING_FAILED 179 || state == ScheduledRecording.STATE_RECORDING_FINISHED) { 180 mIsRecording = false; 181 mCurrentRecording = null; 182 updateCardView(); 183 } else if (state == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) { 184 mIsRecording = true; 185 mCurrentRecording = recording; 186 updateCardView(); 187 } 188 } 189 } 190