• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.car.media.widgets;
2 
3 import android.car.drivingstate.CarUxRestrictions;
4 import android.content.Context;
5 import android.content.Intent;
6 import android.graphics.drawable.Drawable;
7 import android.view.View;
8 
9 import androidx.annotation.NonNull;
10 import androidx.annotation.Nullable;
11 
12 import com.android.car.media.R;
13 import com.android.car.media.common.MediaItemMetadata;
14 import com.android.car.media.common.source.MediaSource;
15 import com.android.car.ui.toolbar.MenuItem;
16 import com.android.car.ui.toolbar.Toolbar;
17 import com.android.car.ui.toolbar.ToolbarController;
18 
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.Objects;
22 
23 /**
24  * Media template application bar. The callers should set properties via the public methods (e.g.,
25  * {@link #setItems}, {@link #setTitle}, {@link #setHasSettings}), and set the visibility of the
26  * views via {@link #setState}. A detailed explanation of all possible states of this application
27  * bar can be seen at {@link Toolbar.State}.
28  */
29 public class AppBarController {
30 
31     private static final int MEDIA_UX_RESTRICTION_DEFAULT =
32             CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP;
33     private static final int MEDIA_UX_RESTRICTION_NONE = CarUxRestrictions.UX_RESTRICTIONS_BASELINE;
34 
35     private int mMaxTabs;
36     private final ToolbarController mToolbarController;
37 
38     private final boolean mUseSourceLogoForAppSelector;
39 
40     @NonNull
41     private AppBarListener mListener = new AppBarListener();
42     private MenuItem mSearch;
43     private MenuItem mSettings;
44     private MenuItem mEqualizer;
45     private MenuItem mAppSelector;
46 
47     private boolean mSearchSupported;
48     private boolean mShowSearchIfSupported;
49     private String mSearchQuery;
50 
51     private Intent mAppSelectorIntent;
52 
53     /**
54      * Application bar listener
55      */
56     public static class AppBarListener {
57         /**
58          * Invoked when the user selects an item from the tabs
59          */
onTabSelected(MediaItemMetadata item)60         protected void onTabSelected(MediaItemMetadata item) {}
61 
62         /**
63          * Invoked when the user clicks on the settings button.
64          */
onSettingsSelection()65         protected void onSettingsSelection() {}
66 
67         /**
68          * Invoked when the user clicks on the equalizer button.
69          */
onEqualizerSelection()70         protected void onEqualizerSelection() {}
71 
72         /**
73          * Invoked when the user submits a search query.
74          */
onSearch(String query)75         protected void onSearch(String query) {}
76 
77         /**
78          * Invoked when the user clicks on the search button
79          */
onSearchSelection()80         protected void onSearchSelection() {}
81     }
82 
AppBarController(Context context, ToolbarController controller)83     public AppBarController(Context context, ToolbarController controller) {
84         mToolbarController = controller;
85         mMaxTabs = context.getResources().getInteger(R.integer.max_tabs);
86 
87         mUseSourceLogoForAppSelector =
88                 context.getResources().getBoolean(R.bool.use_media_source_logo_for_app_selector);
89 
90         mAppSelectorIntent = MediaSource.getSourceSelectorIntent(context, false);
91 
92         mToolbarController.registerOnTabSelectedListener(tab ->
93                 mListener.onTabSelected(((MediaItemTab) tab).getItem()));
94         mToolbarController.registerOnSearchListener(query -> {
95             mSearchQuery = query;
96             mListener.onSearch(query);
97         });
98         mToolbarController.registerOnSearchCompletedListener(
99                 () -> mListener.onSearch(mSearchQuery));
100         mSearch = MenuItem.builder(context)
101                 .setToSearch()
102                 .setOnClickListener(v -> mListener.onSearchSelection())
103                 .build();
104         mSettings = MenuItem.builder(context)
105                 .setToSettings()
106                 .setUxRestrictions(MEDIA_UX_RESTRICTION_DEFAULT)
107                 .setOnClickListener(v -> mListener.onSettingsSelection())
108                 .build();
109         mEqualizer = MenuItem.builder(context)
110                 .setTitle(R.string.menu_item_sound_settings_title)
111                 .setIcon(R.drawable.ic_equalizer)
112                 .setOnClickListener(v -> mListener.onEqualizerSelection())
113                 .build();
114         mAppSelector = MenuItem.builder(context)
115                 .setTitle(R.string.menu_item_app_selector_title)
116                 .setTinted(!mUseSourceLogoForAppSelector)
117                 .setIcon(mUseSourceLogoForAppSelector
118                         ? null : context.getDrawable(R.drawable.ic_app_switch))
119                 .setOnClickListener(m -> context.startActivity(mAppSelectorIntent))
120                 .build();
121         mToolbarController.setMenuItems(
122                 Arrays.asList(mSearch, mEqualizer, mSettings, mAppSelector));
123 
124         setAppLauncherSupported(mAppSelectorIntent != null);
125     }
126 
127     /**
128      * Sets a listener of this application bar events. In order to avoid memory leaks, consumers
129      * must reset this reference by setting the listener to null.
130      */
setListener(AppBarListener listener)131     public void setListener(AppBarListener listener) {
132         mListener = listener;
133     }
134 
135     /**
136      * Updates the list of items to show in the application bar tabs.
137      *
138      * @param items list of tabs to show, or null if no tabs should be shown.
139      */
setItems(@ullable List<MediaItemMetadata> items)140     public void setItems(@Nullable List<MediaItemMetadata> items) {
141         mToolbarController.clearAllTabs();
142 
143         if (items != null && !items.isEmpty()) {
144             int count = 0;
145             for (MediaItemMetadata item : items) {
146                 mToolbarController.addTab(new MediaItemTab(item));
147 
148                 count++;
149                 if (count >= mMaxTabs) {
150                     break;
151                 }
152             }
153         }
154     }
155 
156     /** Sets whether the source has settings (not all screens show it). */
setHasSettings(boolean hasSettings)157     public void setHasSettings(boolean hasSettings) {
158         mSettings.setVisible(hasSettings);
159     }
160 
161     /** Sets whether the source's settings is distraction optimized. */
setSettingsDistractionOptimized(boolean isDistractionOptimized)162     public void setSettingsDistractionOptimized(boolean isDistractionOptimized) {
163         mSettings.setUxRestrictions(isDistractionOptimized
164                 ? MEDIA_UX_RESTRICTION_NONE
165                 : MEDIA_UX_RESTRICTION_DEFAULT);
166     }
167 
168     /** Sets whether the source has equalizer support. */
setHasEqualizer(boolean hasEqualizer)169     public void setHasEqualizer(boolean hasEqualizer) {
170         mEqualizer.setVisible(hasEqualizer);
171     }
172 
173     /**
174      * Sets whether search is supported
175      */
setSearchSupported(boolean supported)176     public void setSearchSupported(boolean supported) {
177         mSearchSupported = supported;
178         updateSearchVisibility();
179     }
180 
181     /** Sets whether to show the search MenuItem if supported */
showSearchIfSupported(boolean show)182     public void showSearchIfSupported(boolean show) {
183         mShowSearchIfSupported = show;
184         updateSearchVisibility();
185     }
186 
updateSearchVisibility()187     private void updateSearchVisibility() {
188         mSearch.setVisible(mShowSearchIfSupported && mSearchSupported);
189     }
190 
191     /**
192      * Sets whether launching app selector is supported
193      */
setAppLauncherSupported(boolean supported)194     private void setAppLauncherSupported(boolean supported) {
195         mAppSelector.setVisible(supported);
196     }
197 
198     /**
199      * Updates the currently active item
200      */
setActiveItem(MediaItemMetadata item)201     public void setActiveItem(MediaItemMetadata item) {
202         for (int i = 0; i < mToolbarController.getTabCount(); i++) {
203             MediaItemTab mediaItemTab = (MediaItemTab) mToolbarController.getTab(i);
204             boolean match = item != null && Objects.equals(
205                     item.getId(),
206                     mediaItemTab.getItem().getId());
207             if (match) {
208                 mToolbarController.selectTab(i);
209                 return;
210             }
211         }
212     }
213 
setSearchQuery(String query)214     public void setSearchQuery(String query) {
215         mToolbarController.setSearchQuery(query);
216     }
217 
setLogo(Drawable drawable)218     public void setLogo(Drawable drawable) {
219         if (mUseSourceLogoForAppSelector) {
220             mAppSelector.setIcon(drawable);
221         } else {
222             mToolbarController.setLogo(drawable);
223         }
224     }
225 
setSearchIcon(Drawable drawable)226     public void setSearchIcon(Drawable drawable) {
227         mToolbarController.setSearchIcon(drawable);
228     }
229 
setTitle(CharSequence title)230     public void setTitle(CharSequence title) {
231         mToolbarController.setTitle(title);
232     }
233 
setTitle(int title)234     public void setTitle(int title) {
235         mToolbarController.setTitle(title);
236     }
237 
setState(Toolbar.State state)238     public void setState(Toolbar.State state) {
239         mToolbarController.setState(state);
240     }
241 
setMenuItems(List<MenuItem> items)242     public void setMenuItems(List<MenuItem> items) {
243         mToolbarController.setMenuItems(items);
244     }
245 
setBackgroundShown(boolean shown)246     public void setBackgroundShown(boolean shown) {
247         mToolbarController.setBackgroundShown(shown);
248     }
249 
setNavButtonMode(Toolbar.NavButtonMode mode)250     public void setNavButtonMode(Toolbar.NavButtonMode mode) {
251         mToolbarController.setNavButtonMode(mode);
252     }
253 
254     /** See {@link ToolbarController#canShowSearchResultItems}. */
canShowSearchResultsView()255     public boolean canShowSearchResultsView() {
256         return mToolbarController.canShowSearchResultsView();
257     }
258 
259     /** See {@link ToolbarController#setSearchResultsView}. */
setSearchResultsView(View view)260     public void setSearchResultsView(View view) {
261         mToolbarController.setSearchResultsView(view);
262     }
263 }
264