Prevent concurrent queue modifications from breaking the cast demo app UI
PiperOrigin-RevId: 233577854
This commit is contained in:
parent
3a5ed6b889
commit
55e6d1d708
@ -211,6 +211,7 @@ public class MainActivity extends AppCompatActivity
|
|||||||
private class QueueItemViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
private class QueueItemViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
||||||
|
|
||||||
public final TextView textView;
|
public final TextView textView;
|
||||||
|
public MediaItem item;
|
||||||
|
|
||||||
public QueueItemViewHolder(TextView textView) {
|
public QueueItemViewHolder(TextView textView) {
|
||||||
super(textView);
|
super(textView);
|
||||||
@ -236,8 +237,9 @@ public class MainActivity extends AppCompatActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(QueueItemViewHolder holder, int position) {
|
public void onBindViewHolder(QueueItemViewHolder holder, int position) {
|
||||||
|
holder.item = playerManager.getItem(position);
|
||||||
TextView view = holder.textView;
|
TextView view = holder.textView;
|
||||||
view.setText(playerManager.getItem(position).title);
|
view.setText(holder.item.title);
|
||||||
// TODO: Solve coloring using the theme's ColorStateList.
|
// TODO: Solve coloring using the theme's ColorStateList.
|
||||||
view.setTextColor(ColorUtils.setAlphaComponent(view.getCurrentTextColor(),
|
view.setTextColor(ColorUtils.setAlphaComponent(view.getCurrentTextColor(),
|
||||||
position == playerManager.getCurrentItemIndex() ? 255 : 100));
|
position == playerManager.getCurrentItemIndex() ? 255 : 100));
|
||||||
@ -278,7 +280,8 @@ public class MainActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||||
int position = viewHolder.getAdapterPosition();
|
int position = viewHolder.getAdapterPosition();
|
||||||
if (playerManager.removeItem(position)) {
|
QueueItemViewHolder queueItemHolder = (QueueItemViewHolder) viewHolder;
|
||||||
|
if (playerManager.removeItem(queueItemHolder.item)) {
|
||||||
mediaQueueListAdapter.notifyItemRemoved(position);
|
mediaQueueListAdapter.notifyItemRemoved(position);
|
||||||
// Update whichever item took its place, in case it became the new selected item.
|
// Update whichever item took its place, in case it became the new selected item.
|
||||||
mediaQueueListAdapter.notifyItemChanged(position);
|
mediaQueueListAdapter.notifyItemChanged(position);
|
||||||
@ -289,8 +292,9 @@ public class MainActivity extends AppCompatActivity
|
|||||||
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
|
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
|
||||||
super.clearView(recyclerView, viewHolder);
|
super.clearView(recyclerView, viewHolder);
|
||||||
if (draggingFromPosition != C.INDEX_UNSET) {
|
if (draggingFromPosition != C.INDEX_UNSET) {
|
||||||
|
QueueItemViewHolder queueItemHolder = (QueueItemViewHolder) viewHolder;
|
||||||
// A drag has ended. We reflect the media queue change in the player.
|
// A drag has ended. We reflect the media queue change in the player.
|
||||||
if (!playerManager.moveItem(draggingFromPosition, draggingToPosition)) {
|
if (!playerManager.moveItem(queueItemHolder.item, draggingToPosition)) {
|
||||||
// The move failed. The entire sequence of onMove calls since the drag started needs to be
|
// The move failed. The entire sequence of onMove calls since the drag started needs to be
|
||||||
// invalidated.
|
// invalidated.
|
||||||
mediaQueueListAdapter.notifyDataSetChanged();
|
mediaQueueListAdapter.notifyDataSetChanged();
|
||||||
|
@ -168,10 +168,16 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* Removes the item at the given index from the media queue.
|
* Removes the item at the given index from the media queue.
|
||||||
*
|
*
|
||||||
* @param itemIndex The index of the item to remove.
|
* @param item The item to remove.
|
||||||
* @return Whether the removal was successful.
|
* @return Whether the removal was successful.
|
||||||
*/
|
*/
|
||||||
public boolean removeItem(int itemIndex) {
|
public boolean removeItem(MediaItem item) {
|
||||||
|
int itemIndex = mediaQueue.indexOf(item);
|
||||||
|
if (itemIndex == -1) {
|
||||||
|
// This may happen if another sender app removes items while this sender app is in "swiping
|
||||||
|
// an item" state.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
concatenatingMediaSource.removeMediaSource(itemIndex);
|
concatenatingMediaSource.removeMediaSource(itemIndex);
|
||||||
mediaQueue.remove(itemIndex);
|
mediaQueue.remove(itemIndex);
|
||||||
if (currentPlayer == exoCastPlayer) {
|
if (currentPlayer == exoCastPlayer) {
|
||||||
@ -188,20 +194,29 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* Moves an item within the queue.
|
* Moves an item within the queue.
|
||||||
*
|
*
|
||||||
* @param fromIndex The index of the item to move.
|
* @param item The item to move. This method does nothing if {@code item} is not contained in the
|
||||||
* @param toIndex The target index of the item in the queue.
|
* queue.
|
||||||
* @return Whether the item move was successful.
|
* @param toIndex The target index of the item in the queue. If {@code toIndex} exceeds the last
|
||||||
|
* position in the queue, {@code toIndex} is clamped to match the largest possible value.
|
||||||
|
* @return True if {@code item} was contained in the queue, and {@code toIndex} was a valid
|
||||||
|
* position. False otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean moveItem(int fromIndex, int toIndex) {
|
public boolean moveItem(MediaItem item, int toIndex) {
|
||||||
mediaQueue.add(toIndex, mediaQueue.remove(fromIndex));
|
int indexOfItem = mediaQueue.indexOf(item);
|
||||||
concatenatingMediaSource.moveMediaSource(fromIndex, toIndex);
|
if (indexOfItem == -1) {
|
||||||
if (currentPlayer == exoCastPlayer) {
|
// This may happen if another sender app removes items while this sender app is in "dragging
|
||||||
exoCastPlayer.moveItemInQueue(fromIndex, toIndex);
|
// an item" state.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int clampedToIndex = Math.min(toIndex, mediaQueue.size() - 1);
|
||||||
|
mediaQueue.add(clampedToIndex, mediaQueue.remove(indexOfItem));
|
||||||
|
concatenatingMediaSource.moveMediaSource(indexOfItem, clampedToIndex);
|
||||||
|
if (currentPlayer == exoCastPlayer) {
|
||||||
|
exoCastPlayer.moveItemInQueue(indexOfItem, clampedToIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index update.
|
// Index update.
|
||||||
maybeSetCurrentItemAndNotify(currentPlayer.getCurrentWindowIndex());
|
maybeSetCurrentItemAndNotify(currentPlayer.getCurrentWindowIndex());
|
||||||
return true;
|
return clampedToIndex == toIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Miscellaneous methods.
|
// Miscellaneous methods.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user