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.os.Bundle; 20 import androidx.leanback.app.DetailsFragment; 21 import androidx.leanback.widget.ClassPresenterSelector; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.TextView; 26 import com.android.tv.R; 27 import com.android.tv.TvSingletons; 28 import com.android.tv.dvr.DvrDataManager; 29 import com.android.tv.dvr.DvrScheduleManager; 30 import com.android.tv.dvr.data.ScheduledRecording; 31 32 /** A base fragment to show the list of schedule recordings. */ 33 public abstract class BaseDvrSchedulesFragment extends DetailsFragment 34 implements DvrDataManager.ScheduledRecordingListener, 35 DvrScheduleManager.OnConflictStateChangeListener { 36 /** The key for scheduled recording which has be selected in the list. */ 37 public static final String SCHEDULES_KEY_SCHEDULED_RECORDING = 38 "schedules_key_scheduled_recording"; 39 40 private ScheduleRowAdapter mRowsAdapter; 41 private TextView mEmptyInfoScreenView; 42 43 @Override onCreate(Bundle savedInstanceState)44 public void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 ClassPresenterSelector presenterSelector = new ClassPresenterSelector(); 47 presenterSelector.addClassPresenter(SchedulesHeaderRow.class, onCreateHeaderRowPresenter()); 48 presenterSelector.addClassPresenter(ScheduleRow.class, onCreateRowPresenter()); 49 mRowsAdapter = onCreateRowsAdapter(presenterSelector); 50 setAdapter(mRowsAdapter); 51 mRowsAdapter.start(); 52 TvSingletons singletons = TvSingletons.getSingletons(getContext()); 53 singletons.getDvrDataManager().addScheduledRecordingListener(this); 54 singletons.getDvrScheduleManager().addOnConflictStateChangeListener(this); 55 mEmptyInfoScreenView = (TextView) getActivity().findViewById(R.id.empty_info_screen); 56 } 57 58 @Override onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)59 public View onCreateView( 60 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 61 View view = super.onCreateView(inflater, container, savedInstanceState); 62 int firstItemPosition = getFirstItemPosition(); 63 if (firstItemPosition != -1) { 64 getRowsFragment().setSelectedPosition(firstItemPosition, false); 65 } 66 return view; 67 } 68 69 /** Returns rows adapter. */ getRowsAdapter()70 protected ScheduleRowAdapter getRowsAdapter() { 71 return mRowsAdapter; 72 } 73 74 /** Shows the empty message. */ showEmptyMessage(int messageId)75 void showEmptyMessage(int messageId) { 76 mEmptyInfoScreenView.setText(messageId); 77 if (mEmptyInfoScreenView.getVisibility() != View.VISIBLE) { 78 mEmptyInfoScreenView.setVisibility(View.VISIBLE); 79 } 80 } 81 82 /** Hides the empty message. */ hideEmptyMessage()83 void hideEmptyMessage() { 84 if (mEmptyInfoScreenView.getVisibility() == View.VISIBLE) { 85 mEmptyInfoScreenView.setVisibility(View.GONE); 86 } 87 } 88 89 @Override onInflateTitleView( LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)90 public View onInflateTitleView( 91 LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { 92 // Workaround of b/31046014 93 return null; 94 } 95 96 @Override onDestroy()97 public void onDestroy() { 98 TvSingletons singletons = TvSingletons.getSingletons(getContext()); 99 singletons.getDvrScheduleManager().removeOnConflictStateChangeListener(this); 100 singletons.getDvrDataManager().removeScheduledRecordingListener(this); 101 mRowsAdapter.stop(); 102 super.onDestroy(); 103 } 104 105 /** Creates header row presenter. */ onCreateHeaderRowPresenter()106 public abstract SchedulesHeaderRowPresenter onCreateHeaderRowPresenter(); 107 108 /** Creates rows presenter. */ onCreateRowPresenter()109 public abstract ScheduleRowPresenter onCreateRowPresenter(); 110 111 /** Creates rows adapter. */ onCreateRowsAdapter( ClassPresenterSelector presenterSelector)112 public abstract ScheduleRowAdapter onCreateRowsAdapter( 113 ClassPresenterSelector presenterSelector); 114 115 /** Gets the first focus position in schedules list. */ getFirstItemPosition()116 protected int getFirstItemPosition() { 117 for (int i = 0; i < mRowsAdapter.size(); i++) { 118 if (mRowsAdapter.get(i) instanceof ScheduleRow) { 119 return i; 120 } 121 } 122 return -1; 123 } 124 125 @Override onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings)126 public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) { 127 if (mRowsAdapter != null) { 128 for (ScheduledRecording recording : scheduledRecordings) { 129 mRowsAdapter.onScheduledRecordingAdded(recording); 130 } 131 } 132 } 133 134 @Override onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings)135 public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) { 136 if (mRowsAdapter != null) { 137 for (ScheduledRecording recording : scheduledRecordings) { 138 mRowsAdapter.onScheduledRecordingRemoved(recording); 139 } 140 } 141 } 142 143 @Override onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings)144 public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) { 145 if (mRowsAdapter != null) { 146 for (ScheduledRecording recording : scheduledRecordings) { 147 mRowsAdapter.onScheduledRecordingUpdated(recording, false); 148 } 149 } 150 } 151 152 @Override onConflictStateChange(boolean conflict, ScheduledRecording... schedules)153 public void onConflictStateChange(boolean conflict, ScheduledRecording... schedules) { 154 if (mRowsAdapter != null) { 155 for (ScheduledRecording recording : schedules) { 156 mRowsAdapter.onScheduledRecordingUpdated(recording, true); 157 } 158 } 159 } 160 } 161