MediaQueue

public class MediaQueue extends Object

A data model representation of a media queue of arbitrary length. This class can be used as the basis for an implementation of a ListView for driving a media queue UI.

MediaQueue is attached to a RemoteMediaClient object and has the same lifecycle of the attached RemoteMediaClient. This means MediaQueue is only valid when a Cast session has started or resumed. When there's no Cast session, clients should stop using this class.

It listens for queue change notifications from the attached RemoteMediaClient and updates its internal data model accordingly. Likewise, it uses the attached RemoteMediaClient to fetch queue information on demand.

The model maintains a list of queue item IDs for the entire queue; it automatically fetches this list whenever it attaches to a Cast session. It also maintains an LRU cache (of configurable size) of MediaQueueItems, keyed by the queue item ID. The default cache size is 20. If the UI may display more than 20 items at the same time, it is possible that the items will compete with each other and they keep getting evicted and refetched. To avoid this, increase the cache capacity by calling setCacheCapacity(int).

The method getItemAtIndex(int) is used to fetch a queue item at a given index. If the MediaQueueItem is not currently in the cache, an asynchronous request is made to fetch that item from the receiver, and the listener is eventually notified when the requested items are received.

If multiple calls to this method are made in a very short amount of time, the requested item IDs are batched internally to reduce the number of network requests made. Because there is an upper limit to how many queue items can be fetched from the receiver at a time, MediaQueue keeps a rolling window of the last N item IDs to be fetched. Therefore if a very large number of items is requested in a short amount of time, only the last N items will actually be fetched. This behavior allows for the efficient management of a very long queue in the app's UI which may be quickly and/or frequently scrolled through by a user.

MediaQueue does not provide any methods for directly modifying the queue, because any such change involves an asynchronous network request to the receiver (via methods on RemoteMediaClient), which can potentially fail with an error. MediaQueue must ensure a consistent representation of the queue as it exists on the receiver, so making local changes to the data model which are not yet committed on the receiver could result in incorrect UI behavior.

Generally RemoteMediaClient identifies queue items by their item ID, while MediaQueue keeps tracks the mapping between their item IDs and their indexes. Most of the interfaces presented to the user of MediaQueue are by index, which is convenient for UI purposes.

Nested Class Summary

class MediaQueue.Callback Callback interface for receiving updates from MediaQueue

Public Method Summary

PendingResult<RemoteMediaClient.MediaChannelResult>
fetchMoreItemsRelativeToIndex(int index, int nextCount, int prevCount)
Requests a range of queue item IDs before or after the given index in the queue.
MediaQueueItem
getItemAtIndex(int index)
Returns the MediaQueueItem at the given index.
MediaQueueItem
getItemAtIndex(int index, boolean fetchIfNeeded)
Returns the MediaQueueItem at the given index.
int
getItemCount()
Returns the number of items in the queue.
int[]
getItemIds()
Returns the list of item IDs in the queue.
int
indexOfItemWithId(int itemId)
Looks up the index of a queue item in the queue.
int
itemIdAtIndex(int index)
Returns the item ID of the item at the given index in the queue.
void
registerCallback(MediaQueue.Callback callback)
Registers a MediaQueue.Callback to receive media queue updates.
void
setCacheCapacity(int capacity)
Sets the capacity of the cache of the queue.
void
unregisterCallback(MediaQueue.Callback callback)
Unregisters a MediaQueue.Callback to stop receiving media queue updates.

Inherited Method Summary

Public Methods

public PendingResult<RemoteMediaClient.MediaChannelResult> fetchMoreItemsRelativeToIndex (int index, int nextCount, int prevCount)

Requests a range of queue item IDs before or after the given index in the queue.

This method is intended to be used when the remote queue is partially full and the sender wants the receiver to fetch more queue items (for example, from the cloud), usually before the beginning of the queue or after the end of the queue. If new items are fetched, the media queue notifies the clients through itemsInsertedInRange(int, int). Note that this method is intended to be used when the UI scrolls to the top or bottom of the queue and the client wants the receiver to fetch more items from the client. Exactly one of nextCount and prevCount must be non-zero.

Parameters
index the index of the item relative to which more items should be fetched
nextCount the maximum number of item IDs to fetch before the index. It can be 0
prevCount the maximum number of item IDs to fetch after the index. It can be 0
Returns

public MediaQueueItem getItemAtIndex (int index)

Returns the MediaQueueItem at the given index.

If the index is out of bounds, returns null.

If the item is not cached, returns null and put the index into the list of item IDs to fetch and arranges for the item to be fetched asynchronously. Calling this method too frequently might make earlier fetches get abandoned.

When the item is fetched, itemsUpdatedAtIndexes(int[]) will be called.

Throws
IllegalStateException if this method is not called on the main thread.

public MediaQueueItem getItemAtIndex (int index, boolean fetchIfNeeded)

Returns the MediaQueueItem at the given index.

If the index is out of bounds, returns null.

If the item is not cached, returns null. If fetchIfNeeded is true, put the index into the list of item IDs to fetch arranges for the item to be fetched asynchronously. Calling this method too frequently might make earlier fetches get abandoned.

When the item is fetched, itemsUpdatedAtIndexes(int[]) will be called.

Parameters
index the index of the MediaQueueItem
fetchIfNeeded whether to fetch the MediaQueueItem if it is not cached
Throws
IllegalStateException if this method is not called on the main thread.

public int getItemCount ()

Returns the number of items in the queue.

Throws
IllegalStateException if this method is not called on the main thread.

public int[] getItemIds ()

Returns the list of item IDs in the queue.

Throws
IllegalStateException if this method is not called on the main thread.

public int indexOfItemWithId (int itemId)

Looks up the index of a queue item in the queue. Returns -1 if not found.

Parameters
itemId the queue item ID
Throws
IllegalStateException if this method is not called on the main thread.

public int itemIdAtIndex (int index)

Returns the item ID of the item at the given index in the queue. Returns INVALID_ITEM_ID if the index out of bounds.

Throws
IllegalStateException if this method is not called on the main thread.

public void registerCallback (MediaQueue.Callback callback)

Registers a MediaQueue.Callback to receive media queue updates. Remember to unregister the callback when it's not used to avoid memory leak.

Throws
IllegalStateException if this method is not called on the main thread.

public void setCacheCapacity (int capacity)

Sets the capacity of the cache of the queue.

Throws
IllegalStateException if this method is not called on the main thread.

public void unregisterCallback (MediaQueue.Callback callback)

Unregisters a MediaQueue.Callback to stop receiving media queue updates.

Throws
IllegalStateException if this method is not called on the main thread.