summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Perez <robertoalexis@google.com>2018-04-17 10:55:35 -0700
committerRoberto Perez <robertoalexis@google.com>2018-04-18 08:26:40 -0700
commit27683666b9c48dd8c53682f196351c9c1f7b7ee9 (patch)
tree623cb9738c657abe8ea5da33d369f889f8b64a18
parent2125426c91cf65f45b4f32fe5d651d175024f3b6 (diff)
downloadMedia-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.xml7
-rw-r--r--res/layout/fragment_playback.xml25
-rw-r--r--res/layout/media_browse_grid_item.xml15
-rw-r--r--res/layout/media_browse_header_item.xml15
-rw-r--r--res/layout/media_browse_list_item.xml15
-rw-r--r--res/layout/media_browse_more_footer.xml15
-rw-r--r--res/layout/media_browse_panel_item.xml15
-rw-r--r--res/layout/view_metadata.xml15
-rw-r--r--src/com/android/car/media/MediaActivity.java9
-rw-r--r--src/com/android/car/media/PlaybackFragment.java79
-rw-r--r--src/com/android/car/media/browse/BrowseAdapter.java19
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;
}
}