summaryrefslogtreecommitdiff
path: root/src/com/android/car/media/PlaybackFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/car/media/PlaybackFragment.java')
-rw-r--r--src/com/android/car/media/PlaybackFragment.java241
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());
- }
}