Replace app selector widget by regular icon button and app launcher.
Bug: 142731385
Test: Manual on device
Change-Id: I0fc666c57d4a8e70da4c726e1fd261be91c21b81
diff --git a/car-media-common/res/anim/media_app_selector_fade_in.xml b/car-media-common/res/anim/media_app_selector_fade_in.xml
deleted file mode 100644
index 83e154e..0000000
--- a/car-media-common/res/anim/media_app_selector_fade_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2017 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <alpha
- android:duration="@android:integer/config_mediumAnimTime"
- android:fromAlpha="0.2"
- android:toAlpha="1"/>
-</set>
diff --git a/car-media-common/res/anim/media_app_selector_fade_out.xml b/car-media-common/res/anim/media_app_selector_fade_out.xml
deleted file mode 100644
index 4a1ddf6..0000000
--- a/car-media-common/res/anim/media_app_selector_fade_out.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2017 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <alpha
- android:duration="@android:integer/config_mediumAnimTime"
- android:fromAlpha="1.0"
- android:toAlpha="0.2"/>
-</set>
diff --git a/car-media-common/res/drawable/ic_app_switch.xml b/car-media-common/res/drawable/ic_app_switch.xml
new file mode 100644
index 0000000..ff485cf
--- /dev/null
+++ b/car-media-common/res/drawable/ic_app_switch.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"/>
+</vector>
diff --git a/car-media-common/res/drawable/ic_media_select_arrow_drop_down.xml b/car-media-common/res/drawable/ic_media_select_arrow_drop_down.xml
deleted file mode 100644
index 2774d0f..0000000
--- a/car-media-common/res/drawable/ic_media_select_arrow_drop_down.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M7,10l5,5 5,-5z"/>
-</vector>
diff --git a/car-media-common/res/drawable/ic_media_select_arrow_drop_up.xml b/car-media-common/res/drawable/ic_media_select_arrow_drop_up.xml
deleted file mode 100644
index 1ba2974..0000000
--- a/car-media-common/res/drawable/ic_media_select_arrow_drop_up.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M7,14l5,-5 5,5z"/>
-</vector>
diff --git a/car-media-common/res/drawable/ic_tracklist.xml b/car-media-common/res/drawable/ic_tracklist.xml
index 97f182f..fadaa7e 100644
--- a/car-media-common/res/drawable/ic_tracklist.xml
+++ b/car-media-common/res/drawable/ic_tracklist.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/appbar_view_icon_size"
- android:height="@dimen/appbar_view_icon_size"
+ android:width="48dp"
+ android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="@color/selectable_button_tint_selector">
diff --git a/car-media-common/res/layout/app_selection_item.xml b/car-media-common/res/layout/app_selection_item.xml
deleted file mode 100644
index 92e177a..0000000
--- a/car-media-common/res/layout/app_selection_item.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~
- ~ Copyright (C) 2018 Google Inc.
- ~
- ~ 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/app_item"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/app_selection_item_margin_h"
- android:layout_marginEnd="@dimen/app_selection_item_margin_h"
- android:layout_marginBottom="@dimen/app_selection_item_margin_bottom"
- android:orientation="vertical"
- android:background="@drawable/car_card_ripple_background"
- android:padding="@dimen/app_selection_item_padding"
- android:gravity="center">
-
- <ImageView
- android:id="@+id/app_icon"
- android:layout_width="@dimen/app_selection_item_app_icon_size"
- android:layout_height="@dimen/app_selection_item_app_icon_size"
- android:layout_marginBottom="@dimen/app_selection_item_app_icon_margin_bottom"
- android:layout_gravity="center_horizontal" />
-
- <TextView
- android:id="@+id/app_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?attr/textAppearanceGridItem"
- android:gravity="center"
- android:singleLine="true"/>
-</LinearLayout>
diff --git a/car-media-common/res/layout/app_switch_widget.xml b/car-media-common/res/layout/app_switch_widget.xml
deleted file mode 100644
index d8b49b3..0000000
--- a/car-media-common/res/layout/app_switch_widget.xml
+++ /dev/null
@@ -1,29 +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.
--->
-<merge
- xmlns:android="http://schemas.android.com/apk/res/android">
- <ImageView
- android:id="@+id/app_switch_icon"
- android:layout_width="@dimen/app_switch_widget_switch_icon_size"
- android:layout_height="@dimen/app_switch_widget_switch_icon_size"
- android:tint="@color/app_switch_widget_icon_tint"/>
-
- <ImageView
- android:id="@+id/app_icon"
- android:layout_width="@dimen/app_switch_widget_app_icon_size"
- android:layout_height="@dimen/app_switch_widget_app_icon_size"/>
-</merge>
diff --git a/car-media-common/res/layout/fragment_app_selection.xml b/car-media-common/res/layout/fragment_app_selection.xml
deleted file mode 100644
index 05f1dcd..0000000
--- a/car-media-common/res/layout/fragment_app_selection.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~
- ~ Copyright (C) 2018 Google Inc.
- ~
- ~ 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"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center">
-
-<androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/actual_content"
- android:background="@color/app_selection_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="80dp">
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/app_bar_bottom"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_begin="@dimen/appbar_first_row_height" />
-
- <com.android.car.media.common.MediaAppSelectorWidget
- android:id="@+id/app_switch_container"
- android:layout_width="@dimen/app_switch_widget_width"
- android:layout_height="@dimen/appbar_view_icon_touch_target_size"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="@+id/app_bar_bottom"
- app:layout_constraintRight_toRightOf="parent"
- android:padding="@dimen/app_switch_widget_icon_padding"
- android:orientation="horizontal"
- android:background="@drawable/appbar_view_icon_background"
- android:gravity="center" />
-
- <com.android.car.apps.common.widget.PagedRecyclerView
- android:id="@+id/apps_grid"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/appbar_first_row_height"
- android:clickable="true"
- android:focusable="true"
- />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
-</FrameLayout>
diff --git a/car-media-common/res/layout/playback_fragment.xml b/car-media-common/res/layout/playback_fragment.xml
index 8123ca1..4404bf3 100644
--- a/car-media-common/res/layout/playback_fragment.xml
+++ b/car-media-common/res/layout/playback_fragment.xml
@@ -41,6 +41,18 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="@dimen/app_selector_icon_size"
+ android:layout_height="@dimen/app_selector_icon_size"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/playback_fragment_text_margin_x"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="@drawable/ic_app_switch"
+ app:layout_constraintTop_toTopOf="@+id/app_name"
+ app:layout_constraintBottom_toBottomOf="@+id/app_name"
+ app:layout_constraintLeft_toLeftOf="parent"/>
+
<TextView
android:id="@+id/app_name"
android:layout_width="0dp"
@@ -51,23 +63,10 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:singleLine="true"
android:includeFontPadding="false"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toLeftOf="@+id/app_switch_container"
+ app:layout_constraintLeft_toRightOf="@+id/app_icon"
+ app:layout_constraintRight_toLeftOf="@+id/app_selector"
app:layout_constraintTop_toTopOf="parent"/>
- <com.android.car.media.common.MediaAppSelectorWidget
- android:id="@+id/app_switch_container"
- android:layout_width="@dimen/app_switch_widget_width"
- android:layout_height="@dimen/appbar_view_icon_touch_target_size"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="@+id/app_name"
- app:layout_constraintBottom_toBottomOf="@+id/app_name"
- app:fullScreenDialog="false"
- android:padding="@dimen/app_switch_widget_icon_padding"
- android:orientation="horizontal"
- android:background="@drawable/appbar_view_icon_background"
- android:gravity="center" />
-
<TextView
android:id="@+id/title"
style="@style/PlaybackTitleStyle"
@@ -89,9 +88,29 @@
android:layout_marginLeft="@dimen/playback_fragment_text_margin_x"
android:layout_marginRight="@dimen/playback_fragment_text_margin_x"
app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintRight_toLeftOf="@+id/app_selector_container"
app:layout_constraintTop_toBottomOf="@+id/title"/>
+ <FrameLayout
+ android:id="@+id/app_selector_container"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/app_selector_icon_touch_target"
+ android:layout_height="@dimen/app_selector_icon_touch_target"
+ android:background="?android:attr/selectableItemBackground"
+ android:layout_marginRight="@dimen/app_selector_margin_x"
+ app:layout_constraintTop_toTopOf="@+id/app_name"
+ app:layout_constraintBottom_toBottomOf="@+id/app_name"
+ app:layout_constraintRight_toRightOf="parent">
+
+ <ImageView
+ android:id="@+id/app_selector"
+ android:layout_width="@dimen/app_selector_icon_size"
+ android:layout_height="@dimen/app_selector_icon_size"
+ android:layout_gravity="center"
+ android:src="@drawable/ic_app_switch"
+ android:tint="@color/icon_tint" />
+ </FrameLayout>
+
<com.android.car.media.common.PlaybackControlsActionBar
android:id="@+id/playback_controls"
android:layout_width="0dp"
diff --git a/car-media-common/res/values/attrs.xml b/car-media-common/res/values/attrs.xml
index 1ae9a35..75ff716 100644
--- a/car-media-common/res/values/attrs.xml
+++ b/car-media-common/res/values/attrs.xml
@@ -38,19 +38,4 @@
<enum name="right" value="2"/>
</attr>
</declare-styleable>
-
- <!-- Attributes for the MediaAppSelectorWidget. -->
- <declare-styleable name="MediaAppSelectorWidget">
- <!-- When false, the widget only displays the application's icon and doesn't react to taps.
- Default is true. -->
- <attr name="switchingEnabled" format="boolean"/>
-
- <!-- Whether the AppSelectionFragment opened by pressing the widget should be full screen.
- -->
- <attr name="fullScreenDialog" format="boolean"/>
-
- <!-- The size of the icons used in this widget -->
- <attr name="appIconSize" format="dimension"/>
-
- </declare-styleable>
</resources>
diff --git a/car-media-common/res/values/colors.xml b/car-media-common/res/values/colors.xml
index 7601e3d..6f9e489 100644
--- a/car-media-common/res/values/colors.xml
+++ b/car-media-common/res/values/colors.xml
@@ -18,12 +18,6 @@
<!-- Album art scrim -->
<color name="album_art_scrim">#000000</color>
- <!-- app_switch_widget.xml -->
- <color name="app_switch_widget_icon_tint">@color/primary_app_icon_color</color>
-
- <!-- App selection background -->
- <color name="app_selection_border">#40000000</color>
- <color name="app_selection_background">#ff000000</color>
<!-- App icons selection background -->
<color name="appbar_view_icon_background_color">#66ffffff</color>
diff --git a/car-media-common/res/values/config.xml b/car-media-common/res/values/config.xml
new file mode 100644
index 0000000..5cf1bc2
--- /dev/null
+++ b/car-media-common/res/values/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2019 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.
+ -->
+
+<resources>
+ <!-- Intent used to launch the app selector as popup -->
+ <string name="launcher_popup_intent" translatable="false">
+ intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_POPUP;end
+ </string>
+
+ <!-- Intent used to launch the app selector -->
+ <string name="launcher_intent" translatable="false">
+ intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_ONLY;end
+ </string>
+</resources>
\ No newline at end of file
diff --git a/car-media-common/res/values/dimens.xml b/car-media-common/res/values/dimens.xml
index ead8675..d11fd1b 100644
--- a/car-media-common/res/values/dimens.xml
+++ b/car-media-common/res/values/dimens.xml
@@ -21,24 +21,6 @@
<!-- Fab -->
<dimen name="fab_spinner_size">128dp</dimen>
- <!-- App bar -->
- <dimen name="appbar_first_row_height">@*android:dimen/car_app_bar_height</dimen>
- <!-- By default app bar has only 1 row -->
- <dimen name="appbar_second_row_height">0dp</dimen>
- <!-- The height of app bar when it expends to 2 rows. Equals 2 * @dimen/appbar_first_row_height. -->
- <dimen name="appbar_2_rows_height">160dp</dimen>
- <dimen name="appbar_view_icon_touch_target_size">76dp</dimen>
- <dimen name="appbar_view_icon_size">@*android:dimen/car_primary_icon_size</dimen>
- <!-- Padding of primary icon, equals (@dimen/appbar_view_icon_touch_target_size - @dimen/appbar_view_icon_size) / 2. -->
- <dimen name="appbar_view_icon_padding">16dp</dimen>
- <dimen name="appbar_view_search_bar_padding_start">62dp</dimen>
- <dimen name="appbar_view_search_bar_padding_end">60dp</dimen>
- <dimen name="appbar_view_search_app_icon_size">@*android:dimen/car_secondary_icon_size</dimen>
- <!-- negative margin to overlap icons on search bar -->
- <dimen name="appbar_view_search_app_icon_margin">-66dp</dimen>
- <dimen name="appbar_view_search_close_icon_margin">-76dp</dimen>
- <dimen name="appbar_view_search_bar_end_margin">16dp</dimen>
-
<!-- playback_fragment.xml -->
<dimen name="playback_fragment_text_margin_top">@*android:dimen/car_padding_4</dimen>
<dimen name="playback_fragment_text_margin_x">@*android:dimen/car_padding_4</dimen>
@@ -46,28 +28,14 @@
<dimen name="playback_fragment_app_icon_margin_right">@*android:dimen/car_padding_4</dimen>
<dimen name="playback_fragment_controls_margin_bottom">@*android:dimen/car_padding_4</dimen>
- <!-- app_switch_widget.xml -->
- <dimen name="app_switch_widget_width">@*android:dimen/car_margin</dimen>
- <dimen name="app_switch_widget_app_icon_size">@*android:dimen/car_primary_icon_size</dimen>
- <dimen name="app_switch_widget_switch_icon_size">@*android:dimen/car_secondary_icon_size</dimen>
- <dimen name="app_switch_widget_icon_padding">@*android:dimen/car_padding_1</dimen>
-
- <!-- app_selection_item.xml -->
- <dimen name="app_selection_item_margin_h">@*android:dimen/car_padding_2</dimen>
- <dimen name="app_selection_item_margin_bottom">@*android:dimen/car_padding_5</dimen>
- <dimen name="app_selection_item_padding">@*android:dimen/car_padding_1</dimen>
- <dimen name="app_selection_item_app_icon_size">@*android:dimen/car_touch_target_size</dimen>
- <dimen name="app_selection_item_app_icon_margin_bottom">@*android:dimen/car_padding_4</dimen>
-
<!-- Drawable appbar_view_icon_background.xml -->
<dimen name="appbar_view_icon_background_corner_radius">@*android:dimen/car_radius_2</dimen>
- <!-- fragment_app_selection.xml -->
- <dimen name="fragment_app_selection_list_top_offset">@*android:dimen/car_padding_5</dimen>
-
<!-- Minimized Progress Bar -->
<dimen name="minimized_progress_bar_track_thickness">4dp</dimen>
- <!-- appbar_view_icon_background.xml -->
- <dimen name="appbar_view_icon_background_radius">38dp</dimen>
+ <!-- App selector -->
+ <dimen name="app_selector_icon_size">@*android:dimen/car_primary_icon_size</dimen>
+ <dimen name="app_selector_icon_touch_target">@*android:dimen/car_touch_target_size</dimen>
+ <dimen name="app_selector_margin_x">@*android:dimen/car_padding_2</dimen>
</resources>
diff --git a/car-media-common/res/values/styles.xml b/car-media-common/res/values/styles.xml
index d4795b3..972837d 100644
--- a/car-media-common/res/values/styles.xml
+++ b/car-media-common/res/values/styles.xml
@@ -15,21 +15,6 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="MediaAppSelectorStyle" parent="android:Theme.DeviceDefault.NoActionBar">
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowBackground">@color/app_selection_border</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowBackground">@*android:color/car_card</item>
- <item name="android:fragmentOpenEnterAnimation">@anim/media_app_selector_fade_in</item>
- </style>
-
- <style
- name="media_app_selector_animation_fade" >
- <item name="android:windowEnterAnimation">@anim/media_app_selector_fade_in</item>
- <item name="android:windowExitAnimation">@anim/media_app_selector_fade_out</item>
- </style>
-
<style name="PlaybackTitleStyle" parent="TextAppearance.Body1">
<item name="android:singleLine">true</item>
<item name="android:includeFontPadding">false</item>
@@ -40,5 +25,4 @@
<item name="android:singleLine">true</item>
<item name="android:includeFontPadding">false</item>
</style>
-
</resources>
diff --git a/car-media-common/src/com/android/car/media/common/AppSelectionFragment.java b/car-media-common/src/com/android/car/media/common/AppSelectionFragment.java
deleted file mode 100644
index 95065eb..0000000
--- a/car-media-common/src/com/android/car/media/common/AppSelectionFragment.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2019 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.common;
-
-import android.annotation.NonNull;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.fragment.app.DialogFragment;
-import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.media.common.source.MediaSource;
-import com.android.car.media.common.source.MediaSourceViewModel;
-import com.android.car.media.common.source.MediaSourcesLiveData;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A {@link Fragment} that implements the app selection UI. It is typically created by a
- * {@link MediaAppSelectorWidget} widget that shows the current media source (stored as
- * {@link #mSelectorWidget}. To ensure visual coherence, the UI of the fragment also shows a
- * {@link MediaAppSelectorWidget} widget, but this one is in "display only" mode as tapping it
- * closes the fragment rather than opening a new one.
- * Note: the fragment dismisses itself in {@link #onStop} as its less confusing to come back to the
- * media app than the fragment after using another facet.
- */
-public class AppSelectionFragment extends DialogFragment {
-
- private static final String ORIGIN_SOURCE_PACKAGE_KEY = "origin_source_package_key";
- private static final String FULL_SCREEN_KEY = "full_screen_key";
-
- /** The widget that opened this fragment. */
- private final MediaAppSelectorWidget mSelectorWidget;
-
- private boolean mFullScreenDialog;
-
- /** The widget contained by this fragment UI to display the current source. */
- private MediaAppSelectorWidget mDisplayWidget;
-
- /**
- * Creates a new {@link AppSelectionFragment}.
- *
- * @param selectorWidget the widget that is opening this fragment
- */
- public static AppSelectionFragment create(MediaAppSelectorWidget selectorWidget,
- boolean fullScreenDialog) {
- AppSelectionFragment result = new AppSelectionFragment(selectorWidget);
- Bundle bundle = new Bundle(1);
- bundle.putBoolean(FULL_SCREEN_KEY, fullScreenDialog);
- result.setArguments(bundle);
- return result;
- }
-
- public AppSelectionFragment() {
- this(null);
- }
-
- private AppSelectionFragment(MediaAppSelectorWidget selectorWidget) {
- mSelectorWidget = selectorWidget;
- }
-
-
- private class AppGridAdapter extends RecyclerView.Adapter<AppItemViewHolder> {
- private List<MediaSource> mMediaSources;
-
- /**
- * Triggers a refresh of media sources
- */
- void updateSources(List<MediaSource> mediaSources) {
- mMediaSources = new ArrayList<>(mediaSources);
- notifyDataSetChanged();
- }
-
- @NonNull
- @Override
- public AppItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.app_selection_item, parent, false);
- return new AppItemViewHolder(view);
-
- }
-
- @Override
- public void onBindViewHolder(@NonNull AppItemViewHolder vh, int position) {
- vh.bind(mMediaSources.get(position));
- }
-
- @Override
- public int getItemCount() {
- return mMediaSources.size();
- }
- }
-
- private class AppItemViewHolder extends RecyclerView.ViewHolder {
- View mAppItem;
- ImageView mAppIconView;
- TextView mAppNameView;
-
- AppItemViewHolder(View view) {
- super(view);
- mAppItem = view.findViewById(R.id.app_item);
- mAppIconView = mAppItem.findViewById(R.id.app_icon);
- mAppNameView = mAppItem.findViewById(R.id.app_name);
- }
-
- /**
- * Binds a media source to a view
- */
- void bind(@NonNull MediaSource mediaSrc) {
- mAppItem.setOnClickListener(
- v -> {
- MediaSourceViewModel model = MediaSourceViewModel.get(
- requireActivity().getApplication());
- model.setPrimaryMediaSource(mediaSrc);
- dismiss();
- });
-
- mAppIconView.setImageDrawable(mediaSrc.getIcon());
- mAppNameView.setText(mediaSrc.getDisplayName());
- }
- }
-
- /** Closes the selector (allowing state loss). */
- @Override
- public void dismiss() {
- if (mSelectorWidget != null) {
- mSelectorWidget.setIsOpen(false);
- }
- mDisplayWidget.setIsOpen(false);
- // TODO(b/122324380) try using a shared element transition instead of this trick.
- // The delay is needed to update the arrow in the MediaAppSelectorWidget of this fragment
- // before the fragment fades away to reveal the underlying MediaAppSelectorWidget with an
- // arrow pointing the other way. Otherwise we end up seeing the arrows pointing in opposite
- // directions... Note that in the home screen the widgets are not overlapped.
- mDisplayWidget.postDelayed(() -> dismissAllowingStateLoss(), 50);
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- if (getDialog() != null) {
- getDialog().getWindow().setWindowAnimations(R.style.media_app_selector_animation_fade);
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- dismiss();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStyle(DialogFragment.STYLE_NORMAL, R.style.MediaAppSelectorStyle); // Full screen style.
-
- Bundle args = getArguments();
- if (args != null) {
- mFullScreenDialog = args.getBoolean(FULL_SCREEN_KEY, true);
- }
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_app_selection, container, false);
-
- if (mFullScreenDialog) {
- ViewGroup contentView = view.findViewById(R.id.actual_content);
- ViewGroup.MarginLayoutParams p =
- (ViewGroup.MarginLayoutParams) contentView.getLayoutParams();
- p.setMargins(0, 0, 0, 0);
- }
-
- int columnNumber = getResources().getInteger(R.integer.num_app_selector_columns);
- AppGridAdapter gridAdapter = new AppGridAdapter();
- gridAdapter.updateSources(MediaSourcesLiveData.getInstance(getContext()).getList());
- mDisplayWidget = view.findViewById(R.id.app_switch_container);
- mDisplayWidget.setFragmentOwner(this);
- mDisplayWidget.setFragmentActivity(getActivity());
-
- RecyclerView gridView = view.findViewById(R.id.apps_grid);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), columnNumber);
- gridView.setLayoutManager(gridLayoutManager);
- gridView.setAdapter(gridAdapter);
- return view;
- }
-}
diff --git a/car-media-common/src/com/android/car/media/common/MediaAppSelectorWidget.java b/car-media-common/src/com/android/car/media/common/MediaAppSelectorWidget.java
deleted file mode 100644
index 383115e..0000000
--- a/car-media-common/src/com/android/car/media/common/MediaAppSelectorWidget.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 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.common;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.car.apps.common.util.ViewUtils;
-import com.android.car.media.common.source.MediaSourceViewModel;
-
-/**
- * Widget showing the icon of the currently selected media application as well as an arrow
- * indicating whether the selection UI is shown. The widget can be embedded both in an application
- * bar where tapping it opens an {@link AppSelectionFragment}, and also in the UI of the selection
- * fragment to provide visual continuity and a way to close the fragment without selecting an
- * application.
- * In order for the widget to connect to {@link MediaSourceViewModel} (so it can update its icon),
- * {@link #setFragmentActivity} must be called by the code that creates a view containing this
- * widget.
- */
-public class MediaAppSelectorWidget extends LinearLayout {
-
- private final boolean mFullScreenDialog;
- private final boolean mSwitchingEnabled;
- private final ImageView mAppIcon;
- private final ImageView mAppSwitchIcon;
- private final Drawable mDefaultIcon;
- private final Drawable mArrowDropDown;
- private final Drawable mArrowDropUp;
-
- private FragmentActivity mActivity;
-
- /** The fragment that owns the widget (only set when in display only mode). */
- @Nullable
- private AppSelectionFragment mFragmentOwner;
- private boolean mFragmentIsOpen;
-
- public MediaAppSelectorWidget(Context context) {
- this(context, null);
- }
-
- public MediaAppSelectorWidget(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public MediaAppSelectorWidget(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public MediaAppSelectorWidget(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.MediaAppSelectorWidget, defStyleAttr, 0 /* defStyleRes */);
- mFullScreenDialog = a.getBoolean(R.styleable.MediaAppSelectorWidget_fullScreenDialog, true);
- mSwitchingEnabled = a.getBoolean(R.styleable.MediaAppSelectorWidget_switchingEnabled, true);
- a.recycle();
-
- mDefaultIcon = getResources().getDrawable(R.drawable.ic_music);
- mArrowDropDown = getResources().getDrawable(R.drawable.ic_media_select_arrow_drop_down,
- null);
- mArrowDropUp = getResources().getDrawable(R.drawable.ic_media_select_arrow_drop_up, null);
-
- LayoutInflater inflater = LayoutInflater.from(context);
- inflater.inflate(R.layout.app_switch_widget, this, true);
-
- mAppIcon = findViewById(R.id.app_icon);
- mAppSwitchIcon = findViewById(R.id.app_switch_icon);
-
- setFragmentOwner(null);
- if (mSwitchingEnabled) {
- setOnClickListener(view -> onAppSwitchClicked());
- } else {
- ViewUtils.setVisible(mAppSwitchIcon, false);
- }
- }
-
- /** Calling this is required so the widget can show the icon of the primary media source. */
- public void setFragmentActivity(FragmentActivity activity) {
- mActivity = activity;
- MediaSourceViewModel model = MediaSourceViewModel.get(activity.getApplication());
- model.getPrimaryMediaSource().observe(activity, source -> {
- if (source == null) {
- setAppIcon(null);
- } else {
- setAppIcon(source.getRoundPackageIcon());
- }
- });
- }
-
- /** Opens the {@link AppSelectionFragment}. */
- public void open() {
- if (mSwitchingEnabled && !mFragmentIsOpen) {
- onAppSwitchClicked();
- }
- }
-
- /** Closes the {@link AppSelectionFragment}. */
- public void close() {
- if (mSwitchingEnabled && mFragmentIsOpen) {
- onAppSwitchClicked();
- }
- }
-
- /** Sets whether the widget is shown as part of an {@link AppSelectionFragment} UI. */
- void setFragmentOwner(@Nullable AppSelectionFragment fragmentOwner) {
- mFragmentOwner = fragmentOwner;
- setIsOpen(mFragmentOwner != null);
- }
-
- void setIsOpen(boolean fragmentIsOpen) {
- if (mSwitchingEnabled) {
- mFragmentIsOpen = fragmentIsOpen;
- mAppSwitchIcon.setImageDrawable(fragmentIsOpen ? mArrowDropUp : mArrowDropDown);
- }
- }
-
- /**
- * Updates the application icon to show next to the application switcher.
- */
- private void setAppIcon(Bitmap icon) {
- if (icon != null) {
- mAppIcon.setImageBitmap(icon);
- } else {
- mAppIcon.setImageDrawable(mDefaultIcon);
- }
- }
-
- private void onAppSwitchClicked() {
- if (mFragmentOwner != null) {
- mFragmentOwner.dismiss();
- } else {
- setIsOpen(true);
- AppSelectionFragment newFragment = AppSelectionFragment.create(this, mFullScreenDialog);
- newFragment.show(mActivity.getSupportFragmentManager(), null);
- }
-
- }
-}
diff --git a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
index 8d04733..36f428d 100644
--- a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
+++ b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
@@ -27,6 +27,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -45,8 +46,6 @@
import com.android.car.media.common.playback.PlaybackViewModel;
import com.android.car.media.common.source.MediaSource;
import com.android.car.media.common.source.MediaSourceViewModel;
-import com.android.internal.util.Preconditions;
-
/**
* {@link Fragment} that can be used to display and control the currently playing media item. Its
@@ -54,7 +53,7 @@
* application.
*/
public class PlaybackFragment extends Fragment {
-
+ private Intent mAppSelectorIntent;
private MediaSourceViewModel mMediaSourceViewModel;
private ImageBinder<MediaItemMetadata.ArtworkRef> mAlbumArtBinder;
@@ -65,6 +64,7 @@
FragmentActivity activity = requireActivity();
PlaybackViewModel playbackViewModel = PlaybackViewModel.get(activity.getApplication());
mMediaSourceViewModel = MediaSourceViewModel.get(activity.getApplication());
+ mAppSelectorIntent = MediaSource.getSourceSelectorIntent(getContext(), true);
ViewModel innerViewModel = ViewModelProviders.of(activity).get(ViewModel.class);
innerViewModel.init(mMediaSourceViewModel, playbackViewModel);
@@ -86,6 +86,9 @@
TextView subtitle = view.findViewById(R.id.subtitle);
innerViewModel.getSubtitle().observe(getViewLifecycleOwner(), subtitle::setText);
+ ImageView appIcon = view.findViewById(R.id.app_icon);
+ innerViewModel.getAppIcon().observe(getViewLifecycleOwner(), appIcon::setImageBitmap);
+
CrossfadeImageView albumBackground = view.findViewById(R.id.album_background);
albumBackground.setOnClickListener(
// Let the Media center trampoline figure out what to open.
@@ -103,10 +106,9 @@
playbackViewModel.getMetadata().observe(getViewLifecycleOwner(),
item -> mAlbumArtBinder.setImage(PlaybackFragment.this.getContext(),
item != null ? item.getArtworkKey() : null));
-
- MediaAppSelectorWidget appSelector = view.findViewById(R.id.app_switch_container);
- Preconditions.checkNotNull(appSelector);
- appSelector.setFragmentActivity(getActivity());
+ View appSelector = view.findViewById(R.id.app_selector_container);
+ appSelector.setVisibility(mAppSelectorIntent != null ? View.VISIBLE : View.GONE);
+ appSelector.setOnClickListener(e -> getContext().startActivity(mAppSelectorIntent));
return view;
}
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSource.java b/car-media-common/src/com/android/car/media/common/source/MediaSource.java
index bbc96dc..f856eb2 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaSource.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSource.java
@@ -37,10 +37,13 @@
import android.util.Log;
import com.android.car.apps.common.BitmapUtils;
+import com.android.car.media.common.R;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.Objects;
+
/**
* This represents a source of media content. It provides convenient methods to access media source
* metadata, such as application name and icon.
@@ -226,4 +229,23 @@
public String toString() {
return mBrowseService.flattenToString();
}
+
+ /**
+ * @return an intent to open the media source selector, or null if no source selector is
+ * configured.
+ * @param popup Whether the intent should point to the regular app selector (false), which
+ * would open the selected media source in Media Center, or the "popup" version
+ * (true), which would just select the source and dismiss itself.
+ */
+ @Nullable
+ public static Intent getSourceSelectorIntent(Context context, boolean popup) {
+ String uri = context.getString(popup ? R.string.launcher_popup_intent
+ : R.string.launcher_intent);
+ try {
+ return uri != null && !uri.isEmpty() ? Intent.parseUri(uri, Intent.URI_INTENT_SCHEME)
+ : null;
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException("Wrong app-launcher intent: " + uri, e);
+ }
+ }
}
diff --git a/car-ui-lib/res/values/bools.xml b/car-ui-lib/res/values/bools.xml
index e139c83..cb7d18d 100644
--- a/car-ui-lib/res/values/bools.xml
+++ b/car-ui-lib/res/values/bools.xml
@@ -26,23 +26,26 @@
<bool name="car_ui_toolbar_logo_fills_nav_icon_space">true</bool>
<!-- Whether tabs should be displayed on a second row, or they should be placed in the first
row, replacing the title -->
- <bool name="car_ui_toolbar_tabs_on_second_row">true</bool>
+ <bool name="car_ui_toolbar_tabs_on_second_row">false</bool>
<!-- CarUiRecyclerView -->
<!-- Whether to display the Scroll Bar or not. Defaults to true. If this is set to false,
the CarUiRecyclerView will behave exactly like the RecyclerView. -->
<bool name="car_ui_scrollbar_enable">true</bool>
-
<!-- Whether to place the scrollbar z-index above the recycler view. Defaults to
true. -->
<bool name="car_ui_scrollbar_above_recycler_view">true</bool>
<!-- Preferences -->
+ <!-- Whether toggle transition should be animated or not -->
<bool name="car_ui_preference_switch_toggle_show_animation">true</bool>
+ <!-- Whether a text track should be used instead of the standard device default track -->
<bool name="car_ui_preference_switch_toggle_use_text_track">false</bool>
+ <!-- Whether list, edit, dropdown and intent preferences should show a chevron or not -->
<bool name="car_ui_preference_show_chevron">false</bool>
+ <!-- whether list preference should be shown in full screen or as a dialog -->
<bool name="car_ui_preference_list_show_full_screen">true</bool>
<!-- List items -->
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
index 3f90b59..d937098 100644
--- a/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
@@ -429,6 +429,12 @@
setState(getState());
}
+ /** Removes all the tabs. */
+ public void clearAllTabs() {
+ mTabLayout.clearAllTabs();
+ setState(getState());
+ }
+
/**
* Gets a tab added to this toolbar. See
* {@link #addTab(TabLayout.Tab)}.