blob: 5c53d34f0ca25642b3d1c81f254f7c3d83b26a2a [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.media.testmediaapp;
import androidx.annotation.Nullable;
import static android.support.v4.media.MediaBrowserCompat.MediaItem.FLAG_PLAYABLE;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_ID;
import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_BROWSABLE_HINT;
import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_GRID_ITEM_HINT_VALUE;
import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_LIST_ITEM_HINT_VALUE;
import static com.android.car.media.common.MediaConstants.CONTENT_STYLE_PLAYABLE_HINT;
import android.os.Bundle;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.MediaSessionCompat.QueueItem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/** Our internal representation of media items. */
public class TmaMediaItem {
private static final String CUSTOM_ACTION_PREFIX = "com.android.car.media.testmediaapp.";
/** The name of each entry is the value used in the json file. */
public enum ContentStyle {
NONE (0),
LIST (CONTENT_STYLE_LIST_ITEM_HINT_VALUE),
GRID (CONTENT_STYLE_GRID_ITEM_HINT_VALUE);
final int mBundleValue;
ContentStyle(int value) {
mBundleValue = value;
}
}
public enum TmaCustomAction {
HEART_PLUS_PLUS(CUSTOM_ACTION_PREFIX + "heart_plus_plus", R.string.heart_plus_plus,
R.drawable.ic_heart_plus_plus),
HEART_LESS_LESS(CUSTOM_ACTION_PREFIX + "heart_less_less", R.string.heart_less_less,
R.drawable.ic_heart_less_less);
final String mId;
final int mNameId;
final int mIcon;
TmaCustomAction(String id, int name, int icon) {
mId = id;
mNameId = name;
mIcon = icon;
}
}
private final int mFlags;
private final MediaMetadataCompat mMediaMetadata;
private final ContentStyle mPlayableStyle;
private final ContentStyle mBrowsableStyle;
/** Read only list. */
final List<TmaMediaItem> mChildren;
/** Read only list. */
private final List<TmaMediaItem> mPlayableChildren;
/** Read only list. */
final List<TmaCustomAction> mCustomActions;
/** Read only list. Events triggered when starting the playback. */
final List<TmaMediaEvent> mMediaEvents;
/** References another json file where to get extra children from. */
final String mInclude;
private @Nullable TmaMediaItem mParent;
int mHearts;
public TmaMediaItem(int flags, ContentStyle playableStyle, ContentStyle browsableStyle,
MediaMetadataCompat metadata, List<TmaCustomAction> customActions,
List<TmaMediaEvent> mediaEvents,
List<TmaMediaItem> children, String include) {
mFlags = flags;
mPlayableStyle = playableStyle;
mBrowsableStyle = browsableStyle;
mMediaMetadata = metadata;
mCustomActions = Collections.unmodifiableList(customActions);
mChildren = Collections.unmodifiableList(children);
mMediaEvents = Collections.unmodifiableList(mediaEvents);
mInclude = include;
List<TmaMediaItem> playableChildren = new ArrayList<>(children.size());
for (TmaMediaItem child: mChildren) {
child.setParent(this);
if ((child.mFlags & FLAG_PLAYABLE) != 0) {
playableChildren.add(child);
}
}
mPlayableChildren = Collections.unmodifiableList(playableChildren);
}
private void setParent(@Nullable TmaMediaItem parent) {
mParent = parent;
}
@Nullable
TmaMediaItem getParent() {
return mParent;
}
@Nullable
TmaMediaItem getPlayableByIndex(long index) {
if (index < 0 || index >= mPlayableChildren.size()) {
return null;
}
return mPlayableChildren.get((int)index);
}
@Nullable
TmaMediaItem getPrevious() {
if (mParent == null) return null;
List<TmaMediaItem> queueItems = mParent.mPlayableChildren;
int myIndex = queueItems.indexOf(this);
return (myIndex > 0) ? queueItems.get(myIndex - 1) : null;
}
@Nullable
TmaMediaItem getNext() {
if (mParent == null) return null;
List<TmaMediaItem> queueItems = mParent.mPlayableChildren;
int myIndex = queueItems.indexOf(this);
return (myIndex < queueItems.size() - 1) ? queueItems.get(myIndex + 1) : null;
}
String getMediaId() {
return mMediaMetadata.getString(METADATA_KEY_MEDIA_ID);
}
/** Returns -1 if the duration key is unspecified or <= 0. */
long getDuration() {
long result = mMediaMetadata.getLong(METADATA_KEY_DURATION);
if (result <= 0) return -1;
return result;
}
TmaMediaItem append(List<TmaMediaItem> children) {
List<TmaMediaItem> allChildren = new ArrayList<>(mChildren.size() + children.size());
allChildren.addAll(mChildren);
allChildren.addAll(children);
return new TmaMediaItem(mFlags, mPlayableStyle, mBrowsableStyle, mMediaMetadata,
mCustomActions, mMediaEvents, allChildren, null);
}
void updateSessionMetadata(MediaSessionCompat session) {
session.setMetadata(mMediaMetadata);
}
MediaItem toMediaItem() {
return new MediaItem(buildDescription(), mFlags);
}
List<QueueItem> buildQueue() {
int count = mPlayableChildren.size();
List<QueueItem> queue = new ArrayList<>(count);
for (int i = 0 ; i < count; i++) {
TmaMediaItem child = mPlayableChildren.get(i);
queue.add(new QueueItem(child.buildDescription(), i));
}
return queue;
}
/** Returns the id of the item in the queue. */
long getQueueId() {
if (mParent != null) {
int index = mParent.mPlayableChildren.indexOf(this);
if (index >= 0) return index;
}
return MediaSessionCompat.QueueItem.UNKNOWN_ID;
}
private MediaDescriptionCompat buildDescription() {
// Use the default media description but add our extras.
MediaDescriptionCompat metadataDescription = mMediaMetadata.getDescription();
MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder();
bob.setMediaId(metadataDescription.getMediaId());
bob.setTitle(metadataDescription.getTitle());
bob.setSubtitle(metadataDescription.getSubtitle());
bob.setDescription(metadataDescription.getDescription());
bob.setIconBitmap(metadataDescription.getIconBitmap());
bob.setIconUri(metadataDescription.getIconUri());
bob.setMediaUri(metadataDescription.getMediaUri());
Bundle extras = new Bundle();
if (metadataDescription.getExtras() != null) {
extras.putAll(metadataDescription.getExtras());
}
extras.putInt(CONTENT_STYLE_PLAYABLE_HINT, mPlayableStyle.mBundleValue);
extras.putInt(CONTENT_STYLE_BROWSABLE_HINT, mBrowsableStyle.mBundleValue);
bob.setExtras(extras);
return bob.build();
}
}