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.app.FragmentManager; 20 import android.content.Context; 21 import android.graphics.Typeface; 22 import android.os.Bundle; 23 import android.support.v17.leanback.widget.GuidanceStylist.Guidance; 24 import android.support.v17.leanback.widget.GuidedAction; 25 import android.support.v17.leanback.widget.GuidedActionsStylist; 26 import android.view.View; 27 import android.widget.ImageView; 28 import android.widget.TextView; 29 30 import com.android.tv.R; 31 import com.android.tv.TvApplication; 32 import com.android.tv.dvr.DvrDataManager; 33 import com.android.tv.dvr.DvrManager; 34 import com.android.tv.dvr.DvrScheduleManager; 35 import com.android.tv.dvr.data.SeriesRecording; 36 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** Fragment for DVR series recording settings. */ 41 public class DvrPrioritySettingsFragment extends TrackedGuidedStepFragment { 42 /** 43 * Name of series recording id starting the fragment. 44 * Type: Long 45 */ 46 public static final String COME_FROM_SERIES_RECORDING_ID = "series_recording_id"; 47 48 private static final int ONE_TIME_RECORDING_ID = 0; 49 // button action's IDs are negative. 50 private static final long ACTION_ID_SAVE = -100L; 51 52 private final List<SeriesRecording> mSeriesRecordings = new ArrayList<>(); 53 54 private SeriesRecording mSelectedRecording; 55 private SeriesRecording mComeFromSeriesRecording; 56 private float mSelectedActionElevation; 57 private int mActionColor; 58 private int mSelectedActionColor; 59 60 @Override onAttach(Context context)61 public void onAttach(Context context) { 62 super.onAttach(context); 63 mSeriesRecordings.clear(); 64 mSeriesRecordings.add(new SeriesRecording.Builder() 65 .setTitle(getString(R.string.dvr_priority_action_one_time_recording)) 66 .setPriority(Long.MAX_VALUE) 67 .setId(ONE_TIME_RECORDING_ID) 68 .build()); 69 DvrDataManager dvrDataManager = TvApplication.getSingletons(context).getDvrDataManager(); 70 long comeFromSeriesRecordingId = 71 getArguments().getLong(COME_FROM_SERIES_RECORDING_ID, -1); 72 for (SeriesRecording series : dvrDataManager.getSeriesRecordings()) { 73 if (series.getState() == SeriesRecording.STATE_SERIES_NORMAL 74 || series.getId() == comeFromSeriesRecordingId) { 75 mSeriesRecordings.add(series); 76 } 77 } 78 mSeriesRecordings.sort(SeriesRecording.PRIORITY_COMPARATOR); 79 mComeFromSeriesRecording = dvrDataManager.getSeriesRecording(comeFromSeriesRecordingId); 80 mSelectedActionElevation = getResources().getDimension(R.dimen.card_elevation_normal); 81 mActionColor = getResources().getColor(R.color.dvr_guided_step_action_text_color, null); 82 mSelectedActionColor = 83 getResources().getColor(R.color.dvr_guided_step_action_text_color_selected, null); 84 } 85 86 @Override onResume()87 public void onResume() { 88 super.onResume(); 89 setSelectedActionPosition(mComeFromSeriesRecording == null ? 1 90 : mSeriesRecordings.indexOf(mComeFromSeriesRecording)); 91 } 92 93 @Override onCreateGuidance(Bundle savedInstanceState)94 public Guidance onCreateGuidance(Bundle savedInstanceState) { 95 String breadcrumb = mComeFromSeriesRecording == null ? null 96 : mComeFromSeriesRecording.getTitle(); 97 return new Guidance(getString(R.string.dvr_priority_title), 98 getString(R.string.dvr_priority_description), breadcrumb, null); 99 } 100 101 @Override onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState)102 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 103 int position = 0; 104 for (SeriesRecording seriesRecording : mSeriesRecordings) { 105 actions.add(new GuidedAction.Builder(getActivity()) 106 .id(position++) 107 .title(seriesRecording.getTitle()) 108 .build()); 109 } 110 } 111 112 @Override onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState)113 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 114 actions.add(new GuidedAction.Builder(getActivity()) 115 .id(ACTION_ID_SAVE) 116 .title(getString(R.string.dvr_priority_button_action_save)) 117 .build()); 118 actions.add(new GuidedAction.Builder(getActivity()) 119 .clickAction(GuidedAction.ACTION_ID_CANCEL) 120 .build()); 121 } 122 123 @Override onTrackedGuidedActionClicked(GuidedAction action)124 public void onTrackedGuidedActionClicked(GuidedAction action) { 125 long actionId = action.getId(); 126 if (actionId == ACTION_ID_SAVE) { 127 DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager(); 128 int size = mSeriesRecordings.size(); 129 for (int i = 1; i < size; ++i) { 130 long priority = DvrScheduleManager.suggestSeriesPriority(size - i); 131 SeriesRecording seriesRecording = mSeriesRecordings.get(i); 132 if (seriesRecording.getPriority() != priority) { 133 dvrManager.updateSeriesRecording(SeriesRecording.buildFrom(seriesRecording) 134 .setPriority(priority).build()); 135 } 136 } 137 FragmentManager fragmentManager = getFragmentManager(); 138 fragmentManager.popBackStack(); 139 } else if (actionId == GuidedAction.ACTION_ID_CANCEL) { 140 FragmentManager fragmentManager = getFragmentManager(); 141 fragmentManager.popBackStack(); 142 } else if (mSelectedRecording == null) { 143 mSelectedRecording = mSeriesRecordings.get((int) actionId); 144 for (int i = 0; i < mSeriesRecordings.size(); ++i) { 145 updateItem(i); 146 } 147 } else { 148 mSelectedRecording = null; 149 for (int i = 0; i < mSeriesRecordings.size(); ++i) { 150 updateItem(i); 151 } 152 } 153 } 154 155 @Override getTrackerPrefix()156 public String getTrackerPrefix() { 157 return "DvrPrioritySettingsFragment"; 158 } 159 160 @Override getTrackerLabelForGuidedAction(GuidedAction action)161 public String getTrackerLabelForGuidedAction(GuidedAction action) { 162 long actionId = action.getId(); 163 if (actionId == ACTION_ID_SAVE) { 164 return "save"; 165 } else { 166 return super.getTrackerLabelForGuidedAction(action); 167 } 168 } 169 170 @Override onGuidedActionFocused(GuidedAction action)171 public void onGuidedActionFocused(GuidedAction action) { 172 super.onGuidedActionFocused(action); 173 if (mSelectedRecording == null) { 174 return; 175 } 176 if (action.getId() < 0) { 177 mSelectedRecording = null; 178 for (int i = 0; i < mSeriesRecordings.size(); ++i) { 179 updateItem(i); 180 } 181 return; 182 } 183 int position = (int) action.getId(); 184 int previousPosition = mSeriesRecordings.indexOf(mSelectedRecording); 185 mSeriesRecordings.remove(mSelectedRecording); 186 mSeriesRecordings.add(position, mSelectedRecording); 187 updateItem(previousPosition); 188 updateItem(position); 189 notifyActionChanged(previousPosition); 190 notifyActionChanged(position); 191 } 192 193 @Override onCreateButtonActionsStylist()194 public GuidedActionsStylist onCreateButtonActionsStylist() { 195 return new DvrGuidedActionsStylist(true); 196 } 197 198 @Override onCreateActionsStylist()199 public GuidedActionsStylist onCreateActionsStylist() { 200 return new DvrGuidedActionsStylist(false) { 201 @Override 202 public void onBindViewHolder(ViewHolder vh, GuidedAction action) { 203 super.onBindViewHolder(vh, action); 204 updateItem(vh.itemView, (int) action.getId()); 205 } 206 207 @Override 208 public int onProvideItemLayoutId() { 209 return R.layout.priority_settings_action_item; 210 } 211 }; 212 } 213 214 private void updateItem(int position) { 215 View itemView = getActionItemView(position); 216 if (itemView == null) { 217 return; 218 } 219 updateItem(itemView, position); 220 } 221 222 private void updateItem(View itemView, int position) { 223 GuidedAction action = getActions().get(position); 224 action.setTitle(mSeriesRecordings.get(position).getTitle()); 225 boolean selected = mSelectedRecording != null 226 && mSeriesRecordings.indexOf(mSelectedRecording) == position; 227 TextView titleView = (TextView) itemView.findViewById(R.id.guidedactions_item_title); 228 ImageView imageView = (ImageView) itemView.findViewById(R.id.guidedactions_item_tail_image); 229 if (position == 0) { 230 // one-time recording 231 itemView.setBackgroundResource(R.drawable.setup_selector_background); 232 imageView.setVisibility(View.GONE); 233 itemView.setFocusable(false); 234 itemView.setElevation(0); 235 // strings.xml <i> tag doesn't work. 236 titleView.setTypeface(titleView.getTypeface(), Typeface.ITALIC); 237 } else if (mSelectedRecording == null) { 238 titleView.setTextColor(mActionColor); 239 itemView.setBackgroundResource(R.drawable.setup_selector_background); 240 imageView.setImageResource(R.drawable.ic_draggable_white); 241 imageView.setVisibility(View.VISIBLE); 242 itemView.setFocusable(true); 243 itemView.setElevation(0); 244 titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL); 245 } else if (selected) { 246 titleView.setTextColor(mSelectedActionColor); 247 itemView.setBackgroundResource(R.drawable.priority_settings_action_item_selected); 248 imageView.setImageResource(R.drawable.ic_dragging_grey); 249 imageView.setVisibility(View.VISIBLE); 250 itemView.setFocusable(true); 251 itemView.setElevation(mSelectedActionElevation); 252 titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL); 253 } else { 254 titleView.setTextColor(mActionColor); 255 itemView.setBackgroundResource(R.drawable.setup_selector_background); 256 imageView.setVisibility(View.INVISIBLE); 257 itemView.setFocusable(true); 258 itemView.setElevation(0); 259 titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL); 260 } 261 } 262 }