1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.car.media.drawer;
17
18import android.content.Context;
19import android.support.annotation.Nullable;
20import com.android.car.app.CarDrawerActivity;
21import com.android.car.app.CarDrawerAdapter;
22import com.android.car.app.DrawerItemViewHolder;
23
24/**
25 * Subclass of CarDrawerAdapter used by the Media app.
26 * <p>
27 * This adapter delegates actual fetching of items (and other operations) to a
28 * {@link MediaItemsFetcher}. The current fetcher being used can be updated at runtime.
29 */
30class MediaDrawerAdapter extends CarDrawerAdapter {
31    private final CarDrawerActivity mActivity;
32    private MediaItemsFetcher mCurrentFetcher;
33    private MediaFetchCallback mFetchCallback;
34    private int mCurrentScrollPosition;
35
36    /**
37     * Interface for a callback object that will be notified of changes to the fetch status of
38     * items in a media drawer.
39     */
40    interface MediaFetchCallback {
41        /**
42         * Called when a fetch for items starts.
43         */
44        void onFetchStart();
45
46        /**
47         * Called when a fetch for items ends.
48         */
49        void onFetchEnd();
50    }
51
52    MediaDrawerAdapter(CarDrawerActivity activity) {
53        super(activity, true /* showDisabledListOnEmpty */);
54        mActivity = activity;
55    }
56
57    /**
58     * Sets the object to be notified of changes to the fetching of items in the media drawer.
59     */
60    void setFetchCallback(@Nullable MediaFetchCallback callback) {
61        mFetchCallback = callback;
62    }
63
64    /**
65     * Switch the {@link MediaItemsFetcher} being used to fetch items. The new fetcher is kicked-off
66     * and the drawer's content's will be updated to show newly loaded items. Any old fetcher is
67     * cleaned up and released.
68     *
69     * @param fetcher New {@link MediaItemsFetcher} to use for display Drawer items.
70     */
71    void setFetcher(MediaItemsFetcher fetcher) {
72        if (mCurrentFetcher != null) {
73            mCurrentFetcher.cleanup();
74        }
75        mCurrentFetcher = fetcher;
76        mCurrentFetcher.start(() -> {
77            if (mFetchCallback != null) {
78                mFetchCallback.onFetchEnd();
79            }
80            notifyDataSetChanged();
81        });
82
83        if (mFetchCallback != null) {
84            mFetchCallback.onFetchStart();
85        }
86    }
87
88    @Override
89    protected int getActualItemCount() {
90        return mCurrentFetcher != null ? mCurrentFetcher.getItemCount() : 0;
91    }
92
93    @Override
94    protected boolean usesSmallLayout(int position) {
95        return mCurrentFetcher.usesSmallLayout(position);
96    }
97
98    @Override
99    protected void populateViewHolder(DrawerItemViewHolder holder, int position) {
100        if (mCurrentFetcher == null) {
101            return;
102        }
103
104        mCurrentFetcher.populateViewHolder(holder, position);
105        scrollToCurrent();
106    }
107
108    @Override
109    public void onItemClick(int position) {
110        if (mCurrentFetcher != null) {
111            mCurrentFetcher.onItemClick(position);
112        }
113    }
114
115    @Override
116    public void cleanup() {
117        super.cleanup();
118        if (mCurrentFetcher != null) {
119            mCurrentFetcher.cleanup();
120            mCurrentFetcher = null;
121        }
122        mFetchCallback = null;
123    }
124
125    public void scrollToCurrent() {
126        if (mCurrentFetcher == null) {
127            return;
128        }
129        int scrollPosition = mCurrentFetcher.getScrollPosition();
130        if (scrollPosition != MediaItemsFetcher.DONT_SCROLL
131                && mCurrentScrollPosition != scrollPosition) {
132            mActivity.scrollToPosition(scrollPosition);
133            mCurrentScrollPosition = scrollPosition;
134        }
135    }
136}
137