Home | History | Annotate | Download | only in list
      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.list;
     18 
     19 import android.annotation.TargetApi;
     20 import android.content.Context;
     21 import android.database.ContentObserver;
     22 import android.media.tv.TvContract.Programs;
     23 import android.net.Uri;
     24 import android.os.Build;
     25 import android.os.Bundle;
     26 import android.os.Handler;
     27 import android.os.Looper;
     28 import android.support.v17.leanback.widget.ClassPresenterSelector;
     29 import android.transition.Fade;
     30 import android.view.LayoutInflater;
     31 import android.view.View;
     32 import android.view.ViewGroup;
     33 
     34 import com.android.tv.ApplicationSingletons;
     35 import com.android.tv.R;
     36 import com.android.tv.TvApplication;
     37 import com.android.tv.data.ChannelDataManager;
     38 import com.android.tv.data.Program;
     39 import com.android.tv.dvr.DvrDataManager;
     40 import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
     41 import com.android.tv.dvr.data.SeriesRecording;
     42 import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
     43 import com.android.tv.dvr.ui.BigArguments;
     44 
     45 import java.util.Collections;
     46 import java.util.List;
     47 
     48 /**
     49  * A fragment to show the list of series schedule recordings.
     50  */
     51 @TargetApi(Build.VERSION_CODES.N)
     52 public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
     53     /**
     54      * The key for series recording whose scheduled recording list will be displayed.
     55      * Type: {@link SeriesRecording}
     56      */
     57     public static final String SERIES_SCHEDULES_KEY_SERIES_RECORDING =
     58             "series_schedules_key_series_recording";
     59     /**
     60      * The key for programs which belong to the series recording whose scheduled recording list
     61      * will be displayed.
     62      * Type: List<{@link Program}>
     63      */
     64     public static final String SERIES_SCHEDULES_KEY_SERIES_PROGRAMS =
     65             "series_schedules_key_series_programs";
     66 
     67     private ChannelDataManager mChannelDataManager;
     68     private DvrDataManager mDvrDataManager;
     69     private SeriesRecording mSeriesRecording;
     70     private List<Program> mPrograms;
     71     private EpisodicProgramLoadTask mProgramLoadTask;
     72 
     73     private final SeriesRecordingListener mSeriesRecordingListener =
     74             new SeriesRecordingListener() {
     75                 @Override
     76                 public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
     77 
     78                 @Override
     79                 public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
     80                     for (SeriesRecording r : seriesRecordings) {
     81                         if (r.getId() == mSeriesRecording.getId()) {
     82                             getActivity().finish();
     83                             return;
     84                         }
     85                     }
     86                 }
     87 
     88                 @Override
     89                 public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
     90                     for (SeriesRecording r : seriesRecordings) {
     91                         if (r.getId() == mSeriesRecording.getId()
     92                                 && getRowsAdapter() instanceof SeriesScheduleRowAdapter) {
     93                             ((SeriesScheduleRowAdapter) getRowsAdapter())
     94                                     .onSeriesRecordingUpdated(r);
     95                             mSeriesRecording = r;
     96                             updateEmptyMessage();
     97                             return;
     98                         }
     99                     }
    100                 }
    101             };
    102 
    103     private final Handler mHandler = new Handler(Looper.getMainLooper());
    104     private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
    105         @Override
    106         public void onChange(boolean selfChange, Uri uri) {
    107             super.onChange(selfChange, uri);
    108             executeProgramLoadingTask();
    109         }
    110     };
    111 
    112     private final ChannelDataManager.Listener mChannelListener = new ChannelDataManager.Listener() {
    113         @Override
    114         public void onLoadFinished() { }
    115 
    116         @Override
    117         public void onChannelListUpdated() {
    118             executeProgramLoadingTask();
    119         }
    120 
    121         @Override
    122         public void onChannelBrowsableChanged() { }
    123     };
    124 
    125     public DvrSeriesSchedulesFragment() {
    126         setEnterTransition(new Fade(Fade.IN));
    127     }
    128 
    129     @Override
    130     public void onAttach(Context context) {
    131         super.onAttach(context);
    132         Bundle args = getArguments();
    133         if (args != null) {
    134             mSeriesRecording = args.getParcelable(SERIES_SCHEDULES_KEY_SERIES_RECORDING);
    135             mPrograms = (List<Program>) BigArguments.getArgument(
    136                     SERIES_SCHEDULES_KEY_SERIES_PROGRAMS);
    137             BigArguments.reset();
    138         }
    139         if (args == null || mPrograms == null) {
    140             getActivity().finish();
    141         }
    142     }
    143 
    144     @Override
    145     public void onCreate(Bundle savedInstanceState) {
    146         super.onCreate(savedInstanceState);
    147         ApplicationSingletons singletons = TvApplication.getSingletons(getContext());
    148         mChannelDataManager = singletons.getChannelDataManager();
    149         mChannelDataManager.addListener(mChannelListener);
    150         mDvrDataManager = singletons.getDvrDataManager();
    151         mDvrDataManager.addSeriesRecordingListener(mSeriesRecordingListener);
    152         getContext().getContentResolver().registerContentObserver(Programs.CONTENT_URI, true,
    153                 mContentObserver);
    154     }
    155 
    156     @Override
    157     public View onCreateView(LayoutInflater inflater, ViewGroup container,
    158             Bundle savedInstanceState) {
    159         onProgramsUpdated();
    160         return super.onCreateView(inflater, container, savedInstanceState);
    161     }
    162 
    163     private void onProgramsUpdated() {
    164         ((SeriesScheduleRowAdapter) getRowsAdapter()).setPrograms(mPrograms);
    165         updateEmptyMessage();
    166     }
    167 
    168     private void updateEmptyMessage() {
    169         if (mPrograms == null || mPrograms.isEmpty()) {
    170             if (mSeriesRecording.getState() == SeriesRecording.STATE_SERIES_STOPPED) {
    171                 showEmptyMessage(R.string.dvr_series_schedules_stopped_empty_state);
    172             } else {
    173                 showEmptyMessage(R.string.dvr_series_schedules_empty_state);
    174             }
    175         } else {
    176             hideEmptyMessage();
    177         }
    178     }
    179 
    180     @Override
    181     public void onDestroy() {
    182         if (mProgramLoadTask != null) {
    183             mProgramLoadTask.cancel(true);
    184             mProgramLoadTask = null;
    185         }
    186         getContext().getContentResolver().unregisterContentObserver(mContentObserver);
    187         mHandler.removeCallbacksAndMessages(null);
    188         mChannelDataManager.removeListener(mChannelListener);
    189         mDvrDataManager.removeSeriesRecordingListener(mSeriesRecordingListener);
    190         super.onDestroy();
    191     }
    192 
    193     @Override
    194     public SchedulesHeaderRowPresenter onCreateHeaderRowPresenter() {
    195         return new SchedulesHeaderRowPresenter.SeriesRecordingHeaderRowPresenter(getContext());
    196     }
    197 
    198     @Override
    199     public ScheduleRowPresenter onCreateRowPresenter() {
    200         return new SeriesScheduleRowPresenter(getContext());
    201     }
    202 
    203     @Override
    204     public ScheduleRowAdapter onCreateRowsAdapter(ClassPresenterSelector presenterSelector) {
    205         return new SeriesScheduleRowAdapter(getContext(), presenterSelector, mSeriesRecording);
    206     }
    207 
    208     @Override
    209     protected int getFirstItemPosition() {
    210         if (mSeriesRecording != null
    211                 && mSeriesRecording.getState() == SeriesRecording.STATE_SERIES_STOPPED) {
    212             return 0;
    213         }
    214         return super.getFirstItemPosition();
    215     }
    216 
    217     private void executeProgramLoadingTask() {
    218         if (mProgramLoadTask != null) {
    219             mProgramLoadTask.cancel(true);
    220         }
    221         mProgramLoadTask = new EpisodicProgramLoadTask(getContext(), mSeriesRecording) {
    222             @Override
    223             protected void onPostExecute(List<Program> programs) {
    224                 mPrograms = programs == null ? Collections.EMPTY_LIST : programs;
    225                 onProgramsUpdated();
    226             }
    227         };
    228         mProgramLoadTask.setLoadCurrentProgram(true)
    229                 .setLoadDisallowedProgram(true)
    230                 .setLoadScheduledEpisode(true)
    231                 .setIgnoreChannelOption(true)
    232                 .execute();
    233     }
    234 }
    235