diff options
author | Roberto Perez <robertoalexis@google.com> | 2018-04-17 10:55:35 -0700 |
---|---|---|
committer | Roberto Perez <robertoalexis@google.com> | 2018-04-18 08:26:40 -0700 |
commit | 27683666b9c48dd8c53682f196351c9c1f7b7ee9 (patch) | |
tree | 623cb9738c657abe8ea5da33d369f889f8b64a18 | |
parent | 2125426c91cf65f45b4f32fe5d651d175024f3b6 (diff) | |
download | Media-27683666b9c48dd8c53682f196351c9c1f7b7ee9.tar.gz |
Showing/hiding playback depending whether the currently browsed source
is being played or not.
Bug: 77334804
Test: TBD
Change-Id: Ie614fc2a31fdebb5edbf7a2c30c3145b096e4241
-rw-r--r-- | AndroidManifest.xml | 7 | ||||
-rw-r--r-- | res/layout/fragment_playback.xml | 25 | ||||
-rw-r--r-- | res/layout/media_browse_grid_item.xml | 15 | ||||
-rw-r--r-- | res/layout/media_browse_header_item.xml | 15 | ||||
-rw-r--r-- | res/layout/media_browse_list_item.xml | 15 | ||||
-rw-r--r-- | res/layout/media_browse_more_footer.xml | 15 | ||||
-rw-r--r-- | res/layout/media_browse_panel_item.xml | 15 | ||||
-rw-r--r-- | res/layout/view_metadata.xml | 15 | ||||
-rw-r--r-- | src/com/android/car/media/MediaActivity.java | 9 | ||||
-rw-r--r-- | src/com/android/car/media/PlaybackFragment.java | 79 | ||||
-rw-r--r-- | src/com/android/car/media/browse/BrowseAdapter.java | 19 |
11 files changed, 206 insertions, 23 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f6ab4e8..80778d5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,16 +25,17 @@ android:minSdkVersion="24" android:targetSdkVersion='24'/> - <application android:label="CarMediaApp" + <application + android:label="CarMediaApp" android:icon="@drawable/ic_music"> <meta-data android:name="android.car.application" android:resource="@xml/automotive_app_desc" /> - <activity android:name=".MediaActivity" + <activity + android:name=".MediaActivity" android:theme="@style/MediaActivityTheme" - android:label="CarMediaApp" android:resizeableActivity="true" android:launchMode="singleTop"> <intent-filter> diff --git a/res/layout/fragment_playback.xml b/res/layout/fragment_playback.xml index 601844f..867d0e9 100644 --- a/res/layout/fragment_playback.xml +++ b/res/layout/fragment_playback.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/playback_container" + android:animateLayoutChanges="true" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -38,15 +54,20 @@ app:layout_constraintTop_toBottomOf="@+id/playback_scrim_bottom" app:layout_constraintBottom_toBottomOf="parent"/> + <android.support.v4.widget.Space + android:id="@+id/app_bar_space" + android:layout_width="match_parent" + android:layout_height="@dimen/car_app_bar_height" + app:layout_constraintTop_toTopOf="parent"/> + <FrameLayout android:id="@+id/metadata_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/car_app_bar_height" android:fitsSystemWindows="true" android:layout_marginLeft="@dimen/car_margin" android:layout_marginRight="@dimen/car_margin" - app:layout_constraintTop_toTopOf="parent"> + app:layout_constraintTop_toBottomOf="@+id/app_bar_space"> <include layout="@layout/view_metadata"/> diff --git a/res/layout/media_browse_grid_item.xml b/res/layout/media_browse_grid_item.xml index 086f11a..c6112d6 100644 --- a/res/layout/media_browse_grid_item.xml +++ b/res/layout/media_browse_grid_item.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" diff --git a/res/layout/media_browse_header_item.xml b/res/layout/media_browse_header_item.xml index b4db506..7daf142 100644 --- a/res/layout/media_browse_header_item.xml +++ b/res/layout/media_browse_header_item.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" diff --git a/res/layout/media_browse_list_item.xml b/res/layout/media_browse_list_item.xml index f20b20d..8f505e9 100644 --- a/res/layout/media_browse_list_item.xml +++ b/res/layout/media_browse_list_item.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" diff --git a/res/layout/media_browse_more_footer.xml b/res/layout/media_browse_more_footer.xml index ea79378..5122da0 100644 --- a/res/layout/media_browse_more_footer.xml +++ b/res/layout/media_browse_more_footer.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" diff --git a/res/layout/media_browse_panel_item.xml b/res/layout/media_browse_panel_item.xml index 3b56c36..28c9033 100644 --- a/res/layout/media_browse_panel_item.xml +++ b/res/layout/media_browse_panel_item.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" diff --git a/res/layout/view_metadata.xml b/res/layout/view_metadata.xml index c503903..3b4341d 100644 --- a/res/layout/view_metadata.xml +++ b/res/layout/view_metadata.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018, 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. +--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/metadata" diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java index db2c544..b3ddd12 100644 --- a/src/com/android/car/media/MediaActivity.java +++ b/src/com/android/car/media/MediaActivity.java @@ -52,7 +52,6 @@ public class MediaActivity extends CarDrawerActivity { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, mPlaybackFragment) .commit(); - handleIntent(getIntent()); } @Override @@ -84,6 +83,12 @@ public class MediaActivity extends CarDrawerActivity { super.onBackPressed(); } + @Override + protected void onResumeFragments() { + super.onResumeFragments(); + handleIntent(getIntent()); + } + private void handleIntent(Intent intent) { Bundle extras = null; if (intent != null) { @@ -102,10 +107,12 @@ public class MediaActivity extends CarDrawerActivity { Log.i(TAG, "Browsing: " + component + " from " + packageName); MediaManager.getInstance(this).setMediaClientComponent(component); + mPlaybackFragment.updateBrowse(); } else { // TODO (b/77334804): Implement the correct initialization logic when no component is // given. For example, it should either connect the user to the currently playing // session, bring the user to the app selector, or open the last known media source. + mPlaybackFragment.updateBrowse(); } if (isSearchIntent(intent)) { diff --git a/src/com/android/car/media/PlaybackFragment.java b/src/com/android/car/media/PlaybackFragment.java index ac4331f..e14dbc8 100644 --- a/src/com/android/car/media/PlaybackFragment.java +++ b/src/com/android/car/media/PlaybackFragment.java @@ -1,12 +1,25 @@ +/* + * Copyright 2018 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; -import android.content.ComponentName; -import android.content.Intent; import android.graphics.Bitmap; import android.graphics.PorterDuff; -import android.media.browse.MediaBrowser; -import android.media.projection.MediaProjectionManager; import android.os.Bundle; +import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; @@ -58,6 +71,8 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer private float mBackgroundBlurScale; private MediaSource mMediaSource; private BrowseAdapter mBrowseAdapter; + private ViewGroup mMetadataContainer; + private MediaItemMetadata mCurrentMetadata; private PlaybackModel.PlaybackObserver mPlaybackObserver = new PlaybackModel.PlaybackObserver() { @Override public void onPlaybackStateChanged() { @@ -105,6 +120,7 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer 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); @@ -161,6 +177,10 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer private void updateMetadata() { MediaItemMetadata metadata = mModel.getMetadata(); + if (Objects.equals(mCurrentMetadata, metadata)) { + return; + } + mCurrentMetadata = metadata; mTitle.setText(metadata != null ? metadata.getTitle() : null); mSubtitle.setText(metadata != null ? metadata.getSubtitle() : null); MediaItemMetadata.updateImageView(getContext(), metadata, mAlbumArt, 0); @@ -224,11 +244,51 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer mPlaybackControls.close(); } - private void updateBrowse() { + /** + * 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); } @@ -241,7 +301,8 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer } private MediaSource getCurrentMediaSource() { - if (getActivity().getIntent() == null || !getActivity().getIntent().hasExtra( + if (getActivity() == null || getActivity().getIntent() == null + || !getActivity().getIntent().hasExtra( MediaManager.KEY_MEDIA_PACKAGE)) { return mModel.getMediaSource(); } else { @@ -260,8 +321,10 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer mBrowseList.setVisibility(View.GONE); // TODO(b/77647430) implement intermediate states. return; + } else { + mBrowseList.setVisibility(View.VISIBLE); } - mBrowseAdapter = new BrowseAdapter(getContext(), mMediaSource.getMediaBrowser(), null, + mBrowseAdapter = new BrowseAdapter(getContext(), mMediaSource, null, ContentForwardStrategy.DEFAULT_STRATEGY); mBrowseList.setAdapter(mBrowseAdapter); mBrowseAdapter.registerObserver(this); @@ -286,8 +349,8 @@ public class PlaybackFragment extends Fragment implements BrowseAdapter.Observer @Override public void onPlayableItemClicked(MediaItemMetadata item) { mModel.onStop(); - getActivity().setIntent(null); mMediaSource.getPlaybackModel().onPlayItem(item.getId()); + getActivity().setIntent(null); } @Override diff --git a/src/com/android/car/media/browse/BrowseAdapter.java b/src/com/android/car/media/browse/BrowseAdapter.java index be50b9b..0b93ed6 100644 --- a/src/com/android/car/media/browse/BrowseAdapter.java +++ b/src/com/android/car/media/browse/BrowseAdapter.java @@ -30,6 +30,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.car.media.common.MediaItemMetadata; +import com.android.car.media.common.MediaSource; import java.util.ArrayList; import java.util.Collection; @@ -66,7 +67,7 @@ public class BrowseAdapter extends RecyclerView.Adapter<BrowseViewHolder> { private static final String TAG = "MediaBrowseAdapter"; @NonNull private final Context mContext; - private final MediaBrowser mMediaBrowser; + private final MediaSource mMediaSource; private final MediaItemMetadata mParentMediaItem; private final ContentForwardStrategy mCFBStrategy; private LinkedHashMap<String, MediaItemState> mItemStates = new LinkedHashMap<>(); @@ -178,15 +179,15 @@ public class BrowseAdapter extends RecyclerView.Adapter<BrowseViewHolder> { /** * Creates a {@link BrowseAdapter} that displays the children of the given media tree node. * - * @param mediaBrowser the {@link MediaBrowser} to get data from. + * @param mediaSource the {@link MediaSource} to get data from. * @param parentItem the node to display children of, or NULL if the * @param strategy a {@link ContentForwardStrategy} that would determine which items would be * expanded and how. */ - public BrowseAdapter(Context context, @NonNull MediaBrowser mediaBrowser, + public BrowseAdapter(Context context, @NonNull MediaSource mediaSource, @Nullable MediaItemMetadata parentItem, @NonNull ContentForwardStrategy strategy) { mContext = context; - mMediaBrowser = mediaBrowser; + mMediaSource = mediaSource; mParentMediaItem = parentItem; mCFBStrategy = strategy; } @@ -198,8 +199,8 @@ public class BrowseAdapter extends RecyclerView.Adapter<BrowseViewHolder> { public void start() { mParentMediaItemId = mParentMediaItem != null ? mParentMediaItem.getId() - : mMediaBrowser.getRoot(); - mMediaBrowser.subscribe(mParentMediaItemId, mSubscriptionCallback); + : mMediaSource.getMediaBrowser().getRoot(); + mMediaSource.getMediaBrowser().subscribe(mParentMediaItemId, mSubscriptionCallback); for (MediaItemState itemState : mItemStates.values()) { subscribe(itemState); } @@ -213,7 +214,7 @@ public class BrowseAdapter extends RecyclerView.Adapter<BrowseViewHolder> { // Not started return; } - mMediaBrowser.unsubscribe(mParentMediaItemId, mSubscriptionCallback); + mMediaSource.getMediaBrowser().unsubscribe(mParentMediaItemId, mSubscriptionCallback); for (MediaItemState itemState : mItemStates.values()) { unsubscribe(itemState); } @@ -296,14 +297,14 @@ public class BrowseAdapter extends RecyclerView.Adapter<BrowseViewHolder> { private void subscribe(MediaItemState state) { if (!state.mIsSubscribed && state.mItem.isBrowsable()) { - mMediaBrowser.subscribe(state.mItem.getId(), mSubscriptionCallback); + mMediaSource.getMediaBrowser().subscribe(state.mItem.getId(), mSubscriptionCallback); state.mIsSubscribed = true; } } private void unsubscribe(MediaItemState state) { if (state.mIsSubscribed) { - mMediaBrowser.unsubscribe(state.mItem.getId(), mSubscriptionCallback); + mMediaSource.getMediaBrowser().unsubscribe(state.mItem.getId(), mSubscriptionCallback); state.mIsSubscribed = false; } } |