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