diff options
Diffstat (limited to 'src/com/android/car/media/PlaybackFragment.java')
-rw-r--r-- | src/com/android/car/media/PlaybackFragment.java | 241 |
1 files changed, 51 insertions, 190 deletions
diff --git a/src/com/android/car/media/PlaybackFragment.java b/src/com/android/car/media/PlaybackFragment.java index e14dbc8..c5772a5 100644 --- a/src/com/android/car/media/PlaybackFragment.java +++ b/src/com/android/car/media/PlaybackFragment.java @@ -16,6 +16,7 @@ package com.android.car.media; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.os.Bundle; @@ -43,35 +44,34 @@ import com.android.car.media.common.PlaybackModel; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.Objects; +import androidx.car.widget.ListItem; +import androidx.car.widget.ListItemAdapter; +import androidx.car.widget.ListItemProvider; import androidx.car.widget.PagedListView; +import androidx.car.widget.TextListItem; /** * A {@link Fragment} that implements both the playback and the content forward browsing experience. * It observes a {@link PlaybackModel} and updates its information depending on the currently * playing media source through the {@link android.media.session.MediaSession} API. */ -public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer { +public class PlaybackFragment extends Fragment { private static final String TAG = "PlaybackFragment"; private static final DateFormat TIME_FORMAT = new SimpleDateFormat("m:ss", Locale.US); private PlaybackModel mModel; - private CrossfadeImageView mAlbumBackground; private PlaybackControls mPlaybackControls; private ImageView mAlbumArt; private TextView mTitle; private TextView mTime; private TextView mSubtitle; private SeekBar mSeekbar; - private PagedListView mBrowseList; - private int mBackgroundRawImageSize; - private float mBackgroundBlurRadius; - private float mBackgroundBlurScale; - private MediaSource mMediaSource; - private BrowseAdapter mBrowseAdapter; - private ViewGroup mMetadataContainer; + private PagedListView mQueueList; + private QueueItemsAdapter mQueueAdapter; private MediaItemMetadata mCurrentMetadata; private PlaybackModel.PlaybackObserver mPlaybackObserver = new PlaybackModel.PlaybackObserver() { @Override @@ -84,7 +84,6 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer updateState(); updateMetadata(); updateAccentColor(); - updateBrowse(); } @Override @@ -92,24 +91,48 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer updateMetadata(); } }; - private MediaSource.Observer mMediaSourceObserver = new MediaSource.Observer() { + private ListItemProvider mQueueItemsProvider = new ListItemProvider() { @Override - protected void onBrowseConnected(boolean success) { - PlaybackFragment.this.onBrowseConnected(success); + public ListItem get(int position) { + if (!mModel.hasQueue()) { + return null; + } + List<MediaItemMetadata> queue = mModel.getQueue(); + if (position < 0 || position >= queue.size()) { + return null; + } + MediaItemMetadata item = queue.get(position); + TextListItem textListItem = new TextListItem(getContext()); + textListItem.setTitle(item.getTitle().toString()); + textListItem.setBody(item.getSubtitle().toString()); + textListItem.setOnClickListener(v -> onQueueItemClicked(item)); + return textListItem; } - @Override - protected void onBrowseDisconnected() { - PlaybackFragment.this.onBrowseDisconnected(); + public int size() { + if (!mModel.hasQueue()) { + return 0; + } + return mModel.getQueue().size(); } }; + private static class QueueItemsAdapter extends ListItemAdapter { + QueueItemsAdapter(Context context, ListItemProvider itemProvider) { + super(context, itemProvider, BackgroundStyle.SOLID); + } + + void refresh() { + // TODO: Perform a diff between current and new content and trigger the proper + // RecyclerView updates. + this.notifyDataSetChanged(); + } + } @Override public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_playback, container, false); mModel = new PlaybackModel(getContext()); - mAlbumBackground = view.findViewById(R.id.album_background); mPlaybackControls = view.findViewById(R.id.playback_controls); mPlaybackControls.setModel(mModel); ViewGroup playbackContainer = view.findViewById(R.id.playback_container); @@ -119,23 +142,14 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer mSubtitle = view.findViewById(R.id.subtitle); mSeekbar = view.findViewById(R.id.seek_bar); mTime = view.findViewById(R.id.time); - mBrowseList = view.findViewById(R.id.browse_list); - mMetadataContainer = view.findViewById(R.id.metadata_container); - GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4); - RecyclerView recyclerView = mBrowseList.getRecyclerView(); - recyclerView.setLayoutManager(gridLayoutManager); + mQueueList = view.findViewById(R.id.queue_list); + RecyclerView recyclerView = mQueueList.getRecyclerView(); recyclerView.setVerticalFadingEdgeEnabled(true); recyclerView.setFadingEdgeLength(getResources() .getDimensionPixelSize(R.dimen.car_padding_4)); - recyclerView.addItemDecoration(new GridSpacingItemDecoration(getResources() - .getDimensionPixelSize(R.dimen.car_padding_4))); - TypedValue outValue = new TypedValue(); - getResources().getValue(R.dimen.playback_background_blur_radius, outValue, true); - mBackgroundBlurRadius = outValue.getFloat(); - getResources().getValue(R.dimen.playback_background_blur_scale, outValue, true); - mBackgroundBlurScale = outValue.getFloat(); - mBackgroundRawImageSize = getContext().getResources().getDimensionPixelSize( - R.dimen.playback_background_raw_image_size); + mQueueAdapter = new QueueItemsAdapter(getContext(), mQueueItemsProvider); + mQueueList.setAdapter(mQueueAdapter); + return view; } @@ -143,21 +157,13 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer public void onStart() { super.onStart(); mModel.registerObserver(mPlaybackObserver); - if (mMediaSource != null) { - mMediaSource.subscribe(mMediaSourceObserver); - } } @Override public void onStop() { super.onStop(); mModel.unregisterObserver(mPlaybackObserver); - if (mMediaSource != null) { - mMediaSource.unsubscribe(mMediaSourceObserver); - } - if (mBrowseAdapter != null) { - mBrowseAdapter.stop(); - } + mCurrentMetadata = null; } private void updateState() { @@ -168,11 +174,8 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer } else { mSeekbar.removeCallbacks(mSeekBarRunnable); } - mBrowseList.setVisibility(mModel.hasQueue() ? View.VISIBLE : View.GONE); - if (mBrowseAdapter != null) { - mBrowseAdapter.setQueue(mModel.getQueue(), mModel.getQueueTitle()); - } + mQueueAdapter.refresh(); } private void updateMetadata() { @@ -184,23 +187,6 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer mTitle.setText(metadata != null ? metadata.getTitle() : null); mSubtitle.setText(metadata != null ? metadata.getSubtitle() : null); MediaItemMetadata.updateImageView(getContext(), metadata, mAlbumArt, 0); - if (metadata != null) { - metadata.getAlbumArt(getContext(), - mBackgroundRawImageSize, - mBackgroundRawImageSize, - false) - .thenAccept(this::setBackgroundImage); - } else { - mAlbumBackground.setImageBitmap(null, true); - } - } - - private void setBackgroundImage(Bitmap bitmap) { - // TODO(b/77551865): Implement image blurring once the following issue is solved: - // b/77551557 - // bitmap = ImageUtils.blur(getContext(), bitmap, mBackgroundBlurScale, - // mBackgroundBlurRadius); - mAlbumBackground.setImageBitmap(bitmap, true); } private void updateAccentColor() { @@ -237,139 +223,14 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer mSeekbar.setProgress((int) mModel.getProgress()); } + private void onQueueItemClicked(MediaItemMetadata item) { + mModel.onSkipToQueueItem(item.getQueueId()); + } + /** * Collapses the playback controls. */ public void closeOverflowMenu() { mPlaybackControls.close(); } - - /** - * Updates the information on the media source being browsed. - */ - public void updateBrowse() { - MediaSource newSource = getCurrentMediaSource(); - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Updating browse: new source " - + (newSource != null ? newSource.getPackageName() : null) - + ", current source: " - + (mMediaSource != null ? mMediaSource.getPackageName() : null) - + ", currently playing: " - + (mModel.getMediaSource() != null - ? mModel.getMediaSource().getPackageName() : null)); - } - - // Visibility might change both because the browsed source changed or because the - // source being played changed. - if (Objects.equals(newSource, mModel.getMediaSource())) { - // We are playing: show everything - mAlbumBackground.setVisibility(View.VISIBLE); - mPlaybackControls.setVisibility(View.VISIBLE); - mAlbumArt.setVisibility(View.VISIBLE); - mTitle.setVisibility(View.VISIBLE); - mTime.setVisibility(View.VISIBLE); - mSubtitle.setVisibility(View.VISIBLE); - mSeekbar.setVisibility(View.VISIBLE); - mMetadataContainer.setVisibility(View.VISIBLE); - } else { - // Hide playback - mAlbumBackground.setVisibility(View.INVISIBLE); - mPlaybackControls.setVisibility(View.GONE); - mAlbumArt.setVisibility(View.VISIBLE); - mTitle.setVisibility(View.GONE); - mTime.setVisibility(View.GONE); - mSubtitle.setVisibility(View.GONE); - mSeekbar.setVisibility(View.GONE); - mMetadataContainer.setVisibility(View.GONE); - } - - if (Objects.equals(mMediaSource, newSource)) { - // Browse information hasn't changed. Nothing to do. - return; - } - - if (mMediaSource != null) { - mMediaSource.unsubscribe(mMediaSourceObserver); - } - mMediaSource = newSource; - if (newSource == null) return; - mMediaSource.subscribe(mMediaSourceObserver); - - MediaManager.getInstance(getContext()) - .setMediaClientComponent(mMediaSource.getBrowseServiceComponentName()); - } - - private MediaSource getCurrentMediaSource() { - if (getActivity() == null || getActivity().getIntent() == null - || !getActivity().getIntent().hasExtra( - MediaManager.KEY_MEDIA_PACKAGE)) { - return mModel.getMediaSource(); - } else { - String packageName = getActivity().getIntent().getStringExtra( - MediaManager.KEY_MEDIA_PACKAGE); - return new MediaSource(getContext(), packageName); - } - } - - private void onBrowseConnected(boolean success) { - if (mBrowseAdapter != null) { - mBrowseAdapter.stop(); - mBrowseAdapter = null; - } - if (!success) { - mBrowseList.setVisibility(View.GONE); - // TODO(b/77647430) implement intermediate states. - return; - } else { - mBrowseList.setVisibility(View.VISIBLE); - } - mBrowseAdapter = new BrowseAdapter(getContext(), mMediaSource, null, - ContentForwardStrategy.DEFAULT_STRATEGY); - mBrowseList.setAdapter(mBrowseAdapter); - mBrowseAdapter.registerObserver(this); - mBrowseAdapter.start(); - } - - private void onBrowseDisconnected() { - mBrowseAdapter.stop(); - } - - @Override - public void onDirty() { - mBrowseAdapter.update(); - if (mBrowseAdapter.getItemCount() > 0) { - mBrowseList.setVisibility(View.VISIBLE); - } else { - mBrowseList.setVisibility(View.GONE); - // TODO(b/77647430) implement intermediate states. - } - } - - @Override - public void onPlayableItemClicked(MediaItemMetadata item) { - mModel.onStop(); - mMediaSource.getPlaybackModel().onPlayItem(item.getId()); - getActivity().setIntent(null); - } - - @Override - public void onBrowseableItemClicked(MediaItemMetadata item) { - // TODO(b/77527398): Drill down in the navigation. - } - - @Override - public void onMoreButtonClicked(MediaItemMetadata item) { - // TODO(b/77527398): Drill down in the navigation - } - - @Override - public void onQueueTitleClicked() { - // TODO(b/77527398): Show full queue - } - - @Override - public void onQueueItemClicked(MediaItemMetadata item) { - mModel.onSkipToQueueItem(item.getQueueId()); - } } |