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
176ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkopackage com.android.tv.dvr.ui.browse;
1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
1965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.Context;
2065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.res.Resources;
2165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.graphics.Bitmap;
2265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.graphics.drawable.BitmapDrawable;
2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.graphics.drawable.Drawable;
24d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.media.tv.TvContentRating;
25d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.net.Uri;
2665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.Bundle;
2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.Nullable;
2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.app.DetailsFragment;
2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.ArrayObjectAdapter;
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.ClassPresenterSelector;
3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.DetailsOverviewRow;
3265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.OnActionClickedListener;
3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.PresenterSelector;
3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.SparseArrayObjectAdapter;
3665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.VerticalGridView;
3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.text.TextUtils;
38d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.widget.Toast;
3965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.R;
41d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.TvApplication;
426ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.common.SoftPreconditions;
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.data.Channel;
44d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.data.ChannelDataManager;
45d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dialog.PinDialogFragment;
466ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.data.RecordedProgram;
486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.ui.DvrUiHelper;
49d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.parental.ParentalControlSettings;
5065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.util.ImageLoader;
51d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.util.ToastUtils;
52d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.util.Utils;
53d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
54d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport java.io.File;
5565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
5665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoabstract class DvrDetailsFragment extends DetailsFragment {
5765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final int LOAD_LOGO_IMAGE = 1;
5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final int LOAD_BACKGROUND_IMAGE = 2;
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected DetailsViewBackgroundHelper mBackgroundHelper;
6165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private ArrayObjectAdapter mRowsAdapter;
6265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private DetailsOverviewRow mDetailsOverview;
6365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
6465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
6565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public void onCreate(Bundle savedInstanceState) {
6665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        super.onCreate(savedInstanceState);
6765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (!onLoadRecordingDetails(getArguments())) {
6865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            getActivity().finish();
6965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return;
7065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
7165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mBackgroundHelper = new DetailsViewBackgroundHelper(getActivity());
7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        setupAdapter();
73d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        onCreateInternal();
7465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
7565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
7665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    @Override
7765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public void onStart() {
7865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        super.onStart();
7965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        // TODO: remove the workaround of b/30401180.
8065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        VerticalGridView container = (VerticalGridView) getActivity()
8165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                .findViewById(R.id.container_list);
8265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        // Need to manually modify offset. Please refer DetailsFragment.setVerticalGridViewLayout.
8365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        container.setItemAlignmentOffset(0);
8465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        container.setWindowAlignmentOffset(
8565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                getResources().getDimensionPixelSize(R.dimen.lb_details_rows_align_top));
8665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
8765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private void setupAdapter() {
89d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        DetailsOverviewRowPresenter rowPresenter = new DetailsOverviewRowPresenter(
90d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                new DetailsContentPresenter(getActivity()));
9165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        rowPresenter.setBackgroundColor(getResources().getColor(R.color.common_tv_background,
9265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                null));
9365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        rowPresenter.setSharedElementEnterTransition(getActivity(),
9465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                DvrDetailsActivity.SHARED_ELEMENT_NAME);
9565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        rowPresenter.setOnActionClickedListener(onCreateOnActionClickedListener());
9665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mRowsAdapter = new ArrayObjectAdapter(onCreatePresenterSelector(rowPresenter));
9765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        setAdapter(mRowsAdapter);
9865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
9965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
10065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Returns details views' rows adapter.
10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected ArrayObjectAdapter getRowsAdapter() {
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return  mRowsAdapter;
10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
10865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Sets details overview.
10965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
11065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected void setDetailsOverviewRow(DetailsContent detailsContent) {
11165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mDetailsOverview = new DetailsOverviewRow(detailsContent);
11265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
11365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mRowsAdapter.add(mDetailsOverview);
11465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        onLoadLogoAndBackgroundImages(detailsContent);
11565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
11665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
11765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
11865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Creates and returns presenter selector will be used by rows adaptor.
11965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
120d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected PresenterSelector onCreatePresenterSelector(
121d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            DetailsOverviewRowPresenter rowPresenter) {
12265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
12365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
12465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return presenterSelector;
12565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
12665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
12765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
128d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * Does customized initialization of subclasses. Since {@link #onCreate(Bundle)} might finish
129d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * activity early when it cannot fetch valid recordings, subclasses' onCreate method should not
130d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * do anything after calling {@link #onCreate(Bundle)}. If there's something subclasses have to
131d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     * do after the super class did onCreate, it should override this method and put the codes here.
132d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko     */
133d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void onCreateInternal() { }
134d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
135d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    /**
13665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Updates actions of details overview.
13765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
13865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected void updateActions() {
13965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
14065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
14165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
14265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
14365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Loads recording details according to the arguments the fragment got.
14465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     *
14565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * @return false if cannot find valid recordings, else return true. If the return value
14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     *         is false, the detail activity and fragment will be ended.
14765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
14865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    abstract boolean onLoadRecordingDetails(Bundle args);
14965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
15065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
15165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Creates actions users can interact with and their adaptor for this fragment.
15265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
15365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    abstract SparseArrayObjectAdapter onCreateActionsAdapter();
15465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
15565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
15665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Creates actions listeners to implement the behavior of the fragment after users click some
15765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * action buttons.
15865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
15965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    abstract OnActionClickedListener onCreateOnActionClickedListener();
16065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
16165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
16265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Loads logo and background images for detail fragments.
16365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
16465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    protected void onLoadLogoAndBackgroundImages(DetailsContent detailsContent) {
16565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        Drawable logoDrawable = null;
16665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        Drawable backgroundDrawable = null;
16765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (TextUtils.isEmpty(detailsContent.getLogoImageUri())) {
16865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            logoDrawable = getContext().getResources()
16965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .getDrawable(R.drawable.dvr_default_poster, null);
17065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mDetailsOverview.setImageDrawable(logoDrawable);
17165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
17265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (TextUtils.isEmpty(detailsContent.getBackgroundImageUri())) {
17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            backgroundDrawable = getContext().getResources()
17465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .getDrawable(R.drawable.dvr_default_poster, null);
17565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mBackgroundHelper.setBackground(backgroundDrawable);
17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (logoDrawable != null && backgroundDrawable != null) {
17865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return;
17965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
18065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (logoDrawable == null && backgroundDrawable == null
18165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                && detailsContent.getLogoImageUri().equals(
18265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                detailsContent.getBackgroundImageUri())) {
18365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
18465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE | LOAD_BACKGROUND_IMAGE,
18565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            getContext()));
18665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return;
18765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
18865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (logoDrawable == null) {
18965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            int imageWidth = getResources().getDimensionPixelSize(R.dimen.dvr_details_poster_width);
19065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            int imageHeight = getResources()
19165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    .getDimensionPixelSize(R.dimen.dvr_details_poster_height);
19265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
19365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    imageWidth, imageHeight,
19465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE, getContext()));
19565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (backgroundDrawable == null) {
19765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            ImageLoader.loadBitmap(getContext(), detailsContent.getBackgroundImageUri(),
19865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    new MyImageLoaderCallback(this, LOAD_BACKGROUND_IMAGE, getContext()));
19965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
20065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
20165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
202d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    protected void startPlayback(RecordedProgram recordedProgram, long seekTimeMs) {
203d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (Utils.isInBundledPackageSet(recordedProgram.getPackageName()) &&
204d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                !isDataUriAccessible(recordedProgram.getDataUri())) {
205d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // Since cleaning RecordedProgram from forgotten storage will take some time,
206d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            // ignore playback until cleaning is finished.
207d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            ToastUtils.show(getContext(),
208d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    getContext().getResources().getString(R.string.dvr_toast_recording_deleted),
209d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    Toast.LENGTH_SHORT);
210d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
211d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
2126ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        long programId = recordedProgram.getId();
213d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        ParentalControlSettings parental = TvApplication.getSingletons(getActivity())
214d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                .getTvInputManagerHelper().getParentalControlSettings();
215d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (!parental.isParentalControlsEnabled()) {
2166ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            DvrUiHelper.startPlaybackActivity(getContext(), programId, seekTimeMs, false);
217d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
218d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
219d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        ChannelDataManager channelDataManager =
220d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                TvApplication.getSingletons(getActivity()).getChannelDataManager();
221d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        Channel channel = channelDataManager.getChannel(recordedProgram.getChannelId());
222d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (channel != null && channel.isLocked()) {
223d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            checkPinToPlay(recordedProgram, seekTimeMs);
224d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
225d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
2266ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        TvContentRating[] ratings = recordedProgram.getContentRatings();
2276ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        TvContentRating blockRatings = parental.getBlockedRating(ratings);
228d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (blockRatings != null) {
229d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            checkPinToPlay(recordedProgram, seekTimeMs);
230d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
2316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            DvrUiHelper.startPlaybackActivity(getContext(), programId, seekTimeMs, false);
232d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
233d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
234d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
235d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private boolean isDataUriAccessible(Uri dataUri) {
236d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (dataUri == null || dataUri.getPath() == null) {
237d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return false;
238d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
239d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        try {
240d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            File recordedProgramPath = new File(dataUri.getPath());
241d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (recordedProgramPath.exists()) {
242d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                return true;
243d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
244d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } catch (SecurityException e) {
245d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
246d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        return false;
247d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
248d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
249d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private void checkPinToPlay(RecordedProgram recordedProgram, long seekTimeMs) {
2506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        SoftPreconditions.checkState(getActivity() instanceof DvrDetailsActivity);
2516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (getActivity() instanceof DvrDetailsActivity) {
2526ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ((DvrDetailsActivity) getActivity()).setOnPinCheckListener(new OnPinCheckedListener() {
2536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                @Override
2546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                public void onPinChecked(boolean checked, int type, String rating) {
2556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    ((DvrDetailsActivity) getActivity()).setOnPinCheckListener(null);
2566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    if (checked && type == PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM) {
2576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                        DvrUiHelper.startPlaybackActivity(getContext(), recordedProgram.getId(),
2586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                                seekTimeMs, true);
259d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
2606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                }
2616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            });
2626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            PinDialogFragment.create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM)
2636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    .show(getActivity().getFragmentManager(), PinDialogFragment.DIALOG_TAG);
264d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
265d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
266d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
26765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static class MyImageLoaderCallback extends
26865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            ImageLoader.ImageLoaderCallback<DvrDetailsFragment> {
26965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private final Context mContext;
27065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        private final int mLoadType;
27165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
27265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public MyImageLoaderCallback(DvrDetailsFragment fragment,
27365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                int loadType, Context context) {
27465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            super(fragment);
27565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mLoadType = loadType;
27665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mContext = context;
27765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
27865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        @Override
28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        public void onBitmapLoaded(DvrDetailsFragment fragment,
28165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                @Nullable Bitmap bitmap) {
28265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            Drawable drawable;
28365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            int loadType = mLoadType;
28465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            if (bitmap == null) {
28565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                Resources res = mContext.getResources();
28665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                drawable = res.getDrawable(R.drawable.dvr_default_poster, null);
28765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if ((loadType & LOAD_BACKGROUND_IMAGE) != 0 && !fragment.isDetached()) {
28865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    loadType &= ~LOAD_BACKGROUND_IMAGE;
28965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    fragment.mBackgroundHelper.setBackgroundColor(
29065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            res.getColor(R.color.dvr_detail_default_background));
29165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    fragment.mBackgroundHelper.setScrim(
29265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                            res.getColor(R.color.dvr_detail_default_background_scrim));
29365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
29465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            } else {
29565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                drawable = new BitmapDrawable(mContext.getResources(), bitmap);
29665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
29765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            if (!fragment.isDetached()) {
29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if ((loadType & LOAD_LOGO_IMAGE) != 0) {
29965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    fragment.mDetailsOverview.setImageDrawable(drawable);
30065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
30165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                if ((loadType & LOAD_BACKGROUND_IMAGE) != 0) {
30265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    fragment.mBackgroundHelper.setBackground(drawable);
30365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                }
30465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            }
30565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
30665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
30765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
308