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