summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-04-26 07:20:54 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-04-26 07:20:54 +0000
commitbc494a8827042319f5d60c683311f10e438004df (patch)
tree1d021f8bc1af282bf48a1080c56a47c9e8365d30
parent9f07c6c37dc0d26178ade6e6c6f54e3743e07c39 (diff)
parent5289168183d65b16813447c2b160adab799f1ac8 (diff)
downloadMedia-bc494a8827042319f5d60c683311f10e438004df.tar.gz
Snap for 4745538 from 5289168183d65b16813447c2b160adab799f1ac8 to pi-release
Change-Id: I880283151f2c973d4be1d226cdd2c7dec62196cd
-rw-r--r--res/drawable/ic_overflow_activated.xml39
-rw-r--r--res/drawable/ic_overflow_normal.xml31
-rw-r--r--res/drawable/ic_pause.xml13
-rw-r--r--res/drawable/ic_play_arrow.xml15
-rw-r--r--res/drawable/ic_play_arrow_off.xml20
-rw-r--r--res/drawable/ic_play_pause_stop.xml42
-rw-r--r--res/drawable/ic_skip_next.xml13
-rw-r--r--res/drawable/ic_skip_previous.xml13
-rw-r--r--res/drawable/ic_stop.xml13
-rw-r--r--res/drawable/seekbar_background.xml10
-rw-r--r--res/drawable/seekbar_thumb.xml9
-rw-r--r--res/layout/fragment_playback.xml40
-rw-r--r--res/layout/media_activity.xml30
-rw-r--r--res/layout/media_controls.xml166
-rw-r--r--res/layout/metadata_compact.xml50
-rw-r--r--res/layout/metadata_normal.xml60
-rw-r--r--res/layout/tab_view.xml6
-rw-r--r--res/layout/view_metadata.xml88
-rw-r--r--res/values/attrs.xml69
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/dimens.xml10
-rw-r--r--src/com/android/car/media/BrowseFragment.java2
-rw-r--r--src/com/android/car/media/CarClientServiceAdapter.java41
-rw-r--r--src/com/android/car/media/MediaActivity.java52
-rw-r--r--src/com/android/car/media/PlaybackFragment.java64
-rw-r--r--src/com/android/car/media/drawer/MediaDrawerController.java2
-rw-r--r--src/com/android/car/media/util/widgets/PlayPauseStopImageView.java134
-rw-r--r--src/com/android/car/media/widgets/MediaItemTabView.java (renamed from src/com/android/car/media/util/widgets/MediaItemTabView.java)3
-rw-r--r--src/com/android/car/media/widgets/MetadataView.java187
29 files changed, 432 insertions, 794 deletions
diff --git a/res/drawable/ic_overflow_activated.xml b/res/drawable/ic_overflow_activated.xml
deleted file mode 100644
index 1649b7cc..00000000
--- a/res/drawable/ic_overflow_activated.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <group
- android:translateX="-0.750000"
- android:translateY="-0.750000">
- <path
- android:strokeWidth="1"
- android:pathData="M 0.75 24.75 L 24.75 24.75 L 24.75 0.75 L 0.75 0.75 Z" />
- <path
- android:fillColor="#000000"
- android:strokeWidth="1"
- android:pathData="M12.75,0.75 C6.123,0.75 0.75,6.123 0.75,12.75 C0.75,19.377 6.123,24.75
-12.75,24.75 C19.377,24.75 24.75,19.377 24.75,12.75 C24.75,6.123 19.377,0.75
-12.75,0.75 M12.75,2.036 C18.658,2.036 23.464,6.842 23.464,12.75 C23.464,18.658
-18.658,23.464 12.75,23.464 C6.842,23.464 2.036,18.658 2.036,12.75 C2.036,6.842
-6.842,2.036 12.75,2.036" />
- <path
- android:fillColor="#000000"
- android:strokeWidth="1"
- android:pathData="M12.75,10.1666667 C13.4604167,10.1666667 14.0416667,9.58541667 14.0416667,8.875
-C14.0416667,8.16458333 13.4604167,7.58333333 12.75,7.58333333
-C12.0395833,7.58333333 11.4583333,8.16458333 11.4583333,8.875
-C11.4583333,9.58541667 12.0395833,10.1666667 12.75,10.1666667 L12.75,10.1666667
-Z M12.75,11.4583333 C12.0395833,11.4583333 11.4583333,12.0395833
-11.4583333,12.75 C11.4583333,13.4604167 12.0395833,14.0416667 12.75,14.0416667
-C13.4604167,14.0416667 14.0416667,13.4604167 14.0416667,12.75
-C14.0416667,12.0395833 13.4604167,11.4583333 12.75,11.4583333 L12.75,11.4583333
-Z M12.75,15.3333333 C12.0395833,15.3333333 11.4583333,15.9145833
-11.4583333,16.625 C11.4583333,17.3354167 12.0395833,17.9166667 12.75,17.9166667
-C13.4604167,17.9166667 14.0416667,17.3354167 14.0416667,16.625
-C14.0416667,15.9145833 13.4604167,15.3333333 12.75,15.3333333 L12.75,15.3333333
-Z" />
- </group>
-</vector>
diff --git a/res/drawable/ic_overflow_normal.xml b/res/drawable/ic_overflow_normal.xml
deleted file mode 100644
index de7b761c..00000000
--- a/res/drawable/ic_overflow_normal.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <group
- android:translateX="-0.750000"
- android:translateY="-0.750000">
- <path
- android:strokeWidth="1"
- android:pathData="M 0.75 24.75 L 24.75 24.75 L 24.75 0.75 L 0.75 0.75 Z" />
- <path
- android:fillColor="#000000"
- android:strokeWidth="1"
- android:pathData="M12.75,10.1666667 C13.4604167,10.1666667 14.0416667,9.58541667 14.0416667,8.875
-C14.0416667,8.16458333 13.4604167,7.58333333 12.75,7.58333333
-C12.0395833,7.58333333 11.4583333,8.16458333 11.4583333,8.875
-C11.4583333,9.58541667 12.0395833,10.1666667 12.75,10.1666667 L12.75,10.1666667
-Z M12.75,11.4583333 C12.0395833,11.4583333 11.4583333,12.0395833
-11.4583333,12.75 C11.4583333,13.4604167 12.0395833,14.0416667 12.75,14.0416667
-C13.4604167,14.0416667 14.0416667,13.4604167 14.0416667,12.75
-C14.0416667,12.0395833 13.4604167,11.4583333 12.75,11.4583333 L12.75,11.4583333
-Z M12.75,15.3333333 C12.0395833,15.3333333 11.4583333,15.9145833
-11.4583333,16.625 C11.4583333,17.3354167 12.0395833,17.9166667 12.75,17.9166667
-C13.4604167,17.9166667 14.0416667,17.3354167 14.0416667,16.625
-C14.0416667,15.9145833 13.4604167,15.3333333 12.75,15.3333333 L12.75,15.3333333
-Z" />
- </group>
-</vector>
diff --git a/res/drawable/ic_pause.xml b/res/drawable/ic_pause.xml
deleted file mode 100644
index 3e80cd11..00000000
--- a/res/drawable/ic_pause.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
-
- <path
- android:fillColor="#000000"
- android:pathData="M12 38h8V10h-8v28zm16-28v28h8V10h-8z" />
- <path
- android:pathData="M0 0h48v48H0z" />
-</vector>
diff --git a/res/drawable/ic_play_arrow.xml b/res/drawable/ic_play_arrow.xml
deleted file mode 100644
index d15c1213..00000000
--- a/res/drawable/ic_play_arrow.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
-
- <path
- android:pathData="M-838-2232H562v3600H-838z" />
- <path
- android:fillColor="#000000"
- android:pathData="M16 10v28l22-14z" />
- <path
- android:pathData="M0 0h48v48H0z" />
-</vector>
diff --git a/res/drawable/ic_play_arrow_off.xml b/res/drawable/ic_play_arrow_off.xml
deleted file mode 100644
index 33b70ca9..00000000
--- a/res/drawable/ic_play_arrow_off.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <group
- android:translateX="3.000000"
- android:translateY="3.000000">
- <path
- android:fillColor="#000000"
- android:strokeWidth="1"
- android:pathData="M16,9 L7.249,3.431 L14.048,10.242 L16,9 Z" />
- <path
- android:fillColor="#000000"
- android:strokeWidth="1"
- android:pathData="M18,16.73 L1.27,0 L0,1.27 L5,6.27 L5,16 L10.946,12.216 L16.73,18 L18,16.73 Z" />
- </group>
-</vector>
diff --git a/res/drawable/ic_play_pause_stop.xml b/res/drawable/ic_play_pause_stop.xml
deleted file mode 100644
index 937a5fc7..00000000
--- a/res/drawable/ic_play_pause_stop.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2016, 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.
--->
-<selector
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:gearhead="http://schemas.android.com/apk/res-auto" >
- <item
- gearhead:state_playing_to_pause="true"
- android:drawable="@drawable/ic_pause" />
- <item
- gearhead:state_playing_to_stop="true"
- android:drawable="@drawable/ic_stop" />
- <item
- gearhead:state_paused="true"
- android:drawable="@drawable/ic_play_arrow" />
- <item
- gearhead:state_buffering_to_pause="true"
- android:drawable="@drawable/ic_pause" />
- <item
- gearhead:state_buffering_to_stop="true"
- android:drawable="@drawable/ic_stop" />
- <item
- gearhead:state_stopped="true"
- android:drawable="@drawable/ic_play_arrow" />
- <item
- gearhead:state_disabled="true"
- android:drawable="@drawable/ic_play_arrow_off" />
- <item android:drawable="@drawable/ic_play_arrow" />
-</selector>
diff --git a/res/drawable/ic_skip_next.xml b/res/drawable/ic_skip_next.xml
deleted file mode 100644
index 5ac0d548..00000000
--- a/res/drawable/ic_skip_next.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:fillColor="#000000"
- android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
- <path
- android:pathData="M0 0h24v24H0z" />
-</vector>
diff --git a/res/drawable/ic_skip_previous.xml b/res/drawable/ic_skip_previous.xml
deleted file mode 100644
index f943f888..00000000
--- a/res/drawable/ic_skip_previous.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:fillColor="#000000"
- android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
- <path
- android:pathData="M0 0h24v24H0z" />
-</vector>
diff --git a/res/drawable/ic_stop.xml b/res/drawable/ic_stop.xml
deleted file mode 100644
index ae018446..00000000
--- a/res/drawable/ic_stop.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
-
- <path
- android:pathData="M0 0h48v48H0z" />
- <path
- android:fillColor="#000000"
- android:pathData="M12 12h24v24H12z" />
-</vector>
diff --git a/res/drawable/seekbar_background.xml b/res/drawable/seekbar_background.xml
index bdb03aae..b66f6eec 100644
--- a/res/drawable/seekbar_background.xml
+++ b/res/drawable/seekbar_background.xml
@@ -17,16 +17,10 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
- android:drawable="@android:color/transparent" />
-
- <item android:id="@android:id/secondaryProgress">
- <scale android:scaleWidth="100%"
- android:drawable="@android:color/transparent" />
- </item>
+ android:drawable="@color/progress_bar_background" />
<item android:id="@android:id/progress">
- <scale android:scaleWidth="100%"
- android:drawable="@drawable/progressbar" />
+ <clip android:drawable="@color/progress_bar_highlight" />
</item>
</layer-list>
diff --git a/res/drawable/seekbar_thumb.xml b/res/drawable/seekbar_thumb.xml
new file mode 100644
index 00000000..d7dea4fb
--- /dev/null
+++ b/res/drawable/seekbar_thumb.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <!-- Transparent thumb, used to leave a gap between the two segments of the progress bar -->
+ <solid android:color="@android:color/transparent"/>
+ <size
+ android:width="@dimen/playback_seekbar_thumb_width"
+ android:height="@dimen/playback_seekbar_height"/>
+</shape> \ No newline at end of file
diff --git a/res/layout/fragment_playback.xml b/res/layout/fragment_playback.xml
index f3a3ee28..59f34bc2 100644
--- a/res/layout/fragment_playback.xml
+++ b/res/layout/fragment_playback.xml
@@ -22,31 +22,47 @@
android:layout_width="match_parent"
android:layout_height="match_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
+ <LinearLayout
android:id="@+id/metadata_container"
+ android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fitsSystemWindows="true"
+ android:paddingTop="@dimen/car_padding_4"
+ android:paddingBottom="@dimen/car_padding_4"
android:layout_marginLeft="@dimen/car_margin"
android:layout_marginRight="@dimen/car_margin"
- app:layout_constraintTop_toBottomOf="@+id/app_bar_space">
+ android:gravity="center_vertical"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <ImageView
+ android:id="@+id/album_art"
+ android:contentDescription="@string/album_art"
+ android:layout_marginStart="@dimen/car_keyline_1"
+ android:layout_marginEnd="@dimen/car_keyline_1"
+ android:layout_width="@dimen/playback_album_art_height"
+ android:layout_height="@dimen/playback_album_art_width"
+ android:scaleType="centerCrop"
+ android:transitionName="@string/album_art"/>
- <include layout="@layout/view_metadata"/>
+ <com.android.car.media.widgets.MetadataView
+ android:id="@+id/metadata"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/car_keyline_1"
+ android:layout_weight="1"
+ android:focusable="false"
+ app:style="normal"/>
- </FrameLayout>
+ </LinearLayout>
<androidx.car.widget.PagedListView
android:id="@+id/queue_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="@dimen/car_padding_4"
- app:showPagedListViewDivider="false"
+ app:listDividerColor="@color/car_list_divider_inverse"
+ app:dividerStartMargin="@dimen/car_keyline_1"
+ app:dividerEndMargin="@dimen/car_keyline_1"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintTop_toBottomOf="@+id/metadata_container"
app:layout_constraintBottom_toTopOf="@+id/playback_controls"/>
diff --git a/res/layout/media_activity.xml b/res/layout/media_activity.xml
index e92308d1..73d7cf32 100644
--- a/res/layout/media_activity.xml
+++ b/res/layout/media_activity.xml
@@ -46,6 +46,7 @@
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/browse_tab_height"
+ android:layout_marginTop="@dimen/car_padding_4"
app:tabIndicatorHeight="0dp"
app:tabGravity="fill"
app:tabMode="fixed"
@@ -57,7 +58,34 @@
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginTop="@dimen/car_padding_4"
app:layout_constraintTop_toBottomOf="@+id/tabs"
- app:layout_constraintBottom_toBottomOf="parent"/>
+ app:layout_constraintBottom_toTopOf="@+id/browse_controls_container"/>
+ <LinearLayout
+ android:id="@+id/browse_controls_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/car_padding_4"
+ android:background="@color/browse_playback_bg"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ app:layout_constraintBottom_toBottomOf="parent">
+
+ <com.android.car.media.common.PlaybackControls
+ android:id="@+id/controls"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:layout_marginRight="@dimen/car_padding_4"
+ app:columns="3"/>
+
+ <com.android.car.media.widgets.MetadataView
+ android:id="@+id/metadata"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ app:style="compact"/>
+
+ </LinearLayout>
</android.support.constraint.ConstraintLayout>
diff --git a/res/layout/media_controls.xml b/res/layout/media_controls.xml
deleted file mode 100644
index 93bc8287..00000000
--- a/res/layout/media_controls.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.v7.widget.CardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/music_panel"
- android:layout_width="match_parent"
- android:layout_height="@dimen/car_action_bar_height"
- android:elevation="@dimen/music_panel_elevation"
- android:layout_gravity="bottom"
- android:visibility="gone"
- app:cardCornerRadius="@dimen/car_radius_1" >
- <LinearLayout
- android:id="@+id/controls"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:background="@color/car_card"
- android:gravity="center" >
- <ImageButton
- android:id="@+id/play_queue"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:layout_marginLeft="@dimen/controls_margin"
- android:background="@drawable/music_action_background"
- android:tint="@color/car_tint" />
- <Space
- android:layout_width="@dimen/controls_spacing_outer"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/prev"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:background="@drawable/music_action_background"
- android:tint="@color/car_tint"/>
- <Space
- android:layout_width="@dimen/controls_spacing_inner"
- android:layout_height="match_parent"/>
- <FrameLayout
- android:id="@+id/play_pause_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <com.android.car.media.util.widgets.PlayPauseStopImageView
- android:id="@+id/play_pause"
- android:layout_width="@dimen/stream_fab_size"
- android:layout_height="@dimen/stream_fab_size"
- android:layout_gravity="center"
- android:scaleType="centerInside"
- android:src="@drawable/ic_play_pause_stop"
- android:focusable="true"
- android:elevation="@dimen/play_pause_elevation"
- android:stateListAnimator="@anim/car_fab_state_list_animator" />
- <ProgressBar
- android:id="@+id/spinner"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="9dp"
- android:indeterminateDrawable="@drawable/music_buffering"
- android:visibility="gone" />
- </FrameLayout>
- <Space
- android:layout_width="@dimen/controls_spacing_inner"
- android:layout_height="match_parent"/>
- <ImageButton
- android:id="@+id/next"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:background="@drawable/music_action_background"
- android:tint="@color/car_tint" />
- <Space
- android:layout_width="@dimen/controls_spacing_outer"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/overflow_on"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:layout_marginRight="@dimen/controls_margin"
- android:background="@drawable/music_action_background"
- android:tint="@color/car_tint" />
- </LinearLayout>
- <LinearLayout
- android:id="@+id/overflow_items"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:background="@color/car_card"
- android:gravity="center"
- android:visibility="gone"
- android:alpha="0.0" >
- <ImageButton
- android:id="@+id/custom_action_1"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:layout_marginLeft="@dimen/overflow_margin"
- android:background="@drawable/music_overflow_action_background"
- android:tint="@color/car_tint_light" />
- <Space
- android:layout_width="@dimen/overflow_spacing_outer"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/custom_action_2"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:background="@drawable/music_overflow_action_background"
- android:tint="@color/car_tint_light" />
- <Space
- android:layout_width="@dimen/overflow_spacing_inner"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/custom_action_3"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:background="@drawable/music_overflow_action_background"
- android:tint="@color/car_tint_light" />
- <Space
- android:layout_width="@dimen/overflow_spacing_inner"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/custom_action_4"
- android:visibility="invisible"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:background="@drawable/music_overflow_action_background"
- android:tint="@color/car_tint_light" />
- <Space
- android:layout_width="@dimen/overflow_spacing_outer"
- android:layout_height="match_parent" />
- <ImageButton
- android:id="@+id/overflow_off"
- android:layout_width="@dimen/controls_tap_target_width"
- android:layout_height="@dimen/controls_tap_target_height"
- android:layout_marginRight="@dimen/overflow_margin"
- android:background="@drawable/music_overflow_action_background"
- android:tint="@color/car_tint_light" />
- </LinearLayout>
- <SeekBar
- android:id="@+id/seek_bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/seek_bar_height"
- android:layout_gravity="top"
- android:focusable="false"
- android:paddingStart="0dp"
- android:paddingEnd="0dp"
- android:progressDrawable="@drawable/seekbar_background"
- android:thumb="@null" />
-</android.support.v7.widget.CardView>
diff --git a/res/layout/metadata_compact.xml b/res/layout/metadata_compact.xml
new file mode 100644
index 00000000..3d772a18
--- /dev/null
+++ b/res/layout/metadata_compact.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/car_padding_1"
+ android:textAppearance="@style/TextAppearance.Car.Body1.Light"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:includeFontPadding="false"/>
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/title"
+ android:layout_marginBottom="@dimen/car_padding_1"
+ android:textAppearance="@style/TextAppearance.Car.Body2.Light"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:includeFontPadding="false"/>
+ <SeekBar
+ android:id="@+id/seek_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/playback_seekbar_height"
+ android:layout_below="@+id/subtitle"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
+ android:visibility="invisible"
+ android:progressDrawable="@drawable/seekbar_background"
+ android:thumb="@drawable/seekbar_thumb"/>
+
+</merge> \ No newline at end of file
diff --git a/res/layout/metadata_normal.xml b/res/layout/metadata_normal.xml
new file mode 100644
index 00000000..cdb63c48
--- /dev/null
+++ b/res/layout/metadata_normal.xml
@@ -0,0 +1,60 @@
+<?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.
+-->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/car_padding_1"
+ android:textAppearance="@style/TextAppearance.Car.Body1.Light"
+ android:maxLines="@integer/playback_title_text_max_lines"
+ android:ellipsize="end"
+ android:includeFontPadding="false"/>
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/title"
+ android:layout_marginBottom="@dimen/car_padding_4"
+ android:textAppearance="@style/TextAppearance.Car.Body2.Light"
+ android:maxLines="@integer/playback_subtitle_text_max_lines"
+ android:ellipsize="end"
+ android:includeFontPadding="false"/>
+ <TextView
+ android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_below="@+id/title"
+ android:textAppearance="@style/TextAppearance.Car.Body2.Light"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:includeFontPadding="false"/>
+ <SeekBar
+ android:id="@+id/seek_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/playback_seekbar_height"
+ android:layout_below="@+id/subtitle"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
+ android:visibility="invisible"
+ android:progressDrawable="@drawable/seekbar_background"
+ android:thumb="@drawable/seekbar_thumb"/>
+
+</merge> \ No newline at end of file
diff --git a/res/layout/tab_view.xml b/res/layout/tab_view.xml
index 68fef69a..0abc1287 100644
--- a/res/layout/tab_view.xml
+++ b/res/layout/tab_view.xml
@@ -21,19 +21,19 @@
android:id="@+id/icon"
android:layout_width="@dimen/car_primary_icon_size"
android:layout_height="@dimen/car_primary_icon_size"
+ android:layout_marginBottom="@dimen/car_padding_0"
android:scaleType="fitCenter"
android:layout_gravity="center_horizontal"
- android:tint="@color/car_tint_inverse"
- android:layout_marginTop="@dimen/car_padding_2"/>
+ android:tint="@color/car_tint_inverse"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:layout_marginBottom="@dimen/car_padding_1"
android:maxLines="1"
android:ellipsize="end"
+ android:includeFontPadding="false"
android:textAppearance="@style/TextAppearance.Car.Body5.Light"/>
</merge> \ No newline at end of file
diff --git a/res/layout/view_metadata.xml b/res/layout/view_metadata.xml
deleted file mode 100644
index 3b4341dc..00000000
--- a/res/layout/view_metadata.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?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"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/car_keyline_2"
- android:layout_marginBottom="@dimen/car_keyline_2"
- android:gravity="center"
- android:layout_centerVertical="true">
-
- <ImageView
- android:id="@+id/album_art"
- android:contentDescription="@string/album_art"
- android:layout_marginStart="@dimen/car_keyline_1"
- android:layout_marginEnd="@dimen/car_keyline_1"
- android:layout_width="@dimen/playback_album_art_height"
- android:layout_height="@dimen/playback_album_art_width"
- android:scaleType="centerCrop"
- android:transitionName="@string/album_art"/>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/car_keyline_1"
- android:layout_weight="1"
- android:focusable="false">
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/car_padding_1"
- android:textAppearance="@style/TextAppearance.Car.Body1.Light"
- android:maxLines="@integer/playback_title_text_max_lines"
- android:ellipsize="end"
- android:includeFontPadding="false"/>
- <TextView
- android:id="@+id/subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/title"
- android:layout_marginBottom="@dimen/car_padding_2"
- android:textAppearance="@style/TextAppearance.Car.Body2.Light"
- android:maxLines="@integer/playback_subtitle_text_max_lines"
- android:ellipsize="end"
- android:includeFontPadding="false"/>
- <TextView
- android:id="@+id/time"
- android:text="3:27 / 4:03"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_below="@+id/title"
- android:textAppearance="@style/TextAppearance.Car.Body2.Light"
- android:maxLines="@integer/playback_subtitle_text_max_lines"
- android:ellipsize="end"
- android:includeFontPadding="false"/>
- <SeekBar
- android:id="@+id/seek_bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/playback_seekbar_height"
- android:layout_below="@+id/subtitle"
- android:paddingStart="0dp"
- android:paddingEnd="0dp"
- android:visibility="invisible"
- android:progressDrawable="@drawable/seekbar_background"
- android:background="@color/car_grey_900"
- android:thumb="@null"/>
-
- </RelativeLayout>
-</LinearLayout>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 857d8f4a..f77c9ced 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright 2016, The Android Open Source Project
+ 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.
@@ -15,66 +15,13 @@
limitations under the License.
-->
<resources>
- <declare-styleable name="ImageButtonWithAlphaFade">
- <!-- Fade duration in ms -->
- <attr name="fadeDuration" format="integer" />
- <attr name="alphaNormal" format="float" />
- <attr name="alphaSelected" format="float" />
- <attr name="fadeColor" format="integer" />
- </declare-styleable>
-
- <declare-styleable name="BrowseItemView">
- <attr name="detailAnimation" format="reference" />
- </declare-styleable>
-
- <declare-styleable name="PlayingState">
- <attr name="state_paused" format="boolean"/>
- <attr name="state_playing_to_pause" format="boolean"/>
- <attr name="state_playing_to_stop" format="boolean"/>
- <attr name="state_buffering_to_pause" format="boolean"/>
- <attr name="state_buffering_to_stop" format="boolean"/>
- <attr name="state_stopped" format="boolean"/>
- <attr name="state_disabled" format="boolean"/>
- </declare-styleable>
-
- <!-- IME stuff -->
- <!-- Modified KeyboardView -->
- <declare-styleable name="KeyboardView">
- <attr name="keyBackground" format="reference"/>
- <attr name="keyTextSize" format="dimension"/>
- <attr name="keyTextColorPrimary" format="color"/>
- <attr name="keyTextColorSecondary" format="color"/>
- <attr name="labelTextSize" format="dimension"/>
- <attr name="fontFamily" format="string" />
- <attr name="textStyle" format="enum">
- <enum name="normal" value="0" />
- <enum name="bold" value="1" />
- <enum name="italic" value="2" />
- <enum name="bold_italic" value="3" />
+ <declare-styleable name="MetadataView">
+ <!-- Style of media item metadata view -->
+ <attr name="style" format="enum">
+ <!-- Compact version (to be included in the bottom bar during browsing -->
+ <enum name="compact" value="0"/>
+ <!-- Normal version (to be included in the playback screen -->
+ <enum name="normal" value="1"/>
</attr>
</declare-styleable>
-
- <declare-styleable name="RotaryKeyboardLayout">
- <attr name="selectedKeyTextColor" format="color" />
- <attr name="selectedKeyTextSize" format="dimension" />
- <attr name="selectedCircleColor" format="dimension" />
- <attr name="selectedCircleRadius" format="dimension" />
- <attr name="clickedCircleRadius" format="dimension" />
- <attr name="movedCircleRadius" format="dimension" />
- <attr name="ringKeySpacing" format="dimension" />
- <attr name="ringKeyTextColor" format="color" />
- <attr name="ringKeyTextSize" format="dimension" />
- <attr name="selectedKeyMargin" format="dimension" />
- <attr name="selectedKeygroupTextSize" format="dimension" />
- <attr name="keyGroupTextSize" format="dimension" />
- <attr name="keyGroupCircleRadius" format="dimension" />
- <attr name="keyGroupCircleColor" format="color" />
- <attr name="keyGroupSpacing" format="dimension" />
- </declare-styleable>
-
- <declare-styleable name="PageIndicator">
- <attr name="dotPadding" format="dimension" />
- <attr name="inactiveDotSrc" format="reference" />
- <attr name="activeDotSrc" format="reference" />
- </declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 30f7d003..a3c9bd91 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -27,4 +27,8 @@
<color name="media_template_background">@color/car_dark_blue_grey_800</color>
<!-- Scrim displayed on top of playback album art background -->
<color name="media_scrim_background">@color/car_dark_blue_grey_900</color>
+ <!-- Color used on the progress bar background -->
+ <color name="progress_bar_background">@color/car_grey_900</color>
+ <!-- Color used on the progress bar -->
+ <color name="progress_bar_highlight">#fafafa</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 254ebd54..6144b7ba 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -35,6 +35,8 @@
<!-- Playback seekbar height -->
<dimen name="playback_seekbar_height">8dp</dimen>
+ <!-- Size of the thumb in the playback seekbar -->
+ <dimen name="playback_seekbar_thumb_width">6dp</dimen>
<!-- Height of the gradient scrim over the background image -->
<dimen name="playback_scrim_transition_height">256dp</dimen>
<!-- Image size used to generate the background -->
@@ -44,11 +46,13 @@
<!-- Scale to apply to images before blurring them to create the playback background -->
<item name="playback_background_blur_scale" format="float" type="dimen">1</item>
<!-- Size of the album art thumbnail -->
- <dimen name="playback_album_art_height">190dp</dimen>
- <dimen name="playback_album_art_width">200dp</dimen>
+ <dimen name="playback_album_art_height">156dp</dimen>
+ <dimen name="playback_album_art_width">156dp</dimen>
<!-- Tab height -->
- <dimen name="browse_tab_height">100dp</dimen>
+ <dimen name="browse_tab_height">76dp</dimen>
<!-- Tab max width -->
<dimen name="browse_tab_width">92dp</dimen>
+ <!-- Browse playback controls size -->
+ <dimen name="browse_playback_controls_height">192dp</dimen>
</resources>
diff --git a/src/com/android/car/media/BrowseFragment.java b/src/com/android/car/media/BrowseFragment.java
index 64c5eaa5..3c56c0e7 100644
--- a/src/com/android/car/media/BrowseFragment.java
+++ b/src/com/android/car/media/BrowseFragment.java
@@ -273,4 +273,4 @@ public class BrowseFragment extends Fragment {
return mBrowseStack.lastElement();
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/car/media/CarClientServiceAdapter.java b/src/com/android/car/media/CarClientServiceAdapter.java
deleted file mode 100644
index ae2c0afb..00000000
--- a/src/com/android/car/media/CarClientServiceAdapter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 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.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import java.util.List;
-
-/**
- * A Media Manager adapter which uses the car api client to query for allowed media services.
- *
- * @deprecated This adapter will be removed as we are not sharing this code with the projected
- * team.
- */
-@Deprecated
-public class CarClientServiceAdapter implements MediaManager.ServiceAdapter {
- private PackageManager mPackageManager;
-
- public CarClientServiceAdapter(PackageManager packageManager) {
- mPackageManager = packageManager;
- }
-
- @Override
- public List<ResolveInfo> queryAllowedServices(Intent providerIntent) {
- return mPackageManager.queryIntentServices(providerIntent, 0);
- }
-}
diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java
index 9723d4de..3ac5396c 100644
--- a/src/com/android/car/media/MediaActivity.java
+++ b/src/com/android/car/media/MediaActivity.java
@@ -26,13 +26,16 @@ import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
import com.android.car.media.common.CrossfadeImageView;
import com.android.car.media.common.MediaItemMetadata;
import com.android.car.media.common.MediaSource;
+import com.android.car.media.common.PlaybackControls;
import com.android.car.media.common.PlaybackModel;
import com.android.car.media.drawer.MediaDrawerController;
-import com.android.car.media.util.widgets.MediaItemTabView;
+import com.android.car.media.widgets.MediaItemTabView;
+import com.android.car.media.widgets.MetadataView;
import java.util.ArrayList;
import java.util.List;
@@ -70,6 +73,10 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
private PlaybackFragment mPlaybackFragment;
private AppBarLayout mAppBarLayout;
private View mBrowseScrim;
+ private PlaybackControls mPlaybackControls;
+ private MetadataView mMetadataView;
+ private ViewGroup mBrowseControlsContainer;
+
/** Current state */
private MediaItemMetadata mCurrentMetadata;
@@ -106,6 +113,7 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
+ Log.i(TAG, "onTabSelected: " + tab.getTag());
mMode = Mode.BROWSING;
updateBrowseFragment((MediaItemMetadata) tab.getTag());
updateMetadata();
@@ -118,6 +126,7 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
@Override
public void onTabReselected(TabLayout.Tab tab) {
+ Log.i(TAG, "onTabReselected: " + tab.getTag());
mMode = Mode.BROWSING;
updateBrowseFragment((MediaItemMetadata) tab.getTag());
updateMetadata();
@@ -151,6 +160,12 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
mAppBarLayout = findViewById(androidx.car.R.id.appbar);
mAlbumBackground = findViewById(R.id.media_background);
mBrowseScrim = findViewById(R.id.browse_scrim);
+ mPlaybackControls = findViewById(R.id.controls);
+ mPlaybackControls.setModel(mPlaybackModel);
+ mMetadataView = findViewById(R.id.metadata);
+ mMetadataView.setModel(mPlaybackModel);
+ mBrowseControlsContainer = findViewById(R.id.browse_controls_container);
+ mBrowseControlsContainer.setOnClickListener(view -> switchToMode(Mode.PLAYBACK));
TypedValue outValue = new TypedValue();
getResources().getValue(R.dimen.playback_background_blur_radius, outValue, true);
mBackgroundBlurRadius = outValue.getFloat();
@@ -174,6 +189,8 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
public void onDestroy() {
super.onDestroy();
mDrawerController.cleanup();
+ mPlaybackControls.setModel(null);
+ mMetadataView.setModel(null);
}
@Override
@@ -202,7 +219,7 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
@Override
protected void onResumeFragments() {
super.onResumeFragments();
- updateBrowseSource();
+ handleIntent();
}
private void onBrowseConnected(boolean success) {
@@ -215,10 +232,10 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
}
private void handleIntent() {
- updateBrowseSource();
switchToMode(getRequestedMediaPackageName() == null || !mContentForwardBrowseEnabled
? Mode.PLAYBACK
: Mode.BROWSING);
+ updateBrowseSource();
}
/**
@@ -297,6 +314,8 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
&& browsableTopLevel.size() <= mMaxBrowserTabs)) {
mAppBarLayout.setVisibility(View.GONE);
mTabLayout.setVisibility(View.VISIBLE);
+ // Temporarily removing the listener, to prevent initial tab selection event.
+ mTabLayout.removeOnTabSelectedListener(mTabSelectedListener);
int count = 0;
for (MediaItemMetadata item : browsableTopLevel) {
MediaItemTabView tab = new MediaItemTabView(this, item);
@@ -306,6 +325,7 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
break;
}
}
+ mTabLayout.addOnTabSelectedListener(mTabSelectedListener);
updateBrowseFragment(browsableTopLevel.get(0));
} else {
mAppBarLayout.setVisibility(View.VISIBLE);
@@ -315,17 +335,13 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
}
private void switchToMode(Mode mode) {
+ Log.i(TAG, "Switch mode to " + mode + " (intent package: " +
+ getRequestedMediaPackageName() + ")");
mMode = mode;
- switch(mode) {
- case PLAYBACK:
- showFragment(mPlaybackFragment);
- break;
- case BROWSING:
- // Browse fragment will be loaded once we have the top level items.
- showFragment(null);
- updateMetadata();
- break;
- }
+ updateMetadata();
+ showFragment(mode == Mode.PLAYBACK
+ ? mPlaybackFragment
+ : null); // Browse fragment will be loaded once we have the top level items.
}
private void updateBrowseFragment(MediaItemMetadata topItem) {
@@ -340,9 +356,12 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
private void updateMetadata() {
if (isCurrentMediaSourcePlaying()) {
mAlbumBackground.setVisibility(View.VISIBLE);
- mBrowseScrim.setVisibility(mCurrentFragment == mPlaybackFragment
+ mBrowseScrim.setVisibility(mMode == Mode.PLAYBACK
+ ? View.GONE
+ : View.VISIBLE);
+ mBrowseControlsContainer.setVisibility(mMode == Mode.PLAYBACK
? View.GONE
- : View. VISIBLE);
+ : View.VISIBLE);
MediaItemMetadata metadata = mPlaybackModel.getMetadata();
if (Objects.equals(mCurrentMetadata, metadata)) {
return;
@@ -359,8 +378,9 @@ public class MediaActivity extends CarDrawerActivity implements BrowseFragment.C
mAlbumBackground.setImageBitmap(null, true);
}
} else {
- mAlbumBackground.setVisibility(View.GONE);
+ mAlbumBackground.setVisibility(View.INVISIBLE);
mBrowseScrim.setVisibility(View.GONE);
+ mBrowseControlsContainer.setVisibility(View.GONE);
}
}
diff --git a/src/com/android/car/media/PlaybackFragment.java b/src/com/android/car/media/PlaybackFragment.java
index c5772a57..42c28250 100644
--- a/src/com/android/car/media/PlaybackFragment.java
+++ b/src/com/android/car/media/PlaybackFragment.java
@@ -17,33 +17,22 @@
package com.android.car.media;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.PorterDuff;
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;
-import android.util.Log;
-import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import com.android.car.media.browse.BrowseAdapter;
-import com.android.car.media.browse.ContentForwardStrategy;
-import com.android.car.media.common.GridSpacingItemDecoration;
import com.android.car.media.common.MediaItemMetadata;
import com.android.car.media.common.MediaSource;
import com.android.car.media.common.PlaybackControls;
import com.android.car.media.common.PlaybackModel;
+import com.android.car.media.widgets.MetadataView;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -66,10 +55,7 @@ public class PlaybackFragment extends Fragment {
private PlaybackModel mModel;
private PlaybackControls mPlaybackControls;
private ImageView mAlbumArt;
- private TextView mTitle;
- private TextView mTime;
- private TextView mSubtitle;
- private SeekBar mSeekbar;
+ private MetadataView mMetadataView;
private PagedListView mQueueList;
private QueueItemsAdapter mQueueAdapter;
private MediaItemMetadata mCurrentMetadata;
@@ -138,10 +124,7 @@ public class PlaybackFragment extends Fragment {
ViewGroup playbackContainer = view.findViewById(R.id.playback_container);
mPlaybackControls.setAnimationViewGroup(playbackContainer);
mAlbumArt = view.findViewById(R.id.album_art);
- mTitle = view.findViewById(R.id.title);
- mSubtitle = view.findViewById(R.id.subtitle);
- mSeekbar = view.findViewById(R.id.seek_bar);
- mTime = view.findViewById(R.id.time);
+ mMetadataView = view.findViewById(R.id.metadata);
mQueueList = view.findViewById(R.id.queue_list);
RecyclerView recyclerView = mQueueList.getRecyclerView();
recyclerView.setVerticalFadingEdgeEnabled(true);
@@ -157,24 +140,18 @@ public class PlaybackFragment extends Fragment {
public void onStart() {
super.onStart();
mModel.registerObserver(mPlaybackObserver);
+ mMetadataView.setModel(mModel);
}
@Override
public void onStop() {
super.onStop();
mModel.unregisterObserver(mPlaybackObserver);
+ mMetadataView.setModel(null);
mCurrentMetadata = null;
}
private void updateState() {
- updateProgress();
-
- if (mModel.isPlaying()) {
- mSeekbar.post(mSeekBarRunnable);
- } else {
- mSeekbar.removeCallbacks(mSeekBarRunnable);
- }
-
mQueueAdapter.refresh();
}
@@ -184,8 +161,6 @@ public class PlaybackFragment extends Fragment {
return;
}
mCurrentMetadata = metadata;
- mTitle.setText(metadata != null ? metadata.getTitle() : null);
- mSubtitle.setText(metadata != null ? metadata.getSubtitle() : null);
MediaItemMetadata.updateImageView(getContext(), metadata, mAlbumArt, 0);
}
@@ -193,34 +168,7 @@ public class PlaybackFragment extends Fragment {
int defaultColor = getResources().getColor(android.R.color.background_dark, null);
MediaSource mediaSource = mModel.getMediaSource();
int color = mediaSource == null ? defaultColor : mediaSource.getAccentColor(defaultColor);
- mSeekbar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
-
- private static final long SEEK_BAR_UPDATE_TIME_INTERVAL_MS = 500;
-
- private final Runnable mSeekBarRunnable = new Runnable() {
- @Override
- public void run() {
- if (!mModel.isPlaying()) {
- return;
- }
- updateProgress();
- mSeekbar.postDelayed(this, SEEK_BAR_UPDATE_TIME_INTERVAL_MS);
-
- }
- };
-
- private void updateProgress() {
- long maxProgress = mModel.getMaxProgress();
- int visibility = maxProgress > 0 ? View.VISIBLE : View.INVISIBLE;
- String time = String.format("%s / %s",
- TIME_FORMAT.format(new Date(mModel.getProgress())),
- TIME_FORMAT.format(new Date(maxProgress)));
- mTime.setVisibility(visibility);
- mTime.setText(time);
- mSeekbar.setVisibility(visibility);
- mSeekbar.setMax((int) mModel.getMaxProgress());
- mSeekbar.setProgress((int) mModel.getProgress());
+ // TODO: Update queue color
}
private void onQueueItemClicked(MediaItemMetadata item) {
diff --git a/src/com/android/car/media/drawer/MediaDrawerController.java b/src/com/android/car/media/drawer/MediaDrawerController.java
index 06b20685..077cd740 100644
--- a/src/com/android/car/media/drawer/MediaDrawerController.java
+++ b/src/com/android/car/media/drawer/MediaDrawerController.java
@@ -149,7 +149,7 @@ public class MediaDrawerController implements MediaDrawerAdapter.MediaFetchCallb
mDrawerController.removeDrawerListener(mQueueDrawerListener);
mRootAdapter.cleanup();
mMediaPlaybackModel.removeListener(mModelListener);
- mMediaPlaybackModel.stop();
+ mMediaPlaybackModel.stop();
}
/**
diff --git a/src/com/android/car/media/util/widgets/PlayPauseStopImageView.java b/src/com/android/car/media/util/widgets/PlayPauseStopImageView.java
deleted file mode 100644
index 7289bbc3..00000000
--- a/src/com/android/car/media/util/widgets/PlayPauseStopImageView.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2016 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.util.widgets;
-
-import android.content.Context;
-import android.graphics.PorterDuff;
-import android.media.session.PlaybackState;
-import android.support.annotation.IntDef;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.ImageView;
-import com.android.car.media.R;
-
-import com.android.car.apps.common.ColorChecker;
-import com.android.car.apps.common.FabDrawable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Custom {@link android.widget.ImageButton} that has three custom states:
- * state_playing
- * state_paused
- * state_buffering
- * state_stopped
- */
-public class PlayPauseStopImageView extends ImageView {
- private static final String TAG = "GH.PlayPauseImageView";
- /**
- * All existing play states in {@link android.media.session.PlaybackState} are
- * positive integers.
- */
- public static final int PLAYBACKSTATE_DISABLED = -2;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({MODE_PAUSE, MODE_STOP})
- @interface ActionModes {}
- public static final int MODE_PAUSE = 1;
- public static final int MODE_STOP = 2;
-
- private final int[] STATE_PLAYING_TO_PAUSE = {R.attr.state_playing_to_pause};
- private final int[] STATE_PLAYING_TO_STOP = {R.attr.state_playing_to_stop};
- private final int[] STATE_PAUSED = {R.attr.state_paused};
- private final int[] STATE_BUFFERING_TO_PAUSE = {R.attr.state_buffering_to_pause};
- private final int[] STATE_BUFFERING_TO_STOP = {R.attr.state_buffering_to_stop};
- private final int[] STATE_STOPPED = {R.attr.state_stopped};
- private final int[] STATE_DISABLED = {R.attr.state_disabled};
-
- private int mPlaybackState = -1;
- // Set pause mode as default, so it will show pause icon if the mode flag doesn't change.
- private int mMode = MODE_PAUSE;
-
- public PlayPauseStopImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setBackground(new FabDrawable(context));
- }
-
- /**
- * Sets the current play state to be represented by this Button.
- *
- * @param playState One of the values returned by {@link PlaybackState#getState()}.
- */
- public void setPlayState(int playState) {
- mPlaybackState = playState;
- }
-
- public void setMode(@ActionModes int mode) {
- mMode = mode;
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- // + 1 so we can potentially add our custom PlayState
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-
- switch(mPlaybackState) {
- case PlaybackState.STATE_PLAYING:
- if (mMode == MODE_STOP) {
- mergeDrawableStates(drawableState, STATE_PLAYING_TO_STOP);
- } else {
- mergeDrawableStates(drawableState, STATE_PLAYING_TO_PAUSE);
- }
- break;
- case PlaybackState.STATE_PAUSED:
- mergeDrawableStates(drawableState, STATE_PAUSED);
- break;
- case PlaybackState.STATE_BUFFERING:
- case PlaybackState.STATE_CONNECTING:
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- case PlaybackState.STATE_SKIPPING_TO_NEXT:
- case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
- if (mMode == MODE_STOP) {
- mergeDrawableStates(drawableState, STATE_BUFFERING_TO_STOP);
- } else {
- mergeDrawableStates(drawableState, STATE_BUFFERING_TO_PAUSE);
- }
- break;
- case PlaybackState.STATE_STOPPED:
- mergeDrawableStates(drawableState, STATE_STOPPED);
- break;
- case PLAYBACKSTATE_DISABLED:
- mergeDrawableStates(drawableState, STATE_DISABLED);
- break;
- default:
- Log.e(TAG, "Unknown PlaybackState: " + mPlaybackState);
- }
- if (getBackground() != null) {
- getBackground().setState(drawableState);
- }
- return drawableState;
- }
-
- public void setPrimaryActionColor(int color) {
- ((FabDrawable) getBackground()).setFabAndStrokeColor(color);
- if (getDrawable() != null) {
- int tintColor = ColorChecker.getTintColor(getContext(), color);
- getDrawable().setColorFilter(tintColor, PorterDuff.Mode.SRC_IN);
- }
- }
-}
diff --git a/src/com/android/car/media/util/widgets/MediaItemTabView.java b/src/com/android/car/media/widgets/MediaItemTabView.java
index 2bcd4d48..c70cdffa 100644
--- a/src/com/android/car/media/util/widgets/MediaItemTabView.java
+++ b/src/com/android/car/media/widgets/MediaItemTabView.java
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package com.android.car.media.util.widgets;
+package com.android.car.media.widgets;
import android.content.Context;
-import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
diff --git a/src/com/android/car/media/widgets/MetadataView.java b/src/com/android/car/media/widgets/MetadataView.java
new file mode 100644
index 00000000..4b3fb38b
--- /dev/null
+++ b/src/com/android/car/media/widgets/MetadataView.java
@@ -0,0 +1,187 @@
+package com.android.car.media.widgets;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.android.car.media.R;
+import com.android.car.media.common.MediaItemMetadata;
+import com.android.car.media.common.PlaybackModel;
+
+import java.lang.annotation.Retention;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * A view that can be used to display the metadata and playback progress of a media item.
+ * This view can be styled using the "MetadataView" styleable attributes.
+ */
+public class MetadataView extends RelativeLayout {
+ private static final DateFormat TIME_FORMAT = new SimpleDateFormat("m:ss", Locale.US);
+
+ @Nullable
+ private MediaItemMetadata mCurrentMetadata;
+ private TextView mTitle;
+ private TextView mTime;
+ private TextView mSubtitle;
+ private SeekBar mSeekbar;
+ @Nullable
+ private PlaybackModel mModel;
+
+ private PlaybackModel.PlaybackObserver mPlaybackObserver =
+ new PlaybackModel.PlaybackObserver() {
+ @Override
+ public void onPlaybackStateChanged() {
+ updateState();
+ }
+
+ @Override
+ public void onSourceChanged() {
+ updateState();
+ updateMetadata();
+ }
+
+ @Override
+ public void onMetadataChanged() {
+ updateMetadata();
+ }
+ };
+
+ /**
+ * The possible styles of this widget.
+ */
+ @IntDef({
+ MetadataView.Style.COMPACT,
+ MetadataView.Style.NORMAL
+ })
+ @Retention(SOURCE)
+ public @interface Style {
+ /** Compact style (small space between elements, no time progress indicator) */
+ int COMPACT = 0;
+ /** Normal style (normal spacing and progress indicator) */
+ int NORMAL = 1;
+ }
+
+ public MetadataView(Context context) {
+ super(context);
+ init(context, null, 0, 0);
+ }
+
+ public MetadataView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0, 0);
+ }
+
+ public MetadataView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs, defStyleAttr, 0);
+ }
+
+ public MetadataView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ TypedArray ta = context.obtainStyledAttributes(
+ attrs, R.styleable.MetadataView, defStyleAttr, defStyleRes);
+ @Style int style = ta.getInteger(R.styleable.MetadataView_style, Style.NORMAL);
+ ta.recycle();
+
+ int layoutId = style == Style.COMPACT
+ ? R.layout.metadata_compact
+ : R.layout.metadata_normal;
+
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(layoutId, this, true);
+
+ mTitle = findViewById(R.id.title);
+ mSubtitle = findViewById(R.id.subtitle);
+ mSeekbar = findViewById(R.id.seek_bar);
+ mTime = findViewById(R.id.time);
+ }
+
+ /**
+ * Registers the {@link PlaybackModel} this widget will use to follow playback state.
+ * Consumers of this class must unregister the {@link PlaybackModel} by calling this method with
+ * null.
+ *
+ * @param model {@link PlaybackModel} to subscribe, or null to unsubscribe.
+ */
+ public void setModel(@Nullable PlaybackModel model) {
+ if (mModel != null) {
+ mModel.unregisterObserver(mPlaybackObserver);
+ }
+ mModel = model;
+ if (mModel != null) {
+ mModel.registerObserver(mPlaybackObserver);
+ }
+ }
+
+ private void updateState() {
+ updateProgress();
+
+ if (mModel != null && mModel.isPlaying()) {
+ mSeekbar.post(mSeekBarRunnable);
+ } else {
+ mSeekbar.removeCallbacks(mSeekBarRunnable);
+ }
+ }
+
+ private void updateMetadata() {
+ MediaItemMetadata metadata = mModel != null ? mModel.getMetadata() : null;
+ if (Objects.equals(mCurrentMetadata, metadata)) {
+ return;
+ }
+ mCurrentMetadata = metadata;
+ mTitle.setText(metadata != null ? metadata.getTitle() : null);
+ mSubtitle.setText(metadata != null ? metadata.getSubtitle() : null);
+ }
+
+ private static final long SEEK_BAR_UPDATE_TIME_INTERVAL_MS = 1000;
+
+ private final Runnable mSeekBarRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (mModel == null || !mModel.isPlaying()) {
+ return;
+ }
+ updateProgress();
+ mSeekbar.postDelayed(this, SEEK_BAR_UPDATE_TIME_INTERVAL_MS);
+
+ }
+ };
+
+ private void updateProgress() {
+ if (mModel == null) {
+ mTime.setVisibility(View.INVISIBLE);
+ mSeekbar.setVisibility(View.INVISIBLE);
+ return;
+ }
+ long maxProgress = mModel.getMaxProgress();
+ int visibility = maxProgress > 0 ? View.VISIBLE : View.INVISIBLE;
+ if (mTime != null) {
+ String time = String.format("%s / %s",
+ TIME_FORMAT.format(new Date(mModel.getProgress())),
+ TIME_FORMAT.format(new Date(maxProgress)));
+ mTime.setVisibility(visibility);
+ mTime.setText(time);
+ }
+ mSeekbar.setVisibility(visibility);
+ mSeekbar.setMax((int) mModel.getMaxProgress());
+ mSeekbar.setProgress((int) mModel.getProgress());
+ }
+}