165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/*
265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Copyright (C) 2016 The Android Open Source Project
365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * you may not use this file except in compliance with the License.
665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * You may obtain a copy of the License at
765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
1065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Unless required by applicable law or agreed to in writing, software
1165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
1265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * See the License for the specific language governing permissions and
1465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * limitations under the License
1565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
1665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.dvr.ui.list;
1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
19d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.animation.Animator;
20d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.animation.AnimatorListenerAdapter;
2165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.animation.ValueAnimator;
22d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.annotation.TargetApi;
2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.app.Activity;
2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.Context;
25d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.content.res.Resources;
26d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.Build;
27d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.support.annotation.IntDef;
2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.RowPresenter;
2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.text.TextUtils;
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.LayoutInflater;
3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.View;
32d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.view.View.OnFocusChangeListener;
3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.ViewGroup;
3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.animation.DecelerateInterpolator;
3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.ImageView;
3665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.LinearLayout;
3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.RelativeLayout;
3865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.TextView;
3965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.Toast;
4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
4165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.R;
4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.TvApplication;
43d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.common.SoftPreconditions;
4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.data.Channel;
456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dialog.HalfSizedDialogFragment;
46d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.DvrManager;
4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.dvr.DvrScheduleManager;
486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.data.ScheduledRecording;
49d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.ui.DvrStopRecordingFragment;
506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.ui.DvrUiHelper;
51d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.util.ToastUtils;
5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.util.Utils;
5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
54d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport java.lang.annotation.Retention;
55d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport java.lang.annotation.RetentionPolicy;
5665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.List;
5765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/**
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * A RowPresenter for {@link ScheduleRow}.
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
61d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko@TargetApi(Build.VERSION_CODES.N)
626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoclass ScheduleRowPresenter extends RowPresenter {
63d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private static final String TAG = "ScheduleRowPresenter";
64d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
65d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @Retention(RetentionPolicy.SOURCE)
66d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @IntDef({ACTION_START_RECORDING, ACTION_STOP_RECORDING, ACTION_CREATE_SCHEDULE,
67d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ACTION_REMOVE_SCHEDULE})
68d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    public @interface ScheduleRowAction {}
69d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /** An action to start recording. */
70d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    public static final int ACTION_START_RECORDING = 1;
71d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /** An action to stop recording. */
72d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    public static final int ACTION_STOP_RECORDING = 2;
73d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /** An action to create schedule for the row. */
74d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    public static final int ACTION_CREATE_SCHEDULE = 3;
75d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /** An action to remove the schedule. */
76d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    public static final int ACTION_REMOVE_SCHEDULE = 4;
77d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
78d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private final Context mContext;
79d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private final DvrManager mDvrManager;
80d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private final DvrScheduleManager mDvrScheduleManager;
8165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private final String mTunerConflictWillNotBeRecordedInfo;
8365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private final String mTunerConflictWillBePartiallyRecordedInfo;
84d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private final int mAnimationDuration;
85d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
86d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private int mLastFocusedViewId;
8765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
8965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * A ViewHolder for {@link ScheduleRow}
9065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
9165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static class ScheduleRowViewHolder extends RowPresenter.ViewHolder {
92d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private ScheduleRowPresenter mPresenter;
93d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        @ScheduleRowAction private int[] mActions;
9465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private boolean mLtr;
9565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private LinearLayout mInfoContainer;
96d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        // The first action is on the right of the second action.
97d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private RelativeLayout mSecondActionContainer;
98d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private RelativeLayout mFirstActionContainer;
9965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private View mSelectorView;
10065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private TextView mTimeView;
10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private TextView mProgramTitleView;
10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private TextView mInfoSeparatorView;
10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private TextView mChannelNameView;
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private TextView mConflictInfoView;
105d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private ImageView mSecondActionView;
106d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private ImageView mFirstActionView;
107d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
108d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private Runnable mPendingAnimationRunnable;
109d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
110d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mSelectorTranslationDelta;
111d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mSelectorWidthDelta;
112d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mInfoContainerTargetWidthWithNoAction;
113d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mInfoContainerTargetWidthWithOneAction;
114d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mInfoContainerTargetWidthWithTwoAction;
115d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final int mRoundRectRadius;
116d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
117d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private final OnFocusChangeListener mOnFocusChangeListener =
118d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                new View.OnFocusChangeListener() {
119d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    @Override
120d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    public void onFocusChange(View view, boolean focused) {
121d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        view.post(new Runnable() {
122d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            @Override
123d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            public void run() {
124d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                if (view.isFocused()) {
125d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                    mPresenter.mLastFocusedViewId = view.getId();
126d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                }
127d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                updateSelector();
128d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            }
129d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        });
130d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
131d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                };
13265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
133d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        public ScheduleRowViewHolder(View view, ScheduleRowPresenter presenter) {
13465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            super(view);
135d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mPresenter = presenter;
13665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mLtr = view.getContext().getResources().getConfiguration().getLayoutDirection()
13765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    == View.LAYOUT_DIRECTION_LTR;
13865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mInfoContainer = (LinearLayout) view.findViewById(R.id.info_container);
139d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mSecondActionContainer = (RelativeLayout) view.findViewById(
140d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    R.id.action_second_container);
141d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mSecondActionView = (ImageView) view.findViewById(R.id.action_second);
142d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mFirstActionContainer = (RelativeLayout) view.findViewById(
143d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    R.id.action_first_container);
144d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mFirstActionView = (ImageView) view.findViewById(R.id.action_first);
14565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mSelectorView = view.findViewById(R.id.selector);
14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mTimeView = (TextView) view.findViewById(R.id.time);
14765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgramTitleView = (TextView) view.findViewById(R.id.program_title);
14865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mInfoSeparatorView = (TextView) view.findViewById(R.id.info_separator);
14965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mChannelNameView = (TextView) view.findViewById(R.id.channel_name);
15065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mConflictInfoView = (TextView) view.findViewById(R.id.conflict_info);
151d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            Resources res = view.getResources();
152d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mSelectorTranslationDelta =
153d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin)
154d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_focus_translation_delta);
155d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mSelectorWidthDelta = res.getDimensionPixelSize(
156d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    R.dimen.dvr_schedules_item_focus_width_delta);
157d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mRoundRectRadius = res.getDimensionPixelSize(R.dimen.dvr_schedules_selector_radius);
158d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            int fullWidth = res.getDimensionPixelSize(
159d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    R.dimen.dvr_schedules_item_width)
160d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - 2 * res.getDimensionPixelSize(R.dimen.dvr_schedules_layout_padding);
161d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mInfoContainerTargetWidthWithNoAction = fullWidth + 2 * mRoundRectRadius;
162d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mInfoContainerTargetWidthWithOneAction = fullWidth
163d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin)
164d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_delete_width)
165d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    + mRoundRectRadius + mSelectorWidthDelta;
166d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mInfoContainerTargetWidthWithTwoAction = mInfoContainerTargetWidthWithOneAction
167d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin)
168d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_icon_size);
169d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
170d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mInfoContainer.setOnFocusChangeListener(mOnFocusChangeListener);
171d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mFirstActionContainer.setOnFocusChangeListener(mOnFocusChangeListener);
172d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mSecondActionContainer.setOnFocusChangeListener(mOnFocusChangeListener);
17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
17465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
17565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Returns time view.
17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
17865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public TextView getTimeView() {
17965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return mTimeView;
18065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
18165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
18265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
18365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Returns title view.
18465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
18565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public TextView getProgramTitleView() {
18665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return mProgramTitleView;
18765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
18865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
18965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private void updateSelector() {
19065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            int animationDuration = mSelectorView.getResources().getInteger(
19165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    android.R.integer.config_shortAnimTime);
19265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            DecelerateInterpolator interpolator = new DecelerateInterpolator();
19365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
194d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (mInfoContainer.isFocused() || mSecondActionContainer.isFocused()
195d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    || mFirstActionContainer.isFocused()) {
19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                final ViewGroup.LayoutParams lp = mSelectorView.getLayoutParams();
19765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                final int targetWidth;
19865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if (mInfoContainer.isFocused()) {
199d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    // Use actions to check the visibility of the actions instead of calling
200d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    // View.getVisibility() because the view could be on the hiding animation.
201d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    if (mActions == null || mActions.length == 0) {
202d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        targetWidth = mInfoContainerTargetWidthWithNoAction;
203d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    } else if (mActions.length == 1) {
204d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        targetWidth = mInfoContainerTargetWidthWithOneAction;
20565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    } else {
206d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        targetWidth = mInfoContainerTargetWidthWithTwoAction;
20765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    }
208d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else if (mSecondActionContainer.isFocused()) {
209d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    targetWidth = Math.max(mSecondActionContainer.getWidth(), 2 * mRoundRectRadius);
21065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                } else {
211d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    targetWidth = mFirstActionContainer.getWidth() + mRoundRectRadius
212d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            + mSelectorTranslationDelta;
21365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
21465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
21565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                float targetTranslationX;
21665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if (mInfoContainer.isFocused()) {
217d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    targetTranslationX = mLtr ? mInfoContainer.getLeft() - mRoundRectRadius
21865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            - mSelectorView.getLeft() :
219d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            mInfoContainer.getRight() + mRoundRectRadius - mSelectorView.getRight();
220d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else if (mSecondActionContainer.isFocused()) {
221d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    if (mSecondActionContainer.getWidth() > 2 * mRoundRectRadius) {
222d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        targetTranslationX = mLtr ? mSecondActionContainer.getLeft() -
22365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                mSelectorView.getLeft()
224d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                : mSecondActionContainer.getRight() - mSelectorView.getRight();
22565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    } else {
226d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        targetTranslationX = mLtr ? mSecondActionContainer.getLeft() -
227d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                (mRoundRectRadius - mSecondActionContainer.getWidth() / 2) -
22865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                mSelectorView.getLeft()
229d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                : mSecondActionContainer.getRight() +
230d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                (mRoundRectRadius - mSecondActionContainer.getWidth() / 2) -
23165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                mSelectorView.getRight();
23265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    }
23365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                } else {
234d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    targetTranslationX = mLtr ? mFirstActionContainer.getLeft()
235d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            - mSelectorTranslationDelta - mSelectorView.getLeft()
236d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            : mFirstActionContainer.getRight() + mSelectorTranslationDelta
237d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            - mSelectorView.getRight();
23865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
23965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
24065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if (mSelectorView.getAlpha() == 0) {
24165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    mSelectorView.setTranslationX(targetTranslationX);
24265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    lp.width = targetWidth;
24365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    mSelectorView.requestLayout();
24465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
24565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
24665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                // animate the selector in and to the proper width and translation X.
24765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                final float deltaWidth = lp.width - targetWidth;
24865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mSelectorView.animate().cancel();
24965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mSelectorView.animate().translationX(targetTranslationX).alpha(1f)
25065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
25165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            @Override
25265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            public void onAnimationUpdate(ValueAnimator animation) {
25365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                // Set width to the proper width for this animation step.
25465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                lp.width = targetWidth + Math.round(
25565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                        deltaWidth * (1f - animation.getAnimatedFraction()));
25665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                                mSelectorView.requestLayout();
25765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            }
25865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                        }).setDuration(animationDuration).setInterpolator(interpolator).start();
259d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                if (mPendingAnimationRunnable != null) {
260d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    mPendingAnimationRunnable.run();
261d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    mPendingAnimationRunnable = null;
262d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
26365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            } else {
26465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mSelectorView.animate().cancel();
26565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                mSelectorView.animate().alpha(0f).setDuration(animationDuration)
266d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setInterpolator(interpolator).setUpdateListener(null).start();
26765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
26865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
26965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
27065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
27165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Grey out the information body.
27265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
27365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public void greyOutInfo() {
27465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mTimeView.setTextColor(mInfoContainer.getResources().getColor(R.color
27565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info_grey, null));
27665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgramTitleView.setTextColor(mInfoContainer.getResources().getColor(R.color
27765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info_grey, null));
27865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mInfoSeparatorView.setTextColor(mInfoContainer.getResources().getColor(R.color
27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info_grey, null));
28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mChannelNameView.setTextColor(mInfoContainer.getResources().getColor(R.color
28165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info_grey, null));
28265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mConflictInfoView.setTextColor(mInfoContainer.getResources().getColor(R.color
28365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info_grey, null));
28465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
28565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
28665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        /**
28765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         * Reverse grey out operation.
28865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko         */
28965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public void whiteBackInfo() {
29065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mTimeView.setTextColor(mInfoContainer.getResources().getColor(R.color
29165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info, null));
29265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mProgramTitleView.setTextColor(mInfoContainer.getResources().getColor(R.color
29365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_main, null));
29465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mInfoSeparatorView.setTextColor(mInfoContainer.getResources().getColor(R.color
29565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info, null));
29665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mChannelNameView.setTextColor(mInfoContainer.getResources().getColor(R.color
29765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info, null));
29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mConflictInfoView.setTextColor(mInfoContainer.getResources().getColor(R.color
29965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .dvr_schedules_item_info, null));
30065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
30165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
30265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
30365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public ScheduleRowPresenter(Context context) {
30465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        setHeaderPresenter(null);
30565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        setSelectEffectEnabled(false);
30665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mContext = context;
307d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        mDvrManager = TvApplication.getSingletons(context).getDvrManager();
308d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        mDvrScheduleManager = TvApplication.getSingletons(context).getDvrScheduleManager();
30965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mTunerConflictWillNotBeRecordedInfo = mContext.getString(
31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                R.string.dvr_schedules_tuner_conflict_will_not_be_recorded_info);
31165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mTunerConflictWillBePartiallyRecordedInfo = mContext.getString(
31265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                R.string.dvr_schedules_tuner_conflict_will_be_partially_recorded);
313d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        mAnimationDuration = mContext.getResources().getInteger(
314d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                android.R.integer.config_shortAnimTime);
31565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
31665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
31765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
31865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public ViewHolder createRowViewHolder(ViewGroup parent) {
319d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return onGetScheduleRowViewHolder(LayoutInflater.from(mContext)
320d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .inflate(R.layout.dvr_schedules_item, parent, false));
32165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
32265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
32365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
32465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns context.
32565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
32665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected Context getContext() {
32765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mContext;
32865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
32965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
33065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
331d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Returns DVR manager.
33265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
333d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected DvrManager getDvrManager() {
334d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return mDvrManager;
33565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
33665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
33765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
33865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
33965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        super.onBindRowViewHolder(vh, item);
34065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        ScheduleRowViewHolder viewHolder = (ScheduleRowViewHolder) vh;
341d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        ScheduleRow row = (ScheduleRow) item;
342d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        @ScheduleRowAction int[] actions = getAvailableActions(row);
343d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mActions = actions;
34465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        viewHolder.mInfoContainer.setOnClickListener(new View.OnClickListener() {
34565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            @Override
34665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            public void onClick(View view) {
3476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                if (isInfoClickable(row)) {
3486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    onInfoClicked(row);
3496ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                }
35065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
35165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        });
35265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
353d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mFirstActionContainer.setOnClickListener(new View.OnClickListener() {
35465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            @Override
35565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            public void onClick(View view) {
356d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onActionClicked(actions[0], row);
35765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
35865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        });
35965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
360d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mSecondActionContainer.setOnClickListener(new View.OnClickListener() {
36165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            @Override
36265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            public void onClick(View view) {
363d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onActionClicked(actions[1], row);
36465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
36565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        });
36665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
367d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mTimeView.setText(onGetRecordingTimeText(row));
368d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        String programInfoText = onGetProgramInfoText(row);
36965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (TextUtils.isEmpty(programInfoText)) {
3706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            int durationMins = Math.max(1, Utils.getRoundOffMinsFromMs(row.getDuration()));
37165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            programInfoText = mContext.getResources().getQuantityString(
37265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    R.plurals.dvr_schedules_recording_duration, durationMins, durationMins);
37365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
374d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        String channelName = getChannelNameText(row);
37565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        viewHolder.mProgramTitleView.setText(programInfoText);
37665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        viewHolder.mInfoSeparatorView.setVisibility((!TextUtils.isEmpty(programInfoText)
37765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && !TextUtils.isEmpty(channelName)) ? View.VISIBLE : View.GONE);
37865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        viewHolder.mChannelNameView.setText(channelName);
379d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (actions != null) {
380d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            switch (actions.length) {
381d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                case 2:
382d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mSecondActionView.setImageResource(getImageForAction(actions[1]));
383d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    // pass through
384d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                case 1:
385d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mFirstActionView.setImageResource(getImageForAction(actions[0]));
386d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    break;
38765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
388d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
389d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (mDvrManager.isConflicting(row.getSchedule())) {
390d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            String conflictInfo;
391d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (mDvrScheduleManager.isPartiallyConflicting(row.getSchedule())) {
392d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                conflictInfo = mTunerConflictWillBePartiallyRecordedInfo;
39365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            } else {
394d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                conflictInfo = mTunerConflictWillNotBeRecordedInfo;
39565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
396d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.mConflictInfoView.setText(conflictInfo);
397d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.mConflictInfoView.setVisibility(View.VISIBLE);
398d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
399d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.mConflictInfoView.setVisibility(View.GONE);
400d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
401d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (shouldBeGrayedOut(row)) {
402d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.greyOutInfo();
403d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
404d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.whiteBackInfo();
405d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
4066ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        viewHolder.mInfoContainer.setFocusable(isInfoClickable(row));
407d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        updateActionContainer(viewHolder, viewHolder.isSelected());
408d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
409d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
410d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private int getImageForAction(@ScheduleRowAction int action) {
411d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        switch (action) {
412d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_START_RECORDING:
413d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return R.drawable.ic_record_start;
414d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_STOP_RECORDING:
415d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return R.drawable.ic_record_stop;
416d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_CREATE_SCHEDULE:
417d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return R.drawable.ic_scheduled_recording;
418d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_REMOVE_SCHEDULE:
419d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return R.drawable.ic_dvr_cancel;
420d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            default:
421d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return 0;
42265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
42365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
42465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
42565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
42665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns view holder for schedule row.
42765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
42865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected ScheduleRowViewHolder onGetScheduleRowViewHolder(View view) {
429d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return new ScheduleRowViewHolder(view, this);
43065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
43165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
43265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
43365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns time text for time view from scheduled recording.
43465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
435d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected String onGetRecordingTimeText(ScheduleRow row) {
436d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return Utils.getDurationString(mContext, row.getStartTimeMs(), row.getEndTimeMs(), true,
437d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                false, true, 0);
43865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
43965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
44065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
44165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns program info text for program title view.
44265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
443d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected String onGetProgramInfoText(ScheduleRow row) {
444d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return row.getProgramTitleWithEpisodeNumber(mContext);
44565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
44665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
447d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private String getChannelNameText(ScheduleRow row) {
448d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        Channel channel = TvApplication.getSingletons(mContext).getChannelDataManager()
449d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .getChannel(row.getChannelId());
450d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return channel == null ? null :
451d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                TextUtils.isEmpty(channel.getDisplayName()) ? channel.getDisplayNumber() :
452d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        channel.getDisplayName().trim() + " " + channel.getDisplayNumber();
45365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
45465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
45565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
456d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Called when user click Info in {@link ScheduleRow}.
45765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
4586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    protected void onInfoClicked(ScheduleRow row) {
4596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        DvrUiHelper.startDetailsActivity((Activity) mContext, row.getSchedule(), null, true);
4606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
4616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
4626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private boolean isInfoClickable(ScheduleRow row) {
4636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return row.getSchedule() != null
4646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                && (row.getSchedule().isNotStarted() || row.getSchedule().isInProgress());
46565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
46665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
46765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
468d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Called when the button in a row is clicked.
46965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
470d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onActionClicked(@ScheduleRowAction final int action, ScheduleRow row) {
471d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        switch (action) {
472d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_START_RECORDING:
473d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onStartRecording(row);
474d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                break;
475d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_STOP_RECORDING:
476d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onStopRecording(row);
477d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                break;
478d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_CREATE_SCHEDULE:
479d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onCreateSchedule(row);
480d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                break;
481d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            case ACTION_REMOVE_SCHEDULE:
482d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                onRemoveSchedule(row);
483d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                break;
48465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
48565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
48665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
48765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
488d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Action handler for {@link #ACTION_START_RECORDING}.
48965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
490d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onStartRecording(ScheduleRow row) {
491d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        ScheduledRecording schedule = row.getSchedule();
492d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (schedule == null) {
493d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // This row has been deleted.
49465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return;
49565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
496d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        // Checks if there are current recordings that will be stopped by schedule this program.
497d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        // If so, shows confirmation dialog to users.
498d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        List<ScheduledRecording> conflictSchedules = mDvrScheduleManager.getConflictingSchedules(
499d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                schedule.getChannelId(), System.currentTimeMillis(), schedule.getEndTimeMs());
500d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        for (int i = conflictSchedules.size() - 1; i >= 0; i--) {
501d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ScheduledRecording conflictSchedule = conflictSchedules.get(i);
502d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (conflictSchedule.isInProgress()) {
503d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                DvrUiHelper.showStopRecordingDialog((Activity) mContext,
504d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        conflictSchedule.getChannelId(),
505d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        DvrStopRecordingFragment.REASON_ON_CONFLICT,
506d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        new HalfSizedDialogFragment.OnActionClickListener() {
507d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            @Override
508d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            public void onActionClick(long actionId) {
509d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                if (actionId == DvrStopRecordingFragment.ACTION_STOP) {
510d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                    onStartRecordingInternal(row);
511d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                                }
512d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            }
513d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        });
514d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return;
515d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
51665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
517d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        onStartRecordingInternal(row);
51865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
51965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
520d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void onStartRecordingInternal(ScheduleRow row) {
521d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.isOnAir() && !row.isRecordingInProgress() && !row.isStartRecordingRequested()) {
522d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            row.setStartRecordingRequested(true);
523d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (row.isRecordingNotStarted()) {
524d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.setHighestPriority(row.getSchedule());
525d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else if (row.isRecordingFinished()) {
526d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.addSchedule(ScheduledRecording.buildFrom(row.getSchedule())
527d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setId(ScheduledRecording.ID_NOT_SET)
528d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)
529d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setPriority(mDvrManager.suggestHighestPriority(row.getSchedule()))
530d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .build());
531d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else {
532d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                SoftPreconditions.checkState(false, TAG, "Invalid row state to start recording: "
533d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        + row);
534d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return;
535d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
536d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            String msg = mContext.getString(R.string.dvr_msg_current_program_scheduled,
537d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    row.getSchedule().getProgramTitle(),
538d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    Utils.toTimeString(row.getEndTimeMs(), false));
539d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ToastUtils.show(mContext, msg, Toast.LENGTH_SHORT);
54065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
54165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
54265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
54365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
544d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Action handler for {@link #ACTION_STOP_RECORDING}.
54565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
546d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onStopRecording(ScheduleRow row) {
547d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.getSchedule() == null) {
548d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // This row has been deleted.
549d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
550d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
5516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (row.isRecordingInProgress() && !row.isStopRecordingRequested()) {
552d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            row.setStopRecordingRequested(true);
553d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            mDvrManager.stopRecording(row.getSchedule());
554d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            CharSequence deletedInfo = onGetProgramInfoText(row);
555d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (TextUtils.isEmpty(deletedInfo)) {
556d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                deletedInfo = getChannelNameText(row);
55765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
558d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ToastUtils.show(mContext, mContext.getResources()
559d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    .getString(R.string.dvr_schedules_deletion_info, deletedInfo),
560d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    Toast.LENGTH_SHORT);
56165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
56265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
56365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
56465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
565d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Action handler for {@link #ACTION_CREATE_SCHEDULE}.
56665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
567d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onCreateSchedule(ScheduleRow row) {
568d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.getSchedule() == null) {
569d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // This row has been deleted.
570d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
571d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
572d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (!row.isOnAir()) {
573d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (row.isScheduleCanceled()) {
574d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.updateScheduledRecording(ScheduledRecording.buildFrom(row.getSchedule())
575d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)
576d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setPriority(mDvrManager.suggestHighestPriority(row.getSchedule()))
577d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .build());
578d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                String msg = mContext.getString(R.string.dvr_msg_program_scheduled,
579d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        row.getSchedule().getProgramTitle());
580d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                ToastUtils.show(mContext, msg, Toast.LENGTH_SHORT);
581d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else if (mDvrManager.isConflicting(row.getSchedule())) {
582d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.setHighestPriority(row.getSchedule());
583d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
584d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
58565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
58665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
58765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
588d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Action handler for {@link #ACTION_REMOVE_SCHEDULE}.
58965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
590d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onRemoveSchedule(ScheduleRow row) {
591d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.getSchedule() == null) {
592d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // This row has been deleted.
59365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return;
59465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
595d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        CharSequence deletedInfo = null;
596d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.isOnAir()) {
597d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (row.isRecordingNotStarted()) {
598d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                deletedInfo = getDeletedInfo(row);
599d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.removeScheduledRecording(row.getSchedule());
600d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
601d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
602d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (mDvrManager.isConflicting(row.getSchedule())
603d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    && !shouldKeepScheduleAfterRemoving()) {
604d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                deletedInfo = getDeletedInfo(row);
605d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.removeScheduledRecording(row.getSchedule());
606d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else if (row.isRecordingNotStarted()) {
607d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                deletedInfo = getDeletedInfo(row);
608d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                mDvrManager.updateScheduledRecording(ScheduledRecording.buildFrom(row.getSchedule())
609d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .setState(ScheduledRecording.STATE_RECORDING_CANCELED)
610d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        .build());
611d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
61265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
613d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (deletedInfo != null) {
614d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ToastUtils.show(mContext, mContext.getResources()
615d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            .getString(R.string.dvr_schedules_deletion_info, deletedInfo),
616d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    Toast.LENGTH_SHORT);
61765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
61865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
61965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
620d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private CharSequence getDeletedInfo(ScheduleRow row) {
621d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        CharSequence deletedInfo = onGetProgramInfoText(row);
622d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (TextUtils.isEmpty(deletedInfo)) {
623d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return getChannelNameText(row);
624d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
625d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return deletedInfo;
62665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
62765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
628d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @Override
629d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onRowViewSelected(ViewHolder vh, boolean selected) {
630d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        super.onRowViewSelected(vh, selected);
631d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        updateActionContainer(vh, selected);
63265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
63365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
63465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
635d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Internal method for onRowViewSelected, can be customized by subclass.
63665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
637d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void updateActionContainer(ViewHolder vh, boolean selected) {
638d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        ScheduleRowViewHolder viewHolder = (ScheduleRowViewHolder) vh;
639d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mSecondActionContainer.animate().setListener(null).cancel();
640d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        viewHolder.mFirstActionContainer.animate().setListener(null).cancel();
641d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (selected && viewHolder.mActions != null) {
642d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            switch (viewHolder.mActions.length) {
643d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                case 2:
644d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    prepareShowActionView(viewHolder.mSecondActionContainer);
645d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    prepareShowActionView(viewHolder.mFirstActionContainer);
646d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mPendingAnimationRunnable = new Runnable() {
647d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        @Override
648d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        public void run() {
649d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            showActionView(viewHolder.mSecondActionContainer);
650d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            showActionView(viewHolder.mFirstActionContainer);
651d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        }
652d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    };
653d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    break;
654d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                case 1:
655d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    prepareShowActionView(viewHolder.mFirstActionContainer);
656d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mPendingAnimationRunnable = new Runnable() {
657d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        @Override
658d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        public void run() {
659d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            hideActionView(viewHolder.mSecondActionContainer, View.GONE);
660d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            showActionView(viewHolder.mFirstActionContainer);
661d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        }
662d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    };
663d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    if (mLastFocusedViewId == R.id.action_second_container) {
664d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        mLastFocusedViewId = R.id.info_container;
665d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
666d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    break;
667d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                case 0:
668d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                default:
669d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mPendingAnimationRunnable = new Runnable() {
670d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        @Override
671d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        public void run() {
672d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            hideActionView(viewHolder.mSecondActionContainer, View.GONE);
673d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            hideActionView(viewHolder.mFirstActionContainer, View.GONE);
674d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        }
675d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    };
6766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    mLastFocusedViewId = R.id.info_container;
6776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    SoftPreconditions.checkState(viewHolder.mInfoContainer.isFocusable(), TAG,
6786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                            "No focusable view in this row: " + viewHolder);
679d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    break;
680d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
681d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            View view = viewHolder.view.findViewById(mLastFocusedViewId);
682d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (view != null && view.getVisibility() == View.VISIBLE) {
683d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                // When the row is selected, information container gets the initial focus.
684d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                // To give the focus to the same control as the previous row, we need to call
685d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                // requestFocus() explicitly.
686d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                if (view.hasFocus()) {
687d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    viewHolder.mPendingAnimationRunnable.run();
6886ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                } else if (view.isFocusable()){
689721bd0da688cd552737fbb753a00597f95103b95Adrian Roos                    view.requestFocus();
6906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                } else {
6916ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    viewHolder.view.requestFocus();
69265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
69365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
694d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
695d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            viewHolder.mPendingAnimationRunnable = null;
696d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            hideActionView(viewHolder.mFirstActionContainer, View.GONE);
697d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            hideActionView(viewHolder.mSecondActionContainer, View.GONE);
698d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
699d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
700d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
701d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void prepareShowActionView(View view) {
702d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (view.getVisibility() != View.VISIBLE) {
703d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            view.setAlpha(0.0f);
70465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
705d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        view.setVisibility(View.VISIBLE);
70665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
70765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
70865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
709d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Add animation when view is visible.
71065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
711d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void showActionView(View view) {
712d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        view.animate().alpha(1.0f).setInterpolator(new DecelerateInterpolator())
713d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .setDuration(mAnimationDuration).start();
714d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
71565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
716d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /**
717d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Add animation when view change to invisible.
718d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     */
719d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void hideActionView(View view, int visibility) {
720d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (view.getVisibility() != View.VISIBLE) {
721d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (view.getVisibility() != visibility) {
722d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                view.setVisibility(visibility);
72365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
724d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
72565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
726d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        view.animate().alpha(0.0f).setInterpolator(new DecelerateInterpolator())
727d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .setDuration(mAnimationDuration)
728d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .setListener(new AnimatorListenerAdapter() {
729d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    @Override
730d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    public void onAnimationEnd(Animator animation) {
731d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        view.setVisibility(visibility);
732d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        view.animate().setListener(null);
733d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
734d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }).start();
73565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
73665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
73765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
738d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Returns the available actions according to the row's state. It should be the reverse order
739d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * with that in the screen.
74065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
741d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    @ScheduleRowAction
742d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected int[] getAvailableActions(ScheduleRow row) {
743d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (row.getSchedule() != null) {
7446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (row.isRecordingInProgress()) {
7456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                return new int[]{ACTION_STOP_RECORDING};
7466ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            } else if (row.isOnAir()) {
7476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                if (row.isRecordingNotStarted()) {
748d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    if (canResolveConflict()) {
749d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        // The "START" action can change the conflict states.
750d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_START_RECORDING};
751d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    } else {
752d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        return new int[] {ACTION_REMOVE_SCHEDULE};
753d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
754d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else if (row.isRecordingFinished()) {
755d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    return new int[] {ACTION_START_RECORDING};
756d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else {
757d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    SoftPreconditions.checkState(false, TAG, "Invalid row state in checking the"
758d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            + " available actions(on air): " + row);
759d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
760d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else {
761d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                if (row.isScheduleCanceled()) {
762d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    return new int[] {ACTION_CREATE_SCHEDULE};
763d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else if (mDvrManager.isConflicting(row.getSchedule()) && canResolveConflict()) {
764d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_CREATE_SCHEDULE};
765d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else if (row.isRecordingNotStarted()) {
766d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    return new int[] {ACTION_REMOVE_SCHEDULE};
767d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } else {
768d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    SoftPreconditions.checkState(false, TAG, "Invalid row state in checking the"
769d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            + " available actions(future schedule): " + row);
770d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
771d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
772d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
773d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return null;
77465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
77565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
77665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
777d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Check if the conflict can be resolved in this screen.
77865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
779d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected boolean canResolveConflict() {
780d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return true;
78165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
78265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
78365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
784d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Check if the schedule should be kept after removing it.
78565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
786d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected boolean shouldKeepScheduleAfterRemoving() {
787d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return false;
78865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
78965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
79065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
791d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Checks if the row should be grayed out.
79265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
793d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected boolean shouldBeGrayedOut(ScheduleRow row) {
794d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return row.getSchedule() == null
795d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                || (row.isOnAir() && !row.isRecordingInProgress())
796d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                || mDvrManager.isConflicting(row.getSchedule())
797d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                || row.isScheduleCanceled();
79865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
79965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
800