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