• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.car.media.common.browse;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.UiThread;
22 import android.support.v4.media.MediaBrowserCompat;
23 
24 import androidx.lifecycle.LiveData;
25 import androidx.lifecycle.ViewModelProvider;
26 
27 import com.android.car.arch.common.FutureData;
28 import com.android.car.media.common.MediaItemMetadata;
29 import com.android.car.media.common.source.MediaSourceViewModel;
30 
31 import java.util.List;
32 
33 /**
34  * Contains observable data needed for displaying playback and browse UI. Instances can be obtained
35  * via {@link MediaBrowserViewModel.Factory}
36  */
37 public interface MediaBrowserViewModel {
38 
39     /**
40      * Possible states of the application UI
41      */
42     enum BrowseState {
43         /** There is no content to show */
44         EMPTY,
45         /** We are still in the process of obtaining data */
46         LOADING,
47         /** Data has been loaded */
48         LOADED,
49         /** The content can't be shown due an error */
50         ERROR
51     }
52 
53     /**
54      * Returns a LiveData that emits the current package name of the browser's service component.
55      */
getPackageName()56     LiveData<String> getPackageName();
57 
58     /**
59      * Returns a LiveData that emits the current {@link BrowseState}
60      */
getBrowseState()61     LiveData<BrowseState> getBrowseState();
62 
63 
64     /**
65      * Fetches the MediaItemMetadatas for the current browsed id, and the loading status of the
66      * fetch operation.
67      *
68      * This LiveData will never emit {@code null}. If the data is loading, the data component of the
69      * {@link FutureData} will be null
70      * A MediaSource must be selected and its MediaBrowser connected, otherwise the FutureData will
71      * always contain a {@code null} data value.
72      *
73      * @return a LiveData that emits a FutureData that contains the loading status and the
74      * MediaItemMetadatas for the current browsed id
75      */
getBrowsedMediaItems()76     LiveData<FutureData<List<MediaItemMetadata>>> getBrowsedMediaItems();
77 
78     /**
79      * Fetches the MediaItemMetadatas for the current search query, and the loading status of the
80      * fetch operation.
81      *
82      * See {@link #getBrowsedMediaItems()}
83      */
getSearchedMediaItems()84     LiveData<FutureData<List<MediaItemMetadata>>> getSearchedMediaItems();
85 
86 
87     /**
88      * Returns a LiveData that emits whether the media browser supports search. This wil never emit
89      * {@code null}
90      */
supportsSearch()91     LiveData<Boolean> supportsSearch();
92 
93     /**
94      * Gets the content style display type of browsable elements in this media browser, set at the
95      * browse root
96      */
rootBrowsableHint()97     LiveData<Integer> rootBrowsableHint();
98 
99     /**
100      * Gets the content style display type of playable elements in this media browser, set at the
101      * browse root
102      */
rootPlayableHint()103     LiveData<Integer> rootPlayableHint();
104 
105     /**
106      * A {@link MediaBrowserViewModel} whose selected browse ID may be changed.
107      */
108     interface WithMutableBrowseId extends MediaBrowserViewModel {
109 
110         /**
111          * Set the current item to be browsed. If available, the list of items will be emitted by
112          * {@link #getBrowsedMediaItems()}.
113          */
114         @UiThread
setCurrentBrowseId(@ullable String browseId)115         void setCurrentBrowseId(@Nullable String browseId);
116 
117         /**
118          * Set the current item to be searched for. If available, the list of items will be emitted
119          * by {@link #getBrowsedMediaItems()}.
120          */
121         @UiThread
search(@ullable String query)122         void search(@Nullable String query);
123     }
124 
125     /**
126      * Creates and/or fetches {@link MediaBrowserViewModel} instances.
127      */
128     class Factory {
129 
130         private static final String KEY_BROWSER_ROOT =
131                 "com.android.car.media.common.browse.MediaBrowserViewModel.Factory.browserRoot";
132 
133         /**
134          * Returns an initialized {@link MediaBrowserViewModel.WithMutableBrowseId} with the
135          * provided connected media browser. The provided {@code mediaBrowser} does not need to be
136          * from the same scope as {@code viewModelProvider}.
137          */
138         @NonNull
getInstanceWithMediaBrowser( @onNull ViewModelProvider viewModelProvider, @NonNull LiveData<MediaBrowserCompat> mediaBrowser)139         public static MediaBrowserViewModel.WithMutableBrowseId getInstanceWithMediaBrowser(
140                 @NonNull ViewModelProvider viewModelProvider,
141                 @NonNull LiveData<MediaBrowserCompat> mediaBrowser) {
142             MediaBrowserViewModelImpl viewModel = viewModelProvider.get(
143                     MediaBrowserViewModelImpl.class);
144             initMediaBrowser(mediaBrowser, viewModel);
145             return viewModel;
146         }
147 
148         /**
149          * Fetch an initialized {@link MediaBrowserViewModel.WithMutableBrowseId}. It will get its
150          * media browser from the {@link MediaSourceViewModel} provided by {@code
151          * viewModelProvider}.
152          *
153          *
154          * @param mediaSourceVM     the {@link MediaSourceViewModel} singleton.
155          * @param viewModelProvider the ViewModelProvider to load ViewModels from.
156          * @param key               a key to decide which instance of the ViewModel to fetch.
157          *                          Subsequent calls with the same key will return the same
158          *                          instance.
159          * @return an initialized MediaBrowserViewModel.WithMutableBrowseId for the given key.
160          * @see ViewModelProvider#get(String, Class)
161          */
162         @NonNull
getInstanceForKey( MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider, @NonNull String key)163         public static MediaBrowserViewModel.WithMutableBrowseId getInstanceForKey(
164                 MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider,
165                 @NonNull String key) {
166             MediaBrowserViewModelImpl viewModel = viewModelProvider.get(key,
167                     MediaBrowserViewModelImpl.class);
168             initMediaBrowser(mediaSourceVM.getConnectedMediaBrowser(), viewModel);
169             return viewModel;
170         }
171 
172         /**
173          * Fetch an initialized {@link MediaBrowserViewModel}. It will get its media browser from
174          * the {@link MediaSourceViewModel} provided by {@code viewModelProvider}. It will already
175          * be configured to browse {@code browseId}.
176          *
177          *
178          * @param mediaSourceVM     the {@link MediaSourceViewModel} singleton.
179          * @param viewModelProvider the ViewModelProvider to load ViewModels from.
180          * @param browseId          the browseId to browse. This will also serve as the key for
181          *                          fetching the ViewModel.
182          * @return an initialized MediaBrowserViewModel configured to browse the specified browseId.
183          */
184         @NonNull
getInstanceForBrowseId( MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider, @NonNull String browseId)185         public static MediaBrowserViewModel getInstanceForBrowseId(
186                 MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider,
187                 @NonNull String browseId) {
188             MediaBrowserViewModel.WithMutableBrowseId viewModel =
189                     getInstanceForKey(mediaSourceVM, viewModelProvider, browseId);
190             viewModel.setCurrentBrowseId(browseId);
191             return viewModel;
192         }
193 
194         /**
195          * Fetch an initialized {@link MediaBrowserViewModel}. It will get its media browser from
196          * the {@link MediaSourceViewModel} provided by {@code viewModelProvider}. It will already
197          * be configured to browse the root of the browser.
198          *
199          * @param mediaSourceVM     the {@link MediaSourceViewModel} singleton.
200          * @param viewModelProvider the ViewModelProvider to load ViewModels from.
201          * @return an initialized MediaBrowserViewModel configured to browse the specified browseId.
202          */
203         @NonNull
getInstanceForBrowseRoot( MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider)204         public static MediaBrowserViewModel getInstanceForBrowseRoot(
205                 MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider) {
206             MediaBrowserViewModel.WithMutableBrowseId viewModel =
207                     getInstanceForKey(mediaSourceVM, viewModelProvider, KEY_BROWSER_ROOT);
208             viewModel.setCurrentBrowseId(null);
209             return viewModel;
210         }
211 
initMediaBrowser( @onNull LiveData<MediaBrowserCompat> connectedMediaBrowser, MediaBrowserViewModelImpl viewModel)212         private static void initMediaBrowser(
213                 @NonNull LiveData<MediaBrowserCompat> connectedMediaBrowser,
214                 MediaBrowserViewModelImpl viewModel) {
215             if (viewModel.getMediaBrowserSource() != connectedMediaBrowser) {
216                 viewModel.setConnectedMediaBrowser(connectedMediaBrowser);
217             }
218         }
219     }
220 }
221