• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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.testmediaapp;
18 
19 import androidx.annotation.Nullable;
20 
21 import static android.support.v4.media.MediaBrowserCompat.MediaItem.FLAG_PLAYABLE;
22 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
23 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_ID;
24 
25 import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_BROWSABLE_HINT;
26 import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_GRID_ITEM_HINT_VALUE;
27 import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_LIST_ITEM_HINT_VALUE;
28 import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_PLAYABLE_HINT;
29 
30 import android.os.Bundle;
31 import android.support.v4.media.MediaBrowserCompat.MediaItem;
32 import android.support.v4.media.MediaBrowserCompat.MediaItem.Flags;
33 import android.support.v4.media.MediaDescriptionCompat;
34 import android.support.v4.media.MediaMetadataCompat;
35 import android.support.v4.media.session.MediaSessionCompat;
36 import android.support.v4.media.session.MediaSessionCompat.QueueItem;
37 
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 
42 /** Our internal representation of media items. */
43 public class TmaMediaItem {
44 
45     private static final String CUSTOM_ACTION_PREFIX = "com.android.car.media.testmediaapp.";
46 
47     /** The name of each entry is the value used in the json file. */
48     public enum ContentStyle {
49         NONE (0),
50         LIST (CONTENT_STYLE_LIST_ITEM_HINT_VALUE),
51         GRID (CONTENT_STYLE_GRID_ITEM_HINT_VALUE);
52         final int mBundleValue;
ContentStyle(int value)53         ContentStyle(int value) {
54             mBundleValue = value;
55         }
56     }
57 
58     public enum TmaCustomAction {
59         HEART_PLUS_PLUS(CUSTOM_ACTION_PREFIX + "heart_plus_plus", R.string.heart_plus_plus,
60                 R.drawable.ic_heart_plus_plus),
61         HEART_LESS_LESS(CUSTOM_ACTION_PREFIX + "heart_less_less", R.string.heart_less_less,
62                 R.drawable.ic_heart_less_less);
63 
64         final String mId;
65         final int mNameId;
66         final int mIcon;
67 
TmaCustomAction(String id, int name, int icon)68         TmaCustomAction(String id, int name, int icon) {
69             mId = id;
70             mNameId = name;
71             mIcon = icon;
72         }
73 
74     }
75 
76     private final @MediaItem.Flags int mFlags;
77     private final MediaMetadataCompat mMediaMetadata;
78     private final ContentStyle mPlayableStyle;
79     private final ContentStyle mBrowsableStyle;
80 
81     /** Read only list. */
82     final List<TmaMediaItem> mChildren;
83     /** Read only list. */
84     private final List<TmaMediaItem> mPlayableChildren;
85     /** Read only list. */
86     final List<TmaCustomAction> mCustomActions;
87     /** Read only list. Events triggered when starting the playback. */
88     final List<TmaMediaEvent> mMediaEvents;
89     /** References another json file where to get extra children from. */
90     final String mInclude;
91 
92     private @Nullable TmaMediaItem mParent;
93     int mHearts;
94 
95 
TmaMediaItem(@lags int flags, ContentStyle playableStyle, ContentStyle browsableStyle, MediaMetadataCompat metadata, List<TmaCustomAction> customActions, List<TmaMediaEvent> mediaEvents, List<TmaMediaItem> children, String include)96     public TmaMediaItem(@Flags int flags, ContentStyle playableStyle, ContentStyle browsableStyle,
97             MediaMetadataCompat metadata, List<TmaCustomAction> customActions,
98             List<TmaMediaEvent> mediaEvents,
99             List<TmaMediaItem> children, String include) {
100         mFlags = flags;
101         mPlayableStyle = playableStyle;
102         mBrowsableStyle = browsableStyle;
103         mMediaMetadata = metadata;
104         mCustomActions = Collections.unmodifiableList(customActions);
105         mChildren = Collections.unmodifiableList(children);
106         mMediaEvents = Collections.unmodifiableList(mediaEvents);
107         mInclude = include;
108         List<TmaMediaItem> playableChildren = new ArrayList<>(children.size());
109         for (TmaMediaItem child: mChildren) {
110             child.setParent(this);
111             if ((child.mFlags & FLAG_PLAYABLE) != 0) {
112                 playableChildren.add(child);
113             }
114         }
115         mPlayableChildren = Collections.unmodifiableList(playableChildren);
116     }
117 
setParent(@ullable TmaMediaItem parent)118     private void setParent(@Nullable TmaMediaItem parent) {
119         mParent = parent;
120     }
121 
122     @Nullable
getParent()123     TmaMediaItem getParent() {
124         return mParent;
125     }
126 
getPlayableByIndex(long index)127     TmaMediaItem getPlayableByIndex(long index) {
128         return mPlayableChildren.get((int)index);
129     }
130 
131     @Nullable
getPrevious()132     TmaMediaItem getPrevious() {
133         if (mParent == null) return null;
134         List<TmaMediaItem> queueItems = mParent.mPlayableChildren;
135         int myIndex = queueItems.indexOf(this);
136         return (myIndex > 0) ? queueItems.get(myIndex - 1) : null;
137     }
138 
139     @Nullable
getNext()140     TmaMediaItem getNext() {
141         if (mParent == null) return null;
142         List<TmaMediaItem> queueItems = mParent.mPlayableChildren;
143         int myIndex = queueItems.indexOf(this);
144         return (myIndex < queueItems.size() - 1) ? queueItems.get(myIndex + 1) : null;
145     }
146 
getMediaId()147     String getMediaId() {
148         return mMediaMetadata.getString(METADATA_KEY_MEDIA_ID);
149     }
150 
151     /** Returns -1 if the duration key is unspecified or <= 0. */
getDuration()152     long getDuration() {
153         long result = mMediaMetadata.getLong(METADATA_KEY_DURATION);
154         if (result <= 0) return -1;
155         return result;
156     }
157 
append(List<TmaMediaItem> children)158     TmaMediaItem append(List<TmaMediaItem> children) {
159         List<TmaMediaItem> allChildren = new ArrayList<>(mChildren.size() + children.size());
160         allChildren.addAll(mChildren);
161         allChildren.addAll(children);
162         return new TmaMediaItem(mFlags, mPlayableStyle, mBrowsableStyle, mMediaMetadata,
163                 mCustomActions, mMediaEvents, allChildren, null);
164     }
165 
updateSessionMetadata(MediaSessionCompat session)166     void updateSessionMetadata(MediaSessionCompat session) {
167         session.setMetadata(mMediaMetadata);
168     }
169 
toMediaItem()170     MediaItem toMediaItem() {
171         return new MediaItem(buildDescription(), mFlags);
172     }
173 
buildQueue()174     List<QueueItem> buildQueue() {
175         int count = mPlayableChildren.size();
176         List<QueueItem> queue = new ArrayList<>(count);
177         for (int i = 0 ; i < count; i++) {
178             TmaMediaItem child = mPlayableChildren.get(i);
179             queue.add(new QueueItem(child.buildDescription(), i));
180         }
181         return queue;
182     }
183 
184     /** Returns the id of the item in the queue. */
getQueueId()185     long getQueueId() {
186         if (mParent != null) {
187             int index = mParent.mPlayableChildren.indexOf(this);
188             if (index >= 0) return index;
189         }
190         return MediaSessionCompat.QueueItem.UNKNOWN_ID;
191     }
192 
buildDescription()193     private MediaDescriptionCompat buildDescription() {
194 
195         // Use the default media description but add our extras.
196         MediaDescriptionCompat metadataDescription = mMediaMetadata.getDescription();
197 
198         MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder();
199         bob.setMediaId(metadataDescription.getMediaId());
200         bob.setTitle(metadataDescription.getTitle());
201         bob.setSubtitle(metadataDescription.getSubtitle());
202         bob.setDescription(metadataDescription.getDescription());
203         bob.setIconBitmap(metadataDescription.getIconBitmap());
204         bob.setIconUri(metadataDescription.getIconUri());
205         bob.setMediaUri(metadataDescription.getMediaUri());
206 
207         Bundle extras = new Bundle();
208         if (metadataDescription.getExtras() != null) {
209             extras.putAll(metadataDescription.getExtras());
210         }
211 
212         extras.putInt(CONTENT_STYLE_PLAYABLE_HINT, mPlayableStyle.mBundleValue);
213         extras.putInt(CONTENT_STYLE_BROWSABLE_HINT, mBrowsableStyle.mBundleValue);
214 
215         bob.setExtras(extras);
216         return bob.build();
217     }
218 }
219