1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.annotation.CallbackExecutor;
20import android.annotation.NonNull;
21import android.annotation.Nullable;
22import android.content.Context;
23import android.media.MediaLibraryService2.MediaLibrarySession;
24import android.media.MediaSession2.ControllerInfo;
25import android.media.update.ApiLoader;
26import android.media.update.MediaBrowser2Provider;
27import android.os.Bundle;
28
29import java.util.List;
30import java.util.concurrent.Executor;
31
32/**
33 * @hide
34 * Browses media content offered by a {@link MediaLibraryService2}.
35 */
36public class MediaBrowser2 extends MediaController2 {
37    // Equals to the ((MediaBrowser2Provider) getProvider())
38    private final MediaBrowser2Provider mProvider;
39
40    /**
41     * Callback to listen events from {@link MediaLibraryService2}.
42     */
43    public static class BrowserCallback extends MediaController2.ControllerCallback {
44        /**
45         * Called with the result of {@link #getLibraryRoot(Bundle)}.
46         * <p>
47         * {@code rootMediaId} and {@code rootExtra} can be {@code null} if the library root isn't
48         * available.
49         *
50         * @param browser the browser for this event
51         * @param rootHints rootHints that you previously requested.
52         * @param rootMediaId media id of the library root. Can be {@code null}
53         * @param rootExtra extra of the library root. Can be {@code null}
54         */
55        public void onGetLibraryRootDone(@NonNull MediaBrowser2 browser, @Nullable Bundle rootHints,
56                @Nullable String rootMediaId, @Nullable Bundle rootExtra) { }
57
58        /**
59         * Called when there's change in the parent's children.
60         * <p>
61         * This API is called when the library service called
62         * {@link MediaLibrarySession#notifyChildrenChanged(ControllerInfo, String, int, Bundle)} or
63         * {@link MediaLibrarySession#notifyChildrenChanged(String, int, Bundle)} for the parent.
64         *
65         * @param browser the browser for this event
66         * @param parentId parent id that you've specified with {@link #subscribe(String, Bundle)}
67         * @param itemCount number of children
68         * @param extras extra bundle from the library service. Can be differ from extras that
69         *               you've specified with {@link #subscribe(String, Bundle)}.
70         */
71        public void onChildrenChanged(@NonNull MediaBrowser2 browser, @NonNull String parentId,
72                int itemCount, @Nullable Bundle extras) { }
73
74        /**
75         * Called when the list of items has been returned by the library service for the previous
76         * {@link MediaBrowser2#getChildren(String, int, int, Bundle)}.
77         *
78         * @param browser the browser for this event
79         * @param parentId parent id
80         * @param page page number that you've specified with
81         *             {@link #getChildren(String, int, int, Bundle)}
82         * @param pageSize page size that you've specified with
83         *                 {@link #getChildren(String, int, int, Bundle)}
84         * @param result result. Can be {@code null}
85         * @param extras extra bundle from the library service
86         */
87        public void onGetChildrenDone(@NonNull MediaBrowser2 browser, @NonNull String parentId,
88                int page, int pageSize, @Nullable List<MediaItem2> result,
89                @Nullable Bundle extras) { }
90
91        /**
92         * Called when the item has been returned by the library service for the previous
93         * {@link MediaBrowser2#getItem(String)} call.
94         * <p>
95         * Result can be null if there had been error.
96         *
97         * @param browser the browser for this event
98         * @param mediaId media id
99         * @param result result. Can be {@code null}
100         */
101        public void onGetItemDone(@NonNull MediaBrowser2 browser, @NonNull String mediaId,
102                @Nullable MediaItem2 result) { }
103
104        /**
105         * Called when there's change in the search result requested by the previous
106         * {@link MediaBrowser2#search(String, Bundle)}.
107         *
108         * @param browser the browser for this event
109         * @param query search query that you've specified with {@link #search(String, Bundle)}
110         * @param itemCount The item count for the search result
111         * @param extras extra bundle from the library service
112         */
113        public void onSearchResultChanged(@NonNull MediaBrowser2 browser, @NonNull String query,
114                int itemCount, @Nullable Bundle extras) { }
115
116        /**
117         * Called when the search result has been returned by the library service for the previous
118         * {@link MediaBrowser2#getSearchResult(String, int, int, Bundle)}.
119         * <p>
120         * Result can be null if there had been error.
121         *
122         * @param browser the browser for this event
123         * @param query search query that you've specified with
124         *              {@link #getSearchResult(String, int, int, Bundle)}
125         * @param page page number that you've specified with
126         *             {@link #getSearchResult(String, int, int, Bundle)}
127         * @param pageSize page size that you've specified with
128         *                 {@link #getSearchResult(String, int, int, Bundle)}
129         * @param result result. Can be {@code null}.
130         * @param extras extra bundle from the library service
131         */
132        public void onGetSearchResultDone(@NonNull MediaBrowser2 browser, @NonNull String query,
133                int page, int pageSize, @Nullable List<MediaItem2> result,
134                @Nullable Bundle extras) { }
135    }
136
137    public MediaBrowser2(@NonNull Context context, @NonNull SessionToken2 token,
138            @NonNull @CallbackExecutor Executor executor, @NonNull BrowserCallback callback) {
139        super(context, token, executor, callback);
140        mProvider = (MediaBrowser2Provider) getProvider();
141    }
142
143    @Override
144    MediaBrowser2Provider createProvider(Context context, SessionToken2 token,
145            Executor executor, ControllerCallback callback) {
146        return ApiLoader.getProvider().createMediaBrowser2(
147                context, this, token, executor, (BrowserCallback) callback);
148    }
149
150    /**
151     * Get the library root. Result would be sent back asynchronously with the
152     * {@link BrowserCallback#onGetLibraryRootDone(MediaBrowser2, Bundle, String, Bundle)}.
153     *
154     * @param rootHints hint for the root
155     * @see BrowserCallback#onGetLibraryRootDone(MediaBrowser2, Bundle, String, Bundle)
156     */
157    public void getLibraryRoot(@Nullable Bundle rootHints) {
158        mProvider.getLibraryRoot_impl(rootHints);
159    }
160
161    /**
162     * Subscribe to a parent id for the change in its children. When there's a change,
163     * {@link BrowserCallback#onChildrenChanged(MediaBrowser2, String, int, Bundle)} will be called
164     * with the bundle that you've specified. You should call
165     * {@link #getChildren(String, int, int, Bundle)} to get the actual contents for the parent.
166     *
167     * @param parentId parent id
168     * @param extras extra bundle
169     */
170    public void subscribe(@NonNull String parentId, @Nullable Bundle extras) {
171        mProvider.subscribe_impl(parentId, extras);
172    }
173
174    /**
175     * Unsubscribe for changes to the children of the parent, which was previously subscribed with
176     * {@link #subscribe(String, Bundle)}.
177     * <p>
178     * This unsubscribes all previous subscription with the parent id, regardless of the extra
179     * that was previously sent to the library service.
180     *
181     * @param parentId parent id
182     */
183    public void unsubscribe(@NonNull String parentId) {
184        mProvider.unsubscribe_impl(parentId);
185    }
186
187    /**
188     * Get list of children under the parent. Result would be sent back asynchronously with the
189     * {@link BrowserCallback#onGetChildrenDone(MediaBrowser2, String, int, int, List, Bundle)}.
190     *
191     * @param parentId parent id for getting the children.
192     * @param page page number to get the result. Starts from {@code 1}
193     * @param pageSize page size. Should be greater or equal to {@code 1}
194     * @param extras extra bundle
195     */
196    public void getChildren(@NonNull String parentId, int page, int pageSize,
197            @Nullable Bundle extras) {
198        mProvider.getChildren_impl(parentId, page, pageSize, extras);
199    }
200
201    /**
202     * Get the media item with the given media id. Result would be sent back asynchronously with the
203     * {@link BrowserCallback#onGetItemDone(MediaBrowser2, String, MediaItem2)}.
204     *
205     * @param mediaId media id for specifying the item
206     */
207    public void getItem(@NonNull String mediaId) {
208        mProvider.getItem_impl(mediaId);
209    }
210
211    /**
212     * Send a search request to the library service. When the search result is changed,
213     * {@link BrowserCallback#onSearchResultChanged(MediaBrowser2, String, int, Bundle)} will be
214     * called. You should call {@link #getSearchResult(String, int, int, Bundle)} to get the actual
215     * search result.
216     *
217     * @param query search query. Should not be an empty string.
218     * @param extras extra bundle
219     */
220    public void search(@NonNull String query, @Nullable Bundle extras) {
221        mProvider.search_impl(query, extras);
222    }
223
224    /**
225     * Get the search result from lhe library service. Result would be sent back asynchronously with
226     * the
227     * {@link BrowserCallback#onGetSearchResultDone(MediaBrowser2, String, int, int, List, Bundle)}.
228     *
229     * @param query search query that you've specified with {@link #search(String, Bundle)}
230     * @param page page number to get search result. Starts from {@code 1}
231     * @param pageSize page size. Should be greater or equal to {@code 1}
232     * @param extras extra bundle
233     */
234    public void getSearchResult(@NonNull String query, int page, int pageSize,
235            @Nullable Bundle extras) {
236        mProvider.getSearchResult_impl(query, page, pageSize, extras);
237    }
238}
239