summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHrX03 <dn.bianco03@gmail.com>2019-03-07 17:50:40 +0000
committeralk3pInjection <webmaster@raspii.tech>2021-09-27 21:17:05 +0800
commit05568d9edda0458d238f3d962c9ed3e10ee4dd15 (patch)
treed3d91ec86ce75f4d76754b4567860020ebbb7612
parent41fa200574b0a00085569d47dda7dcb5bcfea0f9 (diff)
[aospa][quartz] SystemUI: Redesign volume dialog
Inspiration from MiUI, iOS and Dil3mm4 Change-Id: I8bddda04c83c995bec82e9493017db69bd460b34 Co-Authored-By: Andrew Fluck <andrew@aospa.co> Co-Authored-By: rituj <ritujbeniwal@gmail.com> Co-Authored-By: Jyotiraditya <jyotiraditya@aospa.co> Co-Authored-By: Akash Srivastava <akashsrivastava@aospa.co> Co-Authored-By: 00day0 <therandomuser11@gmail.com> Co-authored-by: Kshitij Gupta <kshitijgm@gmail.com> base: Redo expanded volume panel for 10.x [ HrX03 | AgentFabulous - POSP ] - Google nuked expanded volume panel in pie. Redo the current implementation to bring this back from the past and dejank it. - Back to Android 8.x functionality! Change-Id: Ie4931a4ae09483ba737a74fc32ed0a1f6acf105d Co-authored-by: Kshitij Gupta <kshitijgm@gmail.com> Signed-off-by: Arian <arian.kulmer@web.de> SystemUI: VolumePanel: Version 1.1 * Add support for unlinked notification volume * Fix progress bar inconsistencies when switching ringer modes * Some minor animation tweaks Change-Id: I31f87aacb7fbb445dd3b03ceb5064263e5af4836 VolumeDialogImpl: fix ConcurrentModificationException SDB: it's happening to only a few users and let make those fc free msg: java.util.ConcurrentModificationException stacktrace: java.util.ConcurrentModificationException at java.util.ArrayList$Itr.next(ArrayList.java:860) at com.android.systemui.volume.VolumeDialogImpl.updateMediaOutputViewH(VolumeDialogImpl.java:905) at com.android.systemui.volume.VolumeDialogImpl.access$4800(VolumeDialogImpl.java:120) at com.android.systemui.volume.VolumeDialogImpl$H.handleMessage(VolumeDialogImpl.java:1912) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7657) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:594) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) VolumePluginManager: Fix fc for stock panel Change-Id: Ib0f6340ac7fea08abc637a1c3391a58cc4f1dfb6 VolumeDialogImpl: Reschedule the timeout on clicks on captions Change-Id: Ie98813a91396f3c3a84aeac8a609071c5cc315f6 VolumePanel: Fix glitchy ringer and notif bar when switching modes Co-Authored-By: Andrew Fluck <andrew@aospa.co> Co-Authored-By: rituj <ritujbeniwal@gmail.com> Co-Authored-By: Jyotiraditya <jyotiraditya@aospa.co> Co-Authored-By: Akash Srivastava <akashsrivastava@aospa.co> Co-Authored-By: 00day0 <therandomuser11@gmail.com> Co-authored-by: Kshitij Gupta <kshitijgm@gmail.com> Signed-off-by: rituj <ritujbeniwal@gmail.com> Signed-off-by: Arian <arian.kulmer@web.de> Signed-off-by: rituj <ritujbeniwal@gmail.com> Signed-off-by: althafvly <althafvly@gmail.com> Change-Id: I585c7366cb99c0c3baf699a5a553e77da895d195
-rw-r--r--packages/SystemUI/res/drawable/ic_speaker_bluetooth.xml23
-rw-r--r--packages/SystemUI/res/drawable/ic_tick_mark_media.xml23
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_notification.xml7
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_notification_mute.xml11
-rw-r--r--packages/SystemUI/res/drawable/rounded_ripple.xml2
-rw-r--r--packages/SystemUI/res/drawable/rounded_volume_background.xml5
-rw-r--r--packages/SystemUI/res/drawable/volume_dialog_seekbar.xml21
-rw-r--r--packages/SystemUI/res/layout-land/volume_dialog.xml264
-rw-r--r--packages/SystemUI/res/layout-land/volume_tool_tip_view.xml64
-rw-r--r--packages/SystemUI/res/layout/volume_dialog.xml271
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_media_output.xml93
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_row.xml108
-rw-r--r--packages/SystemUI/res/layout/volume_dnd_icon.xml3
-rw-r--r--packages/SystemUI/res/layout/volume_tool_tip_view.xml23
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml1
-rw-r--r--packages/SystemUI/res/values-land/dimens.xml3
-rw-r--r--packages/SystemUI/res/values-night/colors.xml3
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml1
-rw-r--r--packages/SystemUI/res/values/colors.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml38
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/res/values/styles.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java795
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java18
30 files changed, 1376 insertions, 422 deletions
diff --git a/packages/SystemUI/res/drawable/ic_speaker_bluetooth.xml b/packages/SystemUI/res/drawable/ic_speaker_bluetooth.xml
new file mode 100644
index 000000000000..7a4b23e90483
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_speaker_bluetooth.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2020 The Paranoid Android 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:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M4,3A2,2 0 0,0 2,5V19A2,2 0 0,0 4,21H12A2,2 0 0,0 14,19V5A2,2 0 0,0 12,3H4M8,5A2,2 0 0,1 10,7A2,2 0 0,1 8,9A2,2 0 0,1 6,7A2,2 0 0,1 8,5M19,7V10.79L16.71,8.5L16,9.21L18.79,12L16,14.79L16.71,15.5L19,13.21V17H19.5L22.35,14.14L20.21,12L22.35,9.85L19.5,7H19M20,8.91L20.94,9.85L20,10.79V8.91M8,11A4,4 0 0,1 12,15A4,4 0 0,1 8,19A4,4 0 0,1 4,15A4,4 0 0,1 8,11M8,13A2,2 0 0,0 6,15A2,2 0 0,0 8,17A2,2 0 0,0 10,15A2,2 0 0,0 8,13M20,13.21L20.94,14.14L20,15.08V13.21Z" />
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_tick_mark_media.xml b/packages/SystemUI/res/drawable/ic_tick_mark_media.xml
new file mode 100644
index 000000000000..49df1a9324b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_tick_mark_media.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2020 The Paranoid Android 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:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_volume_notification.xml b/packages/SystemUI/res/drawable/ic_volume_notification.xml
index 42eb7b7f3f88..d56120c366ac 100644
--- a/packages/SystemUI/res/drawable/ic_volume_notification.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_notification.xml
@@ -21,10 +21,7 @@
android:tint="?android:attr/colorControlNormal" >
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M20,16H6L4,18V4H20" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_notification_mute.xml b/packages/SystemUI/res/drawable/ic_volume_notification_mute.xml
index 9cb7ca3679b9..387388743767 100644
--- a/packages/SystemUI/res/drawable/ic_volume_notification_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_notification_mute.xml
@@ -21,13 +21,10 @@
android:tint="?android:attr/colorControlNormal" >
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+ android:fillColor="#FFFFFF"
+ android:pathData="M2.08,21.85V5C1.41,4.36 0.74 ,3.71 0.09 ,3L1.37,1.79,22,22.39l-1.26,1.24L15.07,18H6l-3.9,3.9Zm2-14.78c-0.06 0.49 -0.06,10.65,0,10.81a1,1,0,0,0,0.16-0.12l1.64-1.64A0.46 0.46 ,0,0,1,6.29,16H13Z" />
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/>
+ android:fillColor="#FFFFFF"
+ android:pathData="M18.13,16h1.7A1.16,1.16,0,0,0,20,16V4.27A1.6,1.6,0,0,0,20,4H6.19v0A1.81,1.81,0,0,1,6,3.89L4.28,2.21l-0.15-0.15 0.21 ,0H19.87a2.16,2.16,0,0,1,1.35 0.43 ,1.89,1.89,0,0,1,0.71,1.13,3.68,3.68,0,0,1,0.06 0.57 V15.86a2,2,0,0,1-0.6,1.53A1.87,1.87,0,0,1,20.2,18a0.27 0.27 ,0,0,1-0.21-0.07L18.2,16.1S18.17,16,18.13,16Z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/rounded_ripple.xml b/packages/SystemUI/res/drawable/rounded_ripple.xml
index d9ed8233d886..5851d1d7f812 100644
--- a/packages/SystemUI/res/drawable/rounded_ripple.xml
+++ b/packages/SystemUI/res/drawable/rounded_ripple.xml
@@ -23,7 +23,7 @@
</item>
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?android:attr/colorBackgroundFloating"/>
+ <solid android:color="@null"/>
<corners android:radius="8dp"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/rounded_volume_background.xml b/packages/SystemUI/res/drawable/rounded_volume_background.xml
new file mode 100644
index 000000000000..6f377cf54793
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_volume_background.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="?android:attr/dialogCornerRadius" />
+ <solid android:color="?android:attr/colorBackgroundFloating" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_seekbar.xml b/packages/SystemUI/res/drawable/volume_dialog_seekbar.xml
new file mode 100644
index 000000000000..02a3c628c3de
--- /dev/null
+++ b/packages/SystemUI/res/drawable/volume_dialog_seekbar.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@android:id/progress">
+ <clip
+ android:clipOrientation="horizontal"
+ android:gravity="left">
+ <selector>
+ <item
+ android:drawable="@android:color/transparent"
+ android:state_enabled="false" />
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="?android:attr/dialogCornerRadius" />
+ <size android:height="@dimen/volume_dialog_panel_width" />
+ <solid android:color="?android:attr/colorAccent" />
+ </shape>
+ </item>
+ </selector>
+ </clip>
+ </item>
+</layer-list>
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index 5da7819c3d76..2b577399a5af 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -13,135 +13,199 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<FrameLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/volume_dialog_container"
+ android:id="@+id/volume_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
android:background="@android:color/transparent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:gravity="start"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding"
+ android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding_left_right"
+ android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_left_right"
+ android:paddingTop="@dimen/volume_dialog_panel_transparent_padding"
android:theme="@style/qs_theme">
- <FrameLayout
- android:id="@+id/volume_dialog"
- android:minWidth="@dimen/volume_dialog_panel_width"
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
- android:background="@android:color/transparent"
- android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
- android:paddingTop="@dimen/volume_dialog_panel_transparent_padding"
- android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding"
- android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding"
- android:clipToPadding="false">
+ android:layout_marginBottom="@dimen/volume_dialog_spacer"
+ android:clipChildren="false"
+ android:gravity="start"
+ android:orientation="horizontal">
<FrameLayout
android:id="@+id/ringer"
- android:layout_width="@dimen/volume_dialog_ringer_size"
- android:layout_height="@dimen/volume_dialog_ringer_size"
- android:layout_marginBottom="@dimen/volume_dialog_spacer"
- android:gravity="right"
- android:layout_gravity="right"
- android:translationZ="@dimen/volume_dialog_elevation"
- android:clipToPadding="false"
- android:background="@drawable/rounded_bg_full">
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:layout_marginEnd="@dimen/volume_dialog_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation">
+
<com.android.keyguard.AlphaOptimizedImageButton
android:id="@+id/ringer_icon"
style="@style/VolumeButtons"
- android:background="@drawable/rounded_ripple"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:scaleType="fitCenter"
- android:padding="@dimen/volume_dialog_ringer_icon_padding"
- android:tint="@color/accent_tint_color_selector"
- android:layout_gravity="center"
- android:soundEffectsEnabled="false" />
-
- <include layout="@layout/volume_dnd_icon"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/volume_dialog_stream_padding"
- android:layout_marginTop="6dp"/>
+ android:padding="16dp"
+ android:tint="?android:attr/colorAccent" />
+
+ <include
+ layout="@layout/volume_dnd_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:layout_marginStart="6dp"
+ android:layout_marginTop="6dp" />
</FrameLayout>
<LinearLayout
- android:id="@+id/main"
- android:layout_width="wrap_content"
- android:minWidth="@dimen/volume_dialog_panel_width"
- android:layout_height="wrap_content"
- android:layout_marginTop="68dp"
- android:gravity="right"
- android:layout_gravity="right"
+ android:id="@+id/expandable_indicator_container"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:layout_marginEnd="@dimen/volume_dialog_row_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <com.android.systemui.statusbar.phone.ExpandableIndicator
+ android:id="@+id/expandable_indicator"
+ style="@style/VolumeButtons"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="match_parent"
+ android:contentDescription="@string/accessibility_quick_settings_expand"
+ android:rotation="90" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/media_button_view"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:layout_marginEnd="@dimen/volume_dialog_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
android:orientation="vertical"
- android:translationZ="@dimen/volume_dialog_elevation"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:background="@drawable/rounded_bg_full" >
+ android:visibility="gone">
+
+ <com.android.keyguard.AlphaOptimizedImageButton
+ android:id="@+id/media_button"
+ style="@style/VolumeButtons"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="13dp"
+ android:src="@drawable/ic_speaker_bluetooth" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
<LinearLayout
- android:id="@+id/volume_dialog_rows"
+ android:id="@+id/odi_captions"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minWidth="@dimen/volume_dialog_panel_width"
- android:gravity="center"
- android:orientation="horizontal"
- android:paddingRight="@dimen/volume_dialog_stream_padding"
- android:paddingLeft="@dimen/volume_dialog_stream_padding">
- <!-- volume rows added and removed here! :-) -->
+ android:layout_height="match_parent"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <com.android.systemui.volume.CaptionsToggleImageButton
+ android:id="@+id/odi_captions_icon"
+ style="@style/VolumeButtons"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_volume_odi_captions_disabled"
+ sysui:optedOut="false" />
</LinearLayout>
- <FrameLayout
- android:id="@+id/settings_container"
- android:layout_width="match_parent"
+
+ <ViewStub
+ android:id="@+id/odi_captions_tooltip_stub"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/rounded_bg_bottom_background">
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/settings"
- android:src="@drawable/ic_tune_black_16dp"
- android:layout_width="@dimen/volume_dialog_tap_target_size"
- android:layout_height="@dimen/volume_dialog_tap_target_size"
- android:layout_gravity="center"
- android:contentDescription="@string/accessibility_volume_settings"
- android:background="@drawable/ripple_drawable_20dp"
- android:tint="?android:attr/textColorSecondary"
- android:soundEffectsEnabled="false" />
- </FrameLayout>
+ android:layout_marginStart="@dimen/volume_dialog_spacer"
+ android:inflatedId="@+id/odi_captions_tooltip_view"
+ android:layout="@layout/volume_tool_tip_view" />
</LinearLayout>
+ </LinearLayout>
- <FrameLayout
- android:id="@+id/odi_captions"
- android:layout_width="@dimen/volume_dialog_caption_size"
- android:layout_height="@dimen/volume_dialog_caption_size"
- android:layout_marginRight="68dp"
- android:gravity="right"
- android:layout_gravity="right"
- android:clipToPadding="false"
- android:translationZ="@dimen/volume_dialog_elevation"
- android:background="@drawable/rounded_bg_full">
- <com.android.systemui.volume.CaptionsToggleImageButton
- android:id="@+id/odi_captions_icon"
- android:src="@drawable/ic_volume_odi_captions_disabled"
- style="@style/VolumeButtons"
- android:background="@drawable/rounded_ripple"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:tint="@color/caption_tint_color_selector"
- android:layout_gravity="center"
- android:soundEffectsEnabled="false"
- sysui:optedOut="false"/>
- </FrameLayout>
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/volume_dialog_slider_height"
+ android:layout_marginTop="@dimen/volume_dialog_spacer"
+ android:clipChildren="false"
+ android:clipToPadding="false">
- <ViewStub
- android:id="@+id/odi_captions_tooltip_stub"
- android:inflatedId="@+id/odi_captions_tooltip_view"
- android:layout="@layout/volume_tool_tip_view"
+ <LinearLayout
+ android:id="@+id/volume_dialog_rows"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/volume_tool_tip_right_margin"
- android:layout_marginTop="@dimen/volume_tool_tip_top_margin"
- android:layout_gravity="right"/>
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:gravity="center"
+ android:minWidth="@dimen/volume_dialog_panel_width"
+ android:orientation="horizontal">
+ <!-- volume rows added and removed here! :-) -->
+ </LinearLayout>
- </FrameLayout>
+ <LinearLayout
+ android:id="@+id/media_output_scroller"
+ android:layout_width="@dimen/volume_dialog_media_width"
+ android:layout_height="match_parent"
+ android:background="@drawable/rounded_volume_background"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <com.android.systemui.statusbar.AlphaOptimizedTextView
+ android:id="@+id/media_output_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:clickable="false"
+ android:ellipsize="marquee"
+ android:focusable="true"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:paddingBottom="5dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="6dp"
+ android:paddingTop="5dp"
+ android:singleLine="true"
+ android:text="@string/media_output_title"
+ android:textColor="?android:attr/colorControlNormal"
+ android:textSize="15sp"
+ android:textStyle="bold" />
-</FrameLayout> \ No newline at end of file
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:background="@color/divider_stroke_color" />
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fillViewport="true"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/media_output_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top"
+ android:gravity="top"
+ android:layoutDirection="rtl"
+ android:orientation="vertical">
+ <!-- media output devices added and removed here -->
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+ </FrameLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-land/volume_tool_tip_view.xml b/packages/SystemUI/res/layout-land/volume_tool_tip_view.xml
new file mode 100644
index 000000000000..3af2b789fcac
--- /dev/null
+++ b/packages/SystemUI/res/layout-land/volume_tool_tip_view.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<com.android.systemui.volume.VolumeToolTipView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/tooltip_view"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <View
+ android:id="@+id/arrow"
+ android:layout_width="@dimen/volume_tool_tip_arrow_width"
+ android:layout_height="@dimen/volume_tool_tip_arrow_height"
+ android:layout_marginEnd="@dimen/volume_tool_tip_arrow_margin_container" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingEnd="4dp"
+ android:paddingStart="16dp"
+ android:background="@drawable/volume_tool_tip_rounded_bg"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/volume_odi_captions_tip"
+ android:textColor="@android:color/white"
+ android:textSize="14sp" />
+
+ <ImageView
+ android:id="@+id/dismiss"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_gravity="center_vertical"
+ android:padding="12dp"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:alpha="0.7"
+ android:src="@drawable/ic_remove_no_shadow"
+ android:tint="@android:color/white"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:contentDescription="@string/accessibility_volume_close_odi_captions_tip"/>
+ </LinearLayout>
+
+</com.android.systemui.volume.VolumeToolTipView>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 2296b613d56c..32440e14ffbc 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -13,131 +13,214 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/volume_dialog_container"
+ android:id="@+id/volume_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
android:background="@android:color/transparent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding"
+ android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding_left_right"
+ android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_left_right"
+ android:paddingTop="@dimen/volume_dialog_panel_transparent_padding"
android:theme="@style/qs_theme">
- <!-- right-aligned to be physically near volume button -->
<LinearLayout
- android:id="@+id/volume_dialog"
- android:minWidth="@dimen/volume_dialog_panel_width"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@android:color/transparent"
- android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
- android:paddingTop="@dimen/volume_dialog_panel_transparent_padding"
- android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding"
- android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding"
- android:orientation="vertical"
- android:clipToPadding="false">
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ android:orientation="horizontal">
<FrameLayout
android:id="@+id/ringer"
- android:layout_width="@dimen/volume_dialog_ringer_size"
- android:layout_height="@dimen/volume_dialog_ringer_size"
- android:layout_marginBottom="@dimen/volume_dialog_spacer"
- android:translationZ="@dimen/volume_dialog_elevation"
- android:clipToPadding="false"
- android:background="@drawable/rounded_bg_full">
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation">
+
<com.android.keyguard.AlphaOptimizedImageButton
android:id="@+id/ringer_icon"
style="@style/VolumeButtons"
- android:background="@drawable/rounded_ripple"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:scaleType="fitCenter"
- android:padding="@dimen/volume_dialog_ringer_icon_padding"
- android:tint="@color/accent_tint_color_selector"
- android:layout_gravity="center"
- android:soundEffectsEnabled="false" />
-
- <include layout="@layout/volume_dnd_icon"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="6dp"/>
+ android:padding="16dp"
+ android:tint="?android:attr/colorAccent" />
+
+ <include
+ layout="@layout/volume_dnd_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:layout_marginStart="6dp"
+ android:layout_marginTop="6dp" />
</FrameLayout>
+ </LinearLayout>
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/volume_dialog_slider_height"
+ android:layout_marginTop="@dimen/volume_dialog_spacer"
+ android:clipChildren="false"
+ android:clipToPadding="false">
<LinearLayout
- android:id="@+id/main"
- android:minWidth="@dimen/volume_dialog_panel_width"
+ android:id="@+id/volume_dialog_rows"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
- android:orientation="vertical"
- android:translationZ="@dimen/volume_dialog_elevation"
android:clipChildren="false"
android:clipToPadding="false"
- android:background="@drawable/rounded_bg_full" >
- <LinearLayout
- android:id="@+id/volume_dialog_rows"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minWidth="@dimen/volume_dialog_panel_width"
- android:gravity="center"
- android:orientation="horizontal"
- android:paddingRight="@dimen/volume_dialog_stream_padding"
- android:paddingLeft="@dimen/volume_dialog_stream_padding">
- <!-- volume rows added and removed here! :-) -->
- </LinearLayout>
- <FrameLayout
- android:id="@+id/settings_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/rounded_bg_bottom_background">
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/settings"
- android:src="@drawable/ic_tune_black_16dp"
- android:layout_width="@dimen/volume_dialog_tap_target_size"
- android:layout_height="@dimen/volume_dialog_tap_target_size"
- android:layout_gravity="center"
- android:contentDescription="@string/accessibility_volume_settings"
- android:background="@drawable/ripple_drawable_20dp"
- android:tint="?android:attr/textColorSecondary"
- android:soundEffectsEnabled="false" />
- </FrameLayout>
+ android:gravity="center"
+ android:minWidth="@dimen/volume_dialog_panel_width"
+ android:orientation="horizontal">
+ <!-- volume rows added and removed here! :-) -->
</LinearLayout>
- <FrameLayout
- android:id="@+id/odi_captions"
- android:layout_width="@dimen/volume_dialog_caption_size"
- android:layout_height="@dimen/volume_dialog_caption_size"
- android:layout_marginTop="@dimen/volume_dialog_spacer"
- android:gravity="right"
- android:layout_gravity="right"
+ <LinearLayout
+ android:id="@+id/media_output_scroller"
+ android:layout_width="@dimen/volume_dialog_media_width"
+ android:layout_height="match_parent"
+ android:background="@drawable/rounded_volume_background"
+ android:clickable="false"
+ android:clipChildren="false"
android:clipToPadding="false"
- android:translationZ="@dimen/volume_dialog_elevation"
- android:background="@drawable/rounded_bg_full">
- <com.android.systemui.volume.CaptionsToggleImageButton
- android:id="@+id/odi_captions_icon"
- android:src="@drawable/ic_volume_odi_captions_disabled"
- style="@style/VolumeButtons"
- android:background="@drawable/rounded_ripple"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <com.android.systemui.statusbar.AlphaOptimizedTextView
+ android:id="@+id/media_output_title"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:tint="@color/caption_tint_color_selector"
- android:layout_gravity="center"
- android:soundEffectsEnabled="false"
- sysui:optedOut="false"/>
- </FrameLayout>
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:clickable="false"
+ android:ellipsize="marquee"
+ android:focusable="true"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:paddingBottom="5dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="6dp"
+ android:paddingTop="5dp"
+ android:singleLine="true"
+ android:text="@string/media_output_title"
+ android:textColor="?android:attr/colorControlNormal"
+ android:textSize="15sp"
+ android:textStyle="bold" />
- </LinearLayout>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:background="@color/divider_stroke_color" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fillViewport="true"
+ android:scrollbars="none">
- <ViewStub
- android:id="@+id/odi_captions_tooltip_stub"
- android:inflatedId="@+id/odi_captions_tooltip_view"
- android:layout="@layout/volume_tool_tip_view"
+ <LinearLayout
+ android:id="@+id/media_output_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top"
+ android:gravity="top"
+ android:layoutDirection="rtl"
+ android:orientation="vertical">
+ <!-- media output devices added and removed here -->
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+ </LinearLayout>
+ </FrameLayout>
+
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom | right"
- android:layout_marginRight="@dimen/volume_tool_tip_right_margin"
- android:layout_marginBottom="@dimen/volume_tool_tip_bottom_margin"/>
+ android:clipChildren="false"
+ android:layout_marginTop="@dimen/volume_dialog_spacer"
+ android:minWidth="@dimen/volume_dialog_panel_width"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:id="@+id/expandable_indicator_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/volume_dialog_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical">
+
+ <com.android.systemui.statusbar.phone.ExpandableIndicator
+ android:id="@+id/expandable_indicator"
+ style="@style/VolumeButtons"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_button_height"
+ android:background="@drawable/ripple_drawable_20dp"
+ android:rotation="90" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/media_button_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/volume_dialog_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <com.android.keyguard.AlphaOptimizedImageButton
+ android:id="@+id/media_button"
+ style="@style/VolumeButtons"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_button_height"
+ android:background="@drawable/ripple_drawable_20dp"
+ android:padding="10dp"
+ android:src="@drawable/ic_speaker_bluetooth" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/odi_captions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <com.android.systemui.volume.CaptionsToggleImageButton
+ android:id="@+id/odi_captions_icon"
+ style="@style/VolumeButtons"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_button_height"
+ android:background="@drawable/ripple_drawable_20dp"
+ android:src="@drawable/ic_volume_odi_captions_disabled"
+ sysui:optedOut="false" />
+ </LinearLayout>
-</FrameLayout> \ No newline at end of file
+ <ViewStub
+ android:id="@+id/odi_captions_tooltip_stub"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/volume_dialog_spacer"
+ android:inflatedId="@+id/odi_captions_tooltip_view"
+ android:layout="@layout/volume_tool_tip_view" />
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog_media_output.xml b/packages/SystemUI/res/layout/volume_dialog_media_output.xml
new file mode 100644
index 000000000000..30490d06dfd6
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_dialog_media_output.xml
@@ -0,0 +1,93 @@
+<!--
+ Copyright (C) 2020 The AOSPA-Extended 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:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="4dp"
+ android:layout_gravity="end|top"
+ android:gravity="end"
+ android:background="@drawable/rounded_ripple"
+ android:clickable="true"
+ android:orientation="horizontal"
+ android:theme="@style/qs_theme">
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/media_output_selected"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="start|center_vertical"
+ android:gravity="center"
+ android:src="@drawable/ic_tick_mark_media"
+ android:padding="6dp"
+ android:scaleType="fitCenter"
+ android:clickable="false"
+ android:tint="?android:attr/colorControlNormal"
+ android:soundEffectsEnabled="false"
+ android:visibility="gone" />
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|center_vertical"
+ android:layout_weight="1"
+ android:gravity="end"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:clickable="false"
+ android:orientation="vertical">
+ <com.android.systemui.statusbar.AlphaOptimizedTextView
+ android:id="@+id/media_output_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:gravity="left"
+ android:clickable="false"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:focusable="true"
+ android:singleLine="true"
+ android:textSize="14sp"
+ android:textStyle="bold"
+ android:textColor="?android:attr/colorControlNormal" />
+ <com.android.systemui.statusbar.AlphaOptimizedTextView
+ android:id="@+id/media_output_summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:gravity="left"
+ android:ellipsize="marquee"
+ android:clickable="false"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:focusable="true"
+ android:layout_marginTop="-2dp"
+ android:singleLine="true"
+ android:textSize="11sp"
+ android:textStyle="italic"
+ android:textColor="?android:attr/colorControlNormal"
+ android:visibility="gone" />
+ </LinearLayout>
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/media_output_icon"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_gravity="end|center_vertical"
+ android:gravity="left"
+ android:padding="2dp"
+ android:clickable="false"
+ android:scaleType="fitCenter"
+ android:soundEffectsEnabled="false"/>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 6128da8627a9..aa9c403f47ad 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -17,55 +17,73 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:tag="row"
android:layout_height="wrap_content"
- android:layout_width="@dimen/volume_dialog_panel_width"
- android:clipChildren="false"
- android:clipToPadding="false"
+ android:layout_width="wrap_content"
+ android:layout_marginEnd="@dimen/volume_dialog_row_spacer"
+ android:background="@drawable/rounded_volume_background"
+ android:elevation="@dimen/volume_dialog_elevation"
android:theme="@style/qs_theme">
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:gravity="center"
- android:layout_gravity="center"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/volume_row_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:maxLength="10"
- android:maxLines="1"
- android:visibility="gone"
- android:textColor="?android:attr/colorControlNormal"
- android:textAppearance="@style/TextAppearance.Volume.Header" />
- <FrameLayout
- android:id="@+id/volume_row_slider_frame"
- android:layout_width="match_parent"
- android:layout_marginTop="@dimen/volume_dialog_slider_margin_top"
- android:layout_marginBottom="@dimen/volume_dialog_slider_margin_bottom"
+ <FrameLayout
+ android:id="@+id/volume_row_slider_frame"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_slider_height">
+
+ <SeekBar
+ android:id="@+id/volume_row_slider"
+ android:layout_width="@dimen/volume_dialog_slider_height"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:layout_gravity="center"
+ android:background="@null"
+ android:clickable="true"
android:layoutDirection="rtl"
- android:layout_height="@dimen/volume_dialog_slider_height">
- <SeekBar
- android:id="@+id/volume_row_slider"
- android:clickable="true"
- android:layout_width="@dimen/volume_dialog_slider_height"
- android:layout_height="match_parent"
- android:layoutDirection="rtl"
- android:layout_gravity="center"
- android:rotation="90" />
- </FrameLayout>
+ android:paddingBottom="0dp"
+ android:paddingEnd="0dp"
+ android:paddingStart="0dp"
+ android:paddingTop="0dp"
+ android:progressDrawable="@drawable/volume_dialog_seekbar"
+ android:rotation="90"
+ android:thumb="@android:color/transparent" />
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/volume_row_icon"
- style="@style/VolumeButtons"
- android:layout_width="@dimen/volume_dialog_tap_target_size"
- android:layout_height="@dimen/volume_dialog_tap_target_size"
- android:background="@drawable/ripple_drawable_20dp"
- android:layout_marginBottom="@dimen/volume_dialog_row_margin_bottom"
- android:tint="@color/accent_tint_color_selector"
- android:soundEffectsEnabled="false" />
- </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:orientation="vertical">
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/volume_row_icon"
+ android:layout_width="@dimen/volume_dialog_row_icon_size"
+ android:layout_height="@dimen/volume_dialog_tap_target_size"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="-12dp"
+ android:clickable="false"
+ android:layoutDirection="ltr"
+ android:scaleType="fitCenter"
+ android:soundEffectsEnabled="false"
+ android:tint="?android:attr/colorAccent" />
- <include layout="@layout/volume_dnd_icon"/>
+ <com.android.systemui.statusbar.AlphaOptimizedTextView
+ android:id="@+id/volume_row_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="10dp"
+ android:ellipsize="end"
+ android:gravity="bottom|center_horizontal"
+ android:layoutDirection="ltr"
+ android:maxLength="10"
+ android:maxLines="1"
+ android:textAppearance="@style/TextAppearance.Volume.Header"
+ android:textColor="?android:attr/colorAccent"
+ android:textStyle="bold" />
+ </LinearLayout>
+ </FrameLayout>
+ <include
+ layout="@layout/volume_dnd_icon"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:layout_marginStart="6dp"
+ android:layout_marginTop="6dp" />
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
index 10c1472ae993..1adfb316ac59 100644
--- a/packages/SystemUI/res/layout/volume_dnd_icon.xml
+++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml
@@ -16,14 +16,13 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dnd_icon"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
- android:layout_gravity="right|top"
android:src="@*android:drawable/ic_qs_dnd"
android:tint="?android:attr/textColorTertiary"/>
</FrameLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_tool_tip_view.xml b/packages/SystemUI/res/layout/volume_tool_tip_view.xml
index 9fe885ebefc7..8de18821ad97 100644
--- a/packages/SystemUI/res/layout/volume_tool_tip_view.xml
+++ b/packages/SystemUI/res/layout/volume_tool_tip_view.xml
@@ -20,13 +20,20 @@
android:id="@+id/tooltip_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:orientation="horizontal">
+ android:orientation="vertical">
+
+ <View
+ android:id="@+id/arrow"
+ android:layout_width="@dimen/volume_tool_tip_arrow_width"
+ android:layout_height="@dimen/volume_tool_tip_arrow_height"
+ android:layout_marginBottom="@dimen/volume_tool_tip_arrow_margin_container"
+ android:layout_marginStart="@dimen/volume_tool_tip_arrow_margin_start"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="16dp"
android:paddingEnd="4dp"
+ android:paddingStart="16dp"
android:background="@drawable/volume_tool_tip_rounded_bg"
android:orientation="horizontal">
@@ -35,9 +42,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:textColor="@android:color/white"
android:text="@string/volume_odi_captions_tip"
- android:textSize="14sp"/>
+ android:textColor="@android:color/white"
+ android:textSize="14sp" />
+
<ImageView
android:id="@+id/dismiss"
android:layout_width="40dp"
@@ -53,11 +61,4 @@
android:contentDescription="@string/accessibility_volume_close_odi_captions_tip"/>
</LinearLayout>
- <View
- android:id="@+id/arrow"
- android:layout_width="8dp"
- android:layout_height="10dp"
- android:layout_marginLeft="-2dp"
- android:layout_gravity="center_vertical"/>
-
</com.android.systemui.volume.VolumeToolTipView> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7b6ad6bd7b52..4138a7672bf2 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Impossible de se connecter. Réessayez."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
+ <string name="media_output_title" msgid="115223550977351699">"Diffuser des contenus multimédias sur"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 91488fa7094f..55e1d897a39f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(未接続)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"接続できませんでした。もう一度お試しください。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
+ <string name="media_output_title" msgid="115223550977351699">"メディアの再生先"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"電池残量の読み込み中に問題が発生しました"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f5aadc85eab4..1b8cb2286dc9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(연결 끊김)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"연결할 수 없습니다. 다시 시도하세요."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
+ <string name="media_output_title" msgid="115223550977351699">"미디어 출력 대상"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 531b2d4a3114..254256719192 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -33,8 +33,7 @@
<integer name="quick_settings_num_columns">4</integer>
<dimen name="qs_detail_margin_top">0dp</dimen>
- <dimen name="volume_tool_tip_right_margin">136dp</dimen>
- <dimen name="volume_tool_tip_top_margin">12dp</dimen>
+ <dimen name="volume_dialog_icon_padding">17dp</dimen>
<!-- Padding between status bar and bubbles when displayed in expanded state, smaller
value in landscape since we have limited vertical space-->
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index b956956aa1ab..f7a85973ca7a 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -105,4 +105,7 @@
<!-- Color of background circle of user avatars in quick settings user switcher -->
<color name="qs_user_switcher_avatar_background">#3C4043</color>
+ <color name="volume_background_tint">#141414</color>
+ <color name="divider_stroke_color">#434343</color>
+
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 405cbdb22a48..bf08ddb45481 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1110,6 +1110,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (отключено)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Не удалось подключиться. Повторите попытку."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
+ <string name="media_output_title" msgid="115223550977351699">"Где воспроизводить"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удается получить данные об уровне заряда батареи"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b42c89d30634..0382cb3fa64a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(已断开连接)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"无法连接。请重试。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
+ <string name="media_output_title" msgid="115223550977351699">"媒体播放到"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"读取电池计量器时出现问题"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index a1e7054c9faa..4f0cf4c5f8f5 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (已中斷連線)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"無法連線,請再試一次。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <string name="media_output_title" msgid="115223550977351699">"播放媒體的裝置"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ed114c488fff..fe08028f4042 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1098,6 +1098,7 @@
<string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (已中斷連線)"</string>
<string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"無法連線,請再試一次。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <string name="media_output_title" msgid="115223550977351699">"播放媒體"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 461fe2f9d4d2..ae177dfd59ad 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -271,4 +271,7 @@
<color name="misalignment_text_color">#F28B82</color>
<color name="screenrecord_status_color">#E94235</color>
+
+ <color name="volume_background_tint">#f2f2f2</color>
+ <color name="divider_stroke_color">#E0E0E0</color>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ed72e8ba02a0..ae697fd6720b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -439,37 +439,33 @@
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
<dimen name="volume_dialog_panel_transparent_padding_right">4dp</dimen>
-
- <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
-
+ <dimen name="volume_dialog_panel_transparent_padding_left_right">8dp</dimen>
<dimen name="volume_dialog_stream_padding">8dp</dimen>
-
- <dimen name="volume_dialog_panel_width">64dp</dimen>
-
- <dimen name="volume_dialog_slider_height">116dp</dimen>
-
+ <dimen name="volume_tool_tip_top_margin">12dp</dimen>
<dimen name="volume_dialog_ringer_size">64dp</dimen>
-
<dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
-
<dimen name="volume_dialog_caption_size">64dp</dimen>
-
- <dimen name="volume_dialog_tap_target_size">48dp</dimen>
-
+ <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
+ <dimen name="volume_dialog_panel_width">54dp</dimen>
+ <dimen name="volume_dialog_slider_height">185dp</dimen>
+ <dimen name="volume_dialog_icon_padding">13dp</dimen>
+ <dimen name="volume_dialog_tap_target_size">@dimen/volume_dialog_panel_width</dimen>
+ <dimen name="volume_dialog_media_width">170dp</dimen>
<dimen name="volume_dialog_spacer">4dp</dimen>
-
- <dimen name="volume_dialog_slider_margin_top">14dp</dimen>
-
- <dimen name="volume_dialog_slider_margin_bottom">-2dp</dimen>
-
+ <dimen name="volume_dialog_button_height">45dp</dimen>
+ <dimen name="volume_dialog_row_icon_size">24dp</dimen>
+ <dimen name="volume_dialog_row_spacer">@dimen/volume_dialog_spacer</dimen>
<dimen name="volume_dialog_row_margin_bottom">8dp</dimen>
-
<dimen name="volume_dialog_elevation">9dp</dimen>
+ <dimen name="volume_dialog_slider_margin_top">14dp</dimen>
+ <dimen name="volume_dialog_slider_margin_bottom">-2dp</dimen>
<dimen name="volume_tool_tip_right_margin">76dp</dimen>
-
<dimen name="volume_tool_tip_bottom_margin">32dp</dimen>
-
+ <dimen name="volume_tool_tip_arrow_height">8dp</dimen>
+ <dimen name="volume_tool_tip_arrow_width">10dp</dimen>
+ <dimen name="volume_tool_tip_arrow_margin_container">-2dp</dimen>
+ <dimen name="volume_tool_tip_arrow_margin_start">24dp</dimen>
<dimen name="volume_tool_tip_arrow_corner_radius">2dp</dimen>
<!-- Gravity for the notification panel -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3d08c6680319..d7183d73caad 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1059,6 +1059,9 @@
<!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
<string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+ <!-- Title for media output settings -->
+ <string name="media_output_title">Play media to</string>
+
<!-- Zen mode: Priority only introduction message on first use -->
<string name="zen_priority_introduction">You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games.</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1c0518208dea..787b6e9e01cf 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -488,7 +488,14 @@
</style>
<style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
- <item name="android:background">@drawable/btn_borderless_rect</item>
+ <item name="android:layout_gravity">center</item>
+ <item name="android:background">@drawable/rounded_ripple</item>
+ <item name="android:clickable">true</item>
+ <item name="android:focusable">true</item>
+ <item name="android:padding">@dimen/volume_dialog_icon_padding</item>
+ <item name="android:scaleType">fitCenter</item>
+ <item name="android:soundEffectsEnabled">false</item>
+ <item name="android:tint">?android:attr/colorControlNormal</item>
</style>
<style name="DockedDividerBackground">
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index c128cdf8a9c0..aa18d1b62b44 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -543,6 +543,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
updateRingerModeExternalW(mRingerModeObservers.mRingerMode.getValue());
updateZenModeW();
updateZenConfig();
+ updateLinkNotificationConfigW();
updateEffectsSuppressorW(mNoMan.getEffectsSuppressor());
mCallbacks.onStateChanged(mState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 587b10480708..74605da708d7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -23,16 +23,18 @@ import static android.media.AudioManager.RINGER_MODE_VIBRATE;
import static android.media.AudioManager.STREAM_ACCESSIBILITY;
import static android.media.AudioManager.STREAM_ALARM;
import static android.media.AudioManager.STREAM_MUSIC;
+import static android.media.AudioManager.STREAM_NOTIFICATION;
import static android.media.AudioManager.STREAM_RING;
import static android.media.AudioManager.STREAM_VOICE_CALL;
import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
import static android.view.View.GONE;
-import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -50,6 +52,7 @@ import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.os.Debug;
@@ -70,9 +73,13 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.AccessibilityDelegate;
+import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
+import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
@@ -81,12 +88,18 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.android.settingslib.Utils;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.media.InfoMediaManager;
+import com.android.settingslib.media.LocalMediaManager;
+import com.android.settingslib.media.MediaDevice;
+import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dependency;
import com.android.systemui.Prefs;
import com.android.systemui.R;
@@ -96,6 +109,7 @@ import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.plugins.VolumeDialogController.State;
import com.android.systemui.plugins.VolumeDialogController.StreamState;
+import com.android.systemui.statusbar.phone.ExpandableIndicator;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -112,7 +126,7 @@ import java.util.List;
* Methods ending in "H" must be called on the (ui) handler.
*/
public class VolumeDialogImpl implements VolumeDialog,
- ConfigurationController.ConfigurationListener {
+ ConfigurationController.ConfigurationListener, LocalMediaManager.DeviceCallback {
private static final String TAG = Util.logTag(VolumeDialogImpl.class);
private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
@@ -125,6 +139,11 @@ public class VolumeDialogImpl implements VolumeDialog,
static final int DIALOG_SHOW_ANIMATION_DURATION = 300;
static final int DIALOG_HIDE_ANIMATION_DURATION = 250;
+ private static final int SLIDER_PROGRESS_ALPHA_ACTIVE = 100;
+ private static final int SLIDER_PROGRESS_ALPHA_ACTIVE_DARK = 60;
+ private static final int SLIDER_PROGRESS_ALPHA = 50;
+ private static final int SLIDER_PROGRESS_ALPHA_DARK = 40;
+
private final Context mContext;
private final H mHandler = new H();
private final VolumeDialogController mController;
@@ -135,11 +154,16 @@ public class VolumeDialogImpl implements VolumeDialog,
private ViewGroup mDialogView;
private ViewGroup mDialogRowsView;
private ViewGroup mRinger;
+ private ViewGroup mMediaOutputView;
+ private ViewGroup mMediaOutputScrollView;
+ private ViewGroup mMediaButtonView;
+ private TextView mMediaTitleText;
+ private ImageButton mMediaButton;
private ImageButton mRingerIcon;
private ViewGroup mODICaptionsView;
private CaptionsToggleImageButton mODICaptionsIcon;
- private View mSettingsView;
- private ImageButton mSettingsIcon;
+ private View mExpandRowsView;
+ private ExpandableIndicator mExpandRows;
private FrameLayout mZenIcon;
private final List<VolumeRow> mRows = new ArrayList<>();
private ConfigurableTexts mConfigurableTexts;
@@ -163,12 +187,28 @@ public class VolumeDialogImpl implements VolumeDialog,
private boolean mShowActiveStreamOnly;
private boolean mConfigChanged = false;
private boolean mIsAnimatingDismiss = false;
+ private boolean mODIServiceComponentEnabled;
+ private boolean mPendingOdiCaptionsTooltip;
private boolean mHasSeenODICaptionsTooltip;
private ViewStub mODICaptionsTooltipViewStub;
private View mODICaptionsTooltipView = null;
private boolean mHasAlertSlider;
private boolean mLeftVolumeRocker;
+ private LocalMediaManager mLocalMediaManager;
+ private Animator mCurrAnimator;
+
+ private boolean mDarkMode;
+ private boolean mVibrateOnSlider;
+
+ private boolean mExpanded;
+ private boolean mShowingMediaDevices;
+
+ private float mElevation;
+ private float mHeight, mWidth, mSpacer;
+
+ private final List<MediaOutputRow> mMediaOutputRows = new ArrayList<>();
+
public VolumeDialogImpl(Context context) {
mContext =
new ContextThemeWrapper(context, R.style.qs_theme);
@@ -182,11 +222,33 @@ public class VolumeDialogImpl implements VolumeDialog,
Prefs.getBoolean(context, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
mHasAlertSlider = mContext.getResources().getBoolean(com.android.internal.R.bool.config_hasAlertSlider);
mLeftVolumeRocker = mContext.getResources().getBoolean(R.bool.config_audioPanelOnLeftSide);
+ mVibrateOnSlider = mContext.getResources().getBoolean(R.bool.config_vibrateOnIconAnimation);
+ mElevation = mContext.getResources().getDimension(R.dimen.volume_dialog_elevation);
+ mSpacer = mContext.getResources().getDimension(R.dimen.volume_dialog_row_spacer);
+
+ setDarkMode();
}
@Override
public void onUiModeChanged() {
mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
+ removeAllMediaOutputRows();
+ setDarkMode();
+ }
+
+ private void setDarkMode() {
+ final int nightModeFlag = mContext.getResources().getConfiguration().uiMode &
+ Configuration.UI_MODE_NIGHT_MASK;
+
+ switch (nightModeFlag) {
+ case Configuration.UI_MODE_NIGHT_YES:
+ mDarkMode = true;
+ break;
+ case Configuration.UI_MODE_NIGHT_NO:
+ case Configuration.UI_MODE_NIGHT_UNDEFINED:
+ mDarkMode = false;
+ break;
+ }
}
public void init(int windowType, Callback callback) {
@@ -205,16 +267,20 @@ public class VolumeDialogImpl implements VolumeDialog,
mController.removeCallback(mControllerCallbackH);
mHandler.removeCallbacksAndMessages(null);
Dependency.get(ConfigurationController.class).removeCallback(this);
+ if (mLocalMediaManager != null) {
+ mLocalMediaManager.unregisterCallback(this);
+ }
}
private void initDialog() {
mDialog = new CustomDialog(mContext);
-
mConfigurableTexts = new ConfigurableTexts(mContext);
mHovering = false;
mShowing = false;
+ mExpanded = false;
mWindow = mDialog.getWindow();
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+ mWindow.getDecorView();
mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
@@ -225,24 +291,44 @@ public class VolumeDialogImpl implements VolumeDialog,
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
- WindowManager.LayoutParams lp = mWindow.getAttributes();
+ final WindowManager.LayoutParams lp = mWindow.getAttributes();
lp.format = PixelFormat.TRANSLUCENT;
- lp.setTitle(VolumeDialogImpl.class.getSimpleName());
- lp.windowAnimations = -1;
+ lp.width = MATCH_PARENT;
+ lp.height = WRAP_CONTENT;
if(!isAudioPanelOnLeftSide()){
lp.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
} else {
lp.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
}
mWindow.setAttributes(lp);
- mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);
mDialog.setContentView(R.layout.volume_dialog);
mDialogView = mDialog.findViewById(R.id.volume_dialog);
+ FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mDialogView.getLayoutParams();
+ if(!isAudioPanelOnLeftSide()){
+ params.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+ } else {
+ params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+ }
+ mDialogView.setLayoutParams(params);
+ mDialogView.setLayoutDirection(
+ isAudioPanelOnLeftSide() ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL);
mDialogView.setAlpha(0);
mDialog.setCanceledOnTouchOutside(true);
mDialog.setOnShowListener(dialog -> {
- if (!isLandscape()) mDialogView.setTranslationX((mDialogView.getWidth() / 2.0f)*(!isAudioPanelOnLeftSide() ? 1 : -1));
+ ThreadUtils.postOnBackgroundThread(() -> {
+ if (mLocalMediaManager == null) {
+ LocalBluetoothManager lbm = Dependency.get(LocalBluetoothManager.class);
+ InfoMediaManager imm = new InfoMediaManager(mContext, null, null, lbm);
+ mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, null);
+ mLocalMediaManager.registerCallback(VolumeDialogImpl.this);
+ }
+ mLocalMediaManager.startScan();
+ });
+ if (!isLandscape()) {
+ mDialogView.setTranslationX(
+ (mDialogView.getWidth() / 2.0f) * (!isAudioPanelOnLeftSide() ? 1 : -1));
+ }
mDialogView.setAlpha(0);
mDialogView.animate()
.alpha(1)
@@ -273,6 +359,7 @@ public class VolumeDialogImpl implements VolumeDialog,
if (mRinger != null) {
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
mZenIcon = mRinger.findViewById(R.id.dnd_icon);
+ Util.setVisOrGone(mRinger, !mHasAlertSlider);
}
mODICaptionsView = mDialog.findViewById(R.id.odi_captions);
@@ -284,17 +371,16 @@ public class VolumeDialogImpl implements VolumeDialog,
mDialogView.removeView(mODICaptionsTooltipViewStub);
mODICaptionsTooltipViewStub = null;
}
- if (mHasAlertSlider) {
- mRinger.setVisibility(View.GONE);
- }
- if(!isAudioPanelOnLeftSide()) {
- mRinger.setForegroundGravity(Gravity.RIGHT);
- } else {
- mRinger.setForegroundGravity(Gravity.LEFT);
- }
- mSettingsView = mDialog.findViewById(R.id.settings_container);
- mSettingsIcon = mDialog.findViewById(R.id.settings);
+ mExpandRowsView = mDialog.findViewById(R.id.expandable_indicator_container);
+ mExpandRows = mExpandRowsView.findViewById(R.id.expandable_indicator);
+ mExpandRows.setScaleY(isAudioPanelOnLeftSide() ? -1f : 1f);
+
+ mMediaOutputView = mDialog.findViewById(R.id.media_output_container);
+ mMediaOutputScrollView = mDialog.findViewById(R.id.media_output_scroller);
+ mMediaButtonView = mDialog.findViewById(R.id.media_button_view);
+ mMediaButton = mDialog.findViewById(R.id.media_button);
+ mMediaTitleText = mDialog.findViewById(R.id.media_output_title);
if (mRows.isEmpty()) {
if (!AudioSystem.isSingleVolume(mContext)) {
@@ -312,7 +398,8 @@ public class VolumeDialogImpl implements VolumeDialog,
R.drawable.ic_volume_notification_mute, true, false);
}
addRow(STREAM_ALARM,
- R.drawable.ic_alarm, R.drawable.ic_volume_alarm_mute, true, false);
+ com.android.internal.R.drawable.ic_audio_alarm,
+ com.android.internal.R.drawable.ic_audio_alarm_mute, true, false);
addRow(AudioManager.STREAM_VOICE_CALL,
com.android.internal.R.drawable.ic_phone,
com.android.internal.R.drawable.ic_phone, false, false);
@@ -325,12 +412,29 @@ public class VolumeDialogImpl implements VolumeDialog,
addExistingRows();
}
+ if (Util.isVoiceCapable(mContext) && mState != null) {
+ updateNotificationRowH();
+ }
+
updateRowsH(getActiveRow());
initRingerH();
initSettingsH();
initODICaptionsH();
}
+ private final OnComputeInternalInsetsListener mInsetsListener = internalInsetsInfo -> {
+ internalInsetsInfo.touchableRegion.setEmpty();
+ internalInsetsInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ int[] mainLocation = new int[2];
+ mDialogView.getLocationInWindow(mainLocation);
+ internalInsetsInfo.touchableRegion.set(
+ mainLocation[0],
+ mainLocation[1],
+ mainLocation[0] + mDialogView.getWidth(),
+ mainLocation[1] + mDialogView.getHeight()
+ );
+ };
+
protected ViewGroup getDialogView() {
return mDialogView;
}
@@ -373,26 +477,84 @@ public class VolumeDialogImpl implements VolumeDialog,
if (D.BUG) Slog.d(TAG, "Adding row for stream " + stream);
VolumeRow row = new VolumeRow();
initRow(row, stream, iconRes, iconMuteRes, important, defaultStream);
- if(!isAudioPanelOnLeftSide()){
- mDialogRowsView.addView(row.view, 0);
- } else {
- mDialogRowsView.addView(row.view);
- }
+ mDialogRowsView.addView(row.view, 0);
mRows.add(row);
}
private void addExistingRows() {
- int N = mRows.size();
- for (int i = 0; i < N; i++) {
- final VolumeRow row = mRows.get(i);
+ for (VolumeRow row : mRows) {
initRow(row, row.stream, row.iconRes, row.iconMuteRes, row.important,
row.defaultStream);
- if(!isAudioPanelOnLeftSide()){
- mDialogRowsView.addView(row.view, 0);
+ mDialogRowsView.addView(row.view, 0);
+ updateVolumeRowH(row);
+ }
+ }
+
+ private void cleanExpandedRows() {
+ VolumeRow ring = findRow(STREAM_RING);
+ VolumeRow alarm = findRow(STREAM_ALARM);
+ VolumeRow media = findRow(STREAM_MUSIC);
+ VolumeRow notification = findRow(STREAM_NOTIFICATION);
+ VolumeRow active = getActiveRow();
+
+ float width = mWidth + mSpacer;
+ float z = mElevation;
+
+ boolean isMediaButtonVisible = mMediaButtonView.getVisibility() == VISIBLE;
+
+ if (isMediaButtonVisible && !mODIServiceComponentEnabled) {
+ animateViewOut(mMediaButtonView, false, width, z);
+ } else if (mODIServiceComponentEnabled) {
+ float widthMedia = width;
+ if (isMediaButtonVisible) {
+ animateViewOut(mMediaButtonView, false, widthMedia, z/2);
+ widthMedia += widthMedia;
+ }
+ animateViewOut(mODICaptionsView, false, widthMedia, z);
+ hideCaptionsTooltip();
+ }
+
+ boolean isNotificationEnabled = notification != null && !mState.linkedNotification;
+ if (isNotificationEnabled) {
+ final boolean isNotifVisible = active == notification;
+ animateViewOut(notification.view, isNotifVisible, 0, z);
+ z /= 2;
+ }
+ if (alarm != null) {
+ final boolean isAlarmVisible = active == alarm;
+ animateViewOut(alarm.view, isAlarmVisible, isNotificationEnabled ? width : 0, z);
+ z /= 2;
+ width = isAlarmVisible ? 0 : width;
+ }
+ if (ring != null) {
+ final boolean isRingVisible = active == ring;
+ animateViewOut(ring.view, isRingVisible, width, z);
+ z /= 2;
+ width += isRingVisible ? 0 : (mWidth + mSpacer);
+ }
+ if (media != null) {
+ Util.setVisOrGone(media.view, true);
+ animateViewOut(media.view, true, width, z);
+ }
+ if (mShowingMediaDevices) {
+ mDialogRowsView.setAlpha(1f);
+ final ColorStateList tint = Utils.getColorAttr(mContext,
+ android.R.attr.colorControlNormal);
+ mMediaButton.setImageTintList(tint);
+ mMediaTitleText.setSelected(false);
+ mShowingMediaDevices = false;
+ if (mExpanded) {
+ if (mCurrAnimator != null && mCurrAnimator.isRunning()) {
+ mCurrAnimator.cancel();
+ }
+ int x = (int) (isAudioPanelOnLeftSide() ? 0 : (3 * mWidth + 2 * mSpacer));
+ int endRadius = (int) Math.hypot(3 * mWidth + 2 * mSpacer, mHeight);
+ mCurrAnimator = circularExit(mMediaOutputScrollView, x, endRadius);
+ mCurrAnimator.start();
} else {
- mDialogRowsView.addView(row.view);
+ Util.setVisOrGone(mMediaOutputScrollView, false);
+ Util.setVisOrGone(mDialogRowsView, true);
}
- updateVolumeRowH(row);
}
}
@@ -442,7 +604,8 @@ public class VolumeDialogImpl implements VolumeDialog,
row.iconMuteRes = iconMuteRes;
row.important = important;
row.defaultStream = defaultStream;
- row.view = mDialog.getLayoutInflater().inflate(R.layout.volume_dialog_row, null);
+ row.view = mDialog.getLayoutInflater().inflate(R.layout.volume_dialog_row,
+ mDialogRowsView, false);
row.view.setId(row.stream);
row.view.setTag(row);
row.header = row.view.findViewById(R.id.volume_row_header);
@@ -458,57 +621,356 @@ public class VolumeDialogImpl implements VolumeDialog,
row.icon = row.view.findViewById(R.id.volume_row_icon);
row.icon.setImageResource(iconRes);
- if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) {
- row.icon.setOnClickListener(v -> {
- Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState);
- mController.setActiveStream(row.stream);
- if (row.stream == AudioManager.STREAM_RING) {
- final boolean hasVibrator = mController.hasVibrator();
- if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
- if (hasVibrator) {
- mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);
- } else {
- final boolean wasZero = row.ss.level == 0;
- mController.setStreamVolume(stream,
- wasZero ? row.lastAudibleLevel : 0);
- }
- } else {
- mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false);
- if (row.ss.level == 0) {
- mController.setStreamVolume(stream, 1);
- }
- }
- } else {
- final boolean vmute = row.ss.level == row.ss.levelMin;
- mController.setStreamVolume(stream,
- vmute ? row.lastAudibleLevel : row.ss.levelMin);
- }
- row.userAttempt = 0; // reset the grace period, slider updates immediately
- });
- } else {
- row.icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- }
+ row.icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
public void initSettingsH() {
- if (mSettingsView != null) {
- mSettingsView.setVisibility(
+ if (mExpandRowsView != null) {
+ mExpandRowsView.setVisibility(
mDeviceProvisionedController.isCurrentUserSetup() &&
mActivityManager.getLockTaskModeState() == LOCK_TASK_MODE_NONE ?
VISIBLE : GONE);
}
- if (mSettingsIcon != null) {
- mSettingsIcon.setOnClickListener(v -> {
+ if (mExpandRows != null) {
+ mExpandRows.setOnLongClickListener(v -> {
Events.writeEvent(Events.EVENT_SETTINGS_CLICK);
Intent intent = new Intent(Settings.Panel.ACTION_VOLUME);
dismissH(DISMISS_REASON_SETTINGS_CLICKED);
Dependency.get(MediaOutputDialogFactory.class).dismiss();
Dependency.get(ActivityStarter.class).startActivity(intent,
true /* dismissShade */);
+ return true;
+ });
+ mMediaButton.setOnClickListener(v -> {
+ int x = (int) (isLandscape() ? (isAudioPanelOnLeftSide() ? (
+ (mWidth + mSpacer) * (mHasAlertSlider ? 1 : 2) + mWidth / 2)
+ : (mHasAlertSlider ? mWidth * 1.5 + mSpacer : mWidth / 2))
+ : (1.5 * mWidth + mSpacer));
+ int endRadius = (int) Math.hypot((isLandscape() ? 2.2 : 1.1) * (1.5 * mWidth +
+ mSpacer), mHeight);
+ if (mShowingMediaDevices) {
+ mShowingMediaDevices = false;
+ if (mCurrAnimator != null && mCurrAnimator.isRunning()) {
+ mCurrAnimator.cancel();
+ }
+ VolumeRow media = findRow(STREAM_MUSIC);
+ VolumeRow notification = findRow(STREAM_NOTIFICATION);
+ if (media != null && notification != null && !mState.linkedNotification) {
+ animateViewIn(media.view, false, mWidth + mSpacer, mElevation);
+ }
+ mCurrAnimator = circularExit(mMediaOutputScrollView, x, endRadius);
+ } else {
+ mShowingMediaDevices = true;
+ if (mCurrAnimator != null && mCurrAnimator.isRunning()) {
+ mCurrAnimator.cancel();
+ }
+ VolumeRow media = findRow(STREAM_MUSIC);
+ VolumeRow notification = findRow(STREAM_NOTIFICATION);
+ if (media != null && notification != null && !mState.linkedNotification) {
+ animateViewOut(media.view, true, mWidth + mSpacer, mElevation);
+ }
+ mCurrAnimator = circularReveal(mMediaOutputScrollView, x, endRadius);
+ }
+ mCurrAnimator.start();
+ final ColorStateList tint = mShowingMediaDevices
+ ? Utils.getColorAccent(mContext)
+ : Utils.getColorAttr(mContext, android.R.attr.colorControlNormal);
+ mMediaButton.setImageTintList(tint);
+
+ provideTouchHapticH(VibrationEffect.get(VibrationEffect.EFFECT_TICK));
+ });
+ mExpandRows.setOnClickListener(v -> {
+ if (!mExpanded) {
+ VolumeRow ring = findRow(STREAM_RING);
+ VolumeRow alarm = findRow(STREAM_ALARM);
+ VolumeRow media = findRow(STREAM_MUSIC);
+ VolumeRow notification = findRow(STREAM_NOTIFICATION);
+ VolumeRow active = getActiveRow();
+
+ if (mHeight == 0 || mWidth == 0) {
+ mHeight = (float) active.view.getHeight();
+ mWidth = (float) active.view.getWidth();
+ }
+
+ float width = mWidth + mSpacer;
+ float z = mElevation;
+
+ boolean showMediaOutput = !Utils.isAudioModeOngoingCall(mContext) &&
+ mMediaOutputView.getChildCount() > 0;
+
+ if (showMediaOutput && !mODIServiceComponentEnabled) {
+ animateViewIn(mMediaButtonView, false, width, z);
+ } else if (mODIServiceComponentEnabled) {
+ float widthMedia = width;
+ if (showMediaOutput) {
+ animateViewIn(mMediaButtonView, false, widthMedia, z / 2);
+ widthMedia += widthMedia;
+ }
+ animateViewIn(mODICaptionsView, false, widthMedia, z);
+ if (mPendingOdiCaptionsTooltip && mODICaptionsView != null) {
+ showCaptionsTooltip();
+ mPendingOdiCaptionsTooltip = false;
+ }
+ }
+
+ boolean isNotificationEnabled = notification != null && !mState.linkedNotification;
+ if (isNotificationEnabled) {
+ final boolean isNotifVisible = active == notification;
+ animateViewIn(notification.view, isNotifVisible, 0, z);
+ z /= 2;
+ }
+ if (alarm != null) {
+ final boolean isAlarmVisible = active == alarm;
+ animateViewIn(alarm.view, isAlarmVisible, isNotificationEnabled ? width : 0, z);
+ z /= 2;
+ width = isAlarmVisible ? 0 : width;
+ }
+ if (ring != null) {
+ final boolean isRingVisible = active == ring;
+ animateViewIn(ring.view, isRingVisible, width, z);
+ z /= 2;
+ width += isRingVisible ? 0 : (mWidth + mSpacer);
+ }
+ if (media != null) {
+ animateViewIn(media.view, true, width, z);
+ }
+
+ provideTouchHapticH(VibrationEffect.get(VibrationEffect.EFFECT_TICK));
+ mExpanded = true;
+ } else {
+ cleanExpandedRows();
+ provideTouchHapticH(VibrationEffect.get(VibrationEffect.EFFECT_TICK));
+ mExpanded = false;
+ }
+ mExpandRows.setExpanded(mExpanded);
});
}
}
+ private Animator circularReveal(View view, int x, int endRadius) {
+ if (view == null) return null;
+
+ Animator anim = ViewAnimationUtils.createCircularReveal(view, x,
+ isLandscape() ? 0 : (int) mHeight, 0, endRadius);
+
+ anim.setDuration(DIALOG_SHOW_ANIMATION_DURATION);
+ anim.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator());
+ anim.addListener(new Animator.AnimatorListener() {
+ private boolean mIsCancelled;
+ private ViewPropertyAnimator mRowsAnimator;
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mIsCancelled = false;
+ Util.setVisOrGone(view, true);
+ mRowsAnimator = mDialogRowsView.animate()
+ .alpha(0f)
+ .setDuration(DIALOG_SHOW_ANIMATION_DURATION)
+ .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator());
+ mRowsAnimator.start();
+ }
+
+ @Override
+ public void onAnimationEnd (Animator animation) {
+ Util.setVisOrGone(mDialogRowsView, mIsCancelled);
+ mHandler.postDelayed(() -> mMediaTitleText.setSelected(true), 100);
+ }
+
+ @Override
+ public void onAnimationRepeat (Animator animation) { }
+
+ @Override
+ public void onAnimationCancel (Animator animation) {
+ mIsCancelled = true;
+ mRowsAnimator.cancel();
+ }
+ });
+ return anim;
+ }
+
+ private Animator circularExit(View view, int x, int endRadius) {
+ if (view == null) return null;
+
+ Animator anim = ViewAnimationUtils.createCircularReveal(view, x,
+ isLandscape() ? 0 : (int) mHeight, endRadius, 0);
+
+ anim.setDuration(DIALOG_SHOW_ANIMATION_DURATION);
+ anim.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator());
+ anim.addListener(new Animator.AnimatorListener() {
+ private boolean mIsCancelled;
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mIsCancelled = false;
+ Util.setVisOrGone(mDialogRowsView, true);
+ mDialogRowsView.setAlpha(1f);
+ }
+
+ @Override
+ public void onAnimationEnd (Animator animation) {
+ Util.setVisOrGone(view, mIsCancelled);
+ mMediaTitleText.setSelected(false);
+ }
+
+ @Override
+ public void onAnimationRepeat (Animator animation) { }
+
+ @Override
+ public void onAnimationCancel (Animator animation) {
+ mIsCancelled = true;
+ }
+ });
+ return anim;
+ }
+
+ private void animateViewIn(View view, boolean wasVisible, float startX, float startZ) {
+ if (view == null) return;
+
+ float startAlpha = 0f;
+ if (wasVisible) {
+ startZ = 0;
+ startAlpha = 1f;
+ } else {
+ startZ = -startZ;
+ }
+
+ view.setTranslationX(isAudioPanelOnLeftSide() ? -startX : startX);
+ view.setTranslationZ(startZ);
+ view.setAlpha(startAlpha);
+ Util.setVisOrGone(view, true);
+ view.animate()
+ .alpha(1f)
+ .translationX(0f)
+ .translationZ(0f)
+ .withLayer()
+ .setDuration(DIALOG_SHOW_ANIMATION_DURATION)
+ .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
+ .withEndAction(() -> {
+ view.setTranslationX(0f);
+ view.setTranslationZ(0f);
+ Util.setVisOrGone(view, true);
+ })
+ .start();
+ }
+
+ private void animateViewOut(View view, boolean stayVisible, float endX, float endZ) {
+ if (view == null) return;
+
+ float endAlpha = 0f;
+ if (stayVisible) {
+ endZ = 0;
+ endAlpha = 1f;
+ } else {
+ endZ = -endZ;
+ }
+
+ view.animate()
+ .alpha(endAlpha)
+ .translationX(isAudioPanelOnLeftSide() ? -endX : endX)
+ .translationZ(endZ)
+ .withLayer()
+ .setDuration(DIALOG_SHOW_ANIMATION_DURATION)
+ .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
+ .withEndAction(() -> {
+ view.setTranslationX(0);
+ view.setTranslationZ(0);
+ Util.setVisOrGone(view, stayVisible);
+ view.setAlpha(1);
+ })
+ .start();
+ }
+
+ @Override
+ public void onDeviceListUpdate(List<MediaDevice> devices) {
+ if (!mHandler.hasMessages(H.UPDATE_MEDIA_OUTPUT_VIEW)) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(H.UPDATE_MEDIA_OUTPUT_VIEW, devices), 20);
+ }
+ }
+
+ @Override
+ public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
+ // Do nothing
+ }
+
+ private void updateMediaOutputViewH(List<MediaDevice> devices) {
+ // update/add/remove existing views
+ for (MediaOutputRow row : mMediaOutputRows) {
+ if (devices.contains(row.device)) {
+ if (row.device.isConnected()) {
+ boolean active = row.device.equals(mLocalMediaManager.getCurrentConnectedDevice());
+ row.name.setText(row.device.getName());
+ Util.setVisOrGone(row.summary, !row.device.getSummary().equals(""));
+ row.summary.setText(row.device.getSummary());
+ Util.setVisOrGone(row.selected, active);
+ if (!row.addedToGroup) {
+ mMediaOutputView.addView(row.view);
+ row.addedToGroup = true;
+ }
+ } else {
+ mMediaOutputView.removeView(row.view);
+ row.addedToGroup = false;
+ }
+ // remove the device that has been handled
+ devices.remove(row.device);
+ } else {
+ mMediaOutputView.removeView(row.view);
+ row.addedToGroup = false;
+ }
+ }
+
+ try {
+ // handle the remaining devices
+ for (MediaDevice device : devices) {
+ if (device.isConnected()) {
+ // This device does not have a corresponding row yet, make one.
+ MediaOutputRow row = new MediaOutputRow();
+ boolean active = device.equals(mLocalMediaManager.getCurrentConnectedDevice());
+ row.device = device;
+ row.view = mDialog.getLayoutInflater().inflate(R.layout.volume_dialog_media_output,
+ mMediaOutputView, false);
+ row.view.setOnClickListener(v -> {
+ provideTouchHapticH(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+ ThreadUtils.postOnBackgroundThread(() -> {
+ mLocalMediaManager.connectDevice(device);
+ });
+ });
+ row.name = row.view.findViewById(R.id.media_output_text);
+ row.summary = row.view.findViewById(R.id.media_output_summary);
+ row.selected = row.view.findViewById(R.id.media_output_selected);
+ row.icon = row.view.findViewById(R.id.media_output_icon);
+ Drawable drawable = device.getIcon();
+ if (drawable == null) {
+ drawable = mContext.getDrawable(
+ com.android.internal.R.drawable.ic_bt_headphones_a2dp);
+ }
+ row.icon.setImageDrawable(drawable);
+
+ row.name.setText(device.getName());
+ Util.setVisOrGone(row.summary, !device.getSummary().equals(""));
+ row.summary.setText(device.getSummary());
+ Util.setVisOrGone(row.selected, active);
+ row.name.setSelected(true);
+ row.summary.setSelected(true);
+
+ row.addedToGroup = true;
+ mMediaOutputView.addView(row.view);
+ mMediaOutputRows.add(row);
+ }
+ }
+ } catch (Exception e) {
+ // nothing to do
+ }
+ if (mMediaOutputView.getChildCount() == 1) {
+ // This means there are no external devices connected
+ removeAllMediaOutputRows();
+ }
+ }
+
+ private void removeAllMediaOutputRows() {
+ mMediaOutputView.removeAllViews();
+ mMediaOutputRows.clear();
+ }
+
public void initRingerH() {
if (mRingerIcon != null) {
mRingerIcon.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
@@ -607,28 +1069,25 @@ public class VolumeDialogImpl implements VolumeDialog,
.alpha(0.f)
.setStartDelay(0)
.setDuration(DIALOG_HIDE_ANIMATION_DURATION)
- .withEndAction(() -> mODICaptionsTooltipView.setVisibility(INVISIBLE))
+ .withEndAction(() -> mODICaptionsTooltipView.setVisibility(GONE))
.start();
}
}
protected void tryToRemoveCaptionsTooltip() {
if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
- ViewGroup container = mDialog.findViewById(R.id.volume_dialog_container);
- container.removeView(mODICaptionsTooltipView);
+ mDialogView.removeView(mODICaptionsTooltipView);
mODICaptionsTooltipView = null;
}
}
private void updateODICaptionsH(boolean isServiceComponentEnabled, boolean fromTooltip) {
- if (mODICaptionsView != null) {
- mODICaptionsView.setVisibility(isServiceComponentEnabled ? VISIBLE : GONE);
- }
+ mODIServiceComponentEnabled = isServiceComponentEnabled;
- if (!isServiceComponentEnabled) return;
+ if (!mODIServiceComponentEnabled) return;
updateCaptionsIcon();
- if (fromTooltip) showCaptionsTooltip();
+ if (fromTooltip) mPendingOdiCaptionsTooltip = true;
}
private void updateCaptionsIcon() {
@@ -665,6 +1124,8 @@ public class VolumeDialogImpl implements VolumeDialog,
effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
break;
case RINGER_MODE_VIBRATE:
+ effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
+ break;
default:
effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
}
@@ -673,6 +1134,15 @@ public class VolumeDialogImpl implements VolumeDialog,
}
}
+ private void provideTouchHapticH(VibrationEffect effect) {
+ mController.vibrate(effect);
+ }
+
+ private void provideSliderHapticFeedbackH() {
+ VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK);
+ mController.vibrate(effect);
+ }
+
private void maybeShowToastH(int newRingerMode) {
int seenToastCount = Prefs.getInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, 0);
@@ -719,12 +1189,15 @@ public class VolumeDialogImpl implements VolumeDialog,
rescheduleTimeoutH();
if (mConfigChanged) {
+ removeAllMediaOutputRows();
initDialog(); // resets mShowing to false
mConfigurableTexts.update();
+ mShowingMediaDevices = false;
mConfigChanged = false;
}
-
initSettingsH();
+ mDialog.getWindow().getDecorView().getViewTreeObserver()
+ .addOnComputeInternalInsetsListener(mInsetsListener);
mShowing = true;
mIsAnimatingDismiss = false;
mDialog.show();
@@ -769,6 +1242,15 @@ public class VolumeDialogImpl implements VolumeDialog,
Log.d(TAG, "mDialog.dismiss() reason: " + Events.DISMISS_REASONS[reason]
+ " from: " + Debug.getCaller());
}
+ if (mLocalMediaManager != null) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ mLocalMediaManager.stopScan();
+ });
+ }
+ if (!mShowing) {
+ // This may happen when dismissing an expanded panel, don't animate again
+ return;
+ }
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
if (mIsAnimatingDismiss) {
@@ -791,9 +1273,17 @@ public class VolumeDialogImpl implements VolumeDialog,
mDialog.dismiss();
tryToRemoveCaptionsTooltip();
mIsAnimatingDismiss = false;
+ mExpanded = false;
+ cleanExpandedRows();
+ mExpandRows.setExpanded(mExpanded);
}, 50));
- if (!isLandscape()) animator.translationX((mDialogView.getWidth() / 2.0f)*(!isAudioPanelOnLeftSide() ? 1 : -1));
+ if (!isLandscape()) {
+ animator.translationX(
+ (mDialogView.getWidth() / 2.0f) * (!isAudioPanelOnLeftSide() ? 1 : -1));
+ }
animator.start();
+ mDialog.getWindow().getDecorView().getViewTreeObserver()
+ .removeOnComputeInternalInsetsListener(mInsetsListener);
checkODICaptionsTooltip(true);
mController.notifyVisible(false);
synchronized (mSafetyWarningLock) {
@@ -810,21 +1300,20 @@ public class VolumeDialogImpl implements VolumeDialog,
}
private boolean shouldBeVisibleH(VolumeRow row, VolumeRow activeRow) {
- boolean isActive = row.stream == activeRow.stream;
-
- if (isActive) {
+ if (row.stream == activeRow.stream) {
return true;
}
if (!mShowActiveStreamOnly) {
- if (row.stream == AudioSystem.STREAM_ACCESSIBILITY) {
+ if (row.stream == STREAM_ACCESSIBILITY) {
return mShowA11yStream;
}
- // if the active row is accessibility, then continue to display previous
- // active row since accessibility is displayed under it
- if (activeRow.stream == AudioSystem.STREAM_ACCESSIBILITY &&
- row.stream == mPrevActiveStream) {
+ if (row.stream == mPrevActiveStream) {
+ return true;
+ }
+
+ if (row.stream == STREAM_MUSIC) {
return true;
}
@@ -833,6 +1322,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|| activeRow.stream == STREAM_ALARM
|| activeRow.stream == STREAM_VOICE_CALL
|| activeRow.stream == STREAM_ACCESSIBILITY
+ || activeRow.stream == STREAM_NOTIFICATION
|| mDynamic.get(activeRow.stream);
}
}
@@ -845,18 +1335,21 @@ public class VolumeDialogImpl implements VolumeDialog,
if (!mShowing) {
trimObsoleteH();
}
+
// apply changes to all rows
for (final VolumeRow row : mRows) {
final boolean isActive = row == activeRow;
final boolean shouldBeVisible = shouldBeVisibleH(row, activeRow);
- Util.setVisOrGone(row.view, shouldBeVisible);
+ if(!mExpanded) {
+ Util.setVisOrGone(row.view, shouldBeVisible);
+ }
if (row.view.isShown()) {
updateVolumeRowTintH(row, isActive);
}
}
}
- protected void updateRingerH() {
+ private void updateRingerH() {
if (mRinger != null && mState != null) {
final StreamState ss = mState.states.get(AudioManager.STREAM_RING);
if (ss == null) {
@@ -979,6 +1472,12 @@ public class VolumeDialogImpl implements VolumeDialog,
mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK));
}
+ boolean ringerChanged = false;
+ if (mState != null && state != null
+ && mState.ringerModeInternal != state.ringerModeInternal) {
+ ringerChanged = true;
+ }
+
mState = state;
mDynamic.clear();
// add any new dynamic rows
@@ -1016,12 +1515,28 @@ public class VolumeDialogImpl implements VolumeDialog,
}
private void updateNotificationRowH() {
- VolumeRow notificationRow = findRow(AudioManager.STREAM_NOTIFICATION);
- if (notificationRow != null && mState.linkedNotification) {
- removeRow(notificationRow);
- } else if (notificationRow == null && !mState.linkedNotification) {
- addRow(AudioManager.STREAM_NOTIFICATION, R.drawable.ic_volume_notification,
+ VolumeRow notificationRow = findRow(STREAM_NOTIFICATION);
+ VolumeRow alarm = findRow(STREAM_ALARM);
+ if (notificationRow != null) {
+ if (mState.linkedNotification) {
+ removeRow(notificationRow);
+ } else {
+ final int alarmIndex = mDialogRowsView.indexOfChild(alarm.view);
+ final int notifIndex = mDialogRowsView.indexOfChild(notificationRow.view);
+ if (notifIndex == -1) {
+ mDialogRowsView.addView(notificationRow.view, alarmIndex);
+ } else if ((alarmIndex - 1) != notifIndex) {
+ mDialogRowsView.removeView(notificationRow.view);
+ mDialogRowsView.addView(notificationRow.view, alarmIndex - 1);
+ }
+ }
+ } else if (notificationRow == null && !mState.linkedNotification
+ && !AudioSystem.isSingleVolume(mContext)) {
+ notificationRow = new VolumeRow();
+ initRow(notificationRow, STREAM_NOTIFICATION, R.drawable.ic_volume_notification,
R.drawable.ic_volume_notification_mute, true, false);
+ mDialogRowsView.addView(notificationRow.view, mDialogRowsView.indexOfChild(alarm.view));
+ mRows.add(notificationRow);
}
}
@@ -1031,9 +1546,6 @@ public class VolumeDialogImpl implements VolumeDialog,
final StreamState ss = mState.states.get(row.stream);
if (ss == null) return;
row.ss = ss;
- if (ss.level > 0) {
- row.lastAudibleLevel = ss.level;
- }
if (ss.level == row.requestedLevel) {
row.requestedLevel = -1;
}
@@ -1042,7 +1554,7 @@ public class VolumeDialogImpl implements VolumeDialog,
final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM;
final boolean isAlarmStream = row.stream == STREAM_ALARM;
final boolean isMusicStream = row.stream == AudioManager.STREAM_MUSIC;
- final boolean isNotificationStream = row.stream == AudioManager.STREAM_NOTIFICATION;
+ final boolean isNotificationStream = row.stream == STREAM_NOTIFICATION;
final boolean isVibrate = mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
final boolean isRingVibrate = isRingStream && isVibrate;
final boolean isRingSilent = isRingStream
@@ -1065,21 +1577,12 @@ public class VolumeDialogImpl implements VolumeDialog,
if (max != row.slider.getMax()) {
row.slider.setMax(max);
}
- // update slider min
- final int min = ss.levelMin * 100;
- if (min != row.slider.getMin()) {
- row.slider.setMin(min);
- }
- // update header text
- Util.setText(row.header, getStreamLabelH(ss));
- row.slider.setContentDescription(row.header.getText());
- mConfigurableTexts.add(row.header, ss.name);
+ row.slider.setContentDescription(getStreamLabelH(ss));
// update icon
final boolean iconEnabled = (mAutomute || ss.muteSupported) && !zenMuted;
row.icon.setEnabled(iconEnabled);
- row.icon.setAlpha(iconEnabled ? 1 : 0.5f);
final int iconRes =
isRingVibrate ? R.drawable.ic_volume_ringer_vibrate
: isRingSilent || zenMuted ? row.iconMuteRes
@@ -1088,13 +1591,6 @@ public class VolumeDialogImpl implements VolumeDialog,
: R.drawable.ic_volume_media_bt
: isStreamMuted(ss) ? row.iconMuteRes : row.iconRes;
row.icon.setImageResource(iconRes);
- row.iconState =
- iconRes == R.drawable.ic_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE
- : (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes)
- ? Events.ICON_STATE_MUTE
- : (iconRes == R.drawable.ic_volume_media_bt || iconRes == row.iconRes)
- ? Events.ICON_STATE_UNMUTE
- : Events.ICON_STATE_UNKNOWN;
if (iconEnabled) {
if (isRingStream) {
if (isRingVibrate) {
@@ -1158,18 +1654,18 @@ public class VolumeDialogImpl implements VolumeDialog,
}
boolean useActiveColoring = isActive && row.slider.isEnabled();
final ColorStateList tint = useActiveColoring
- ? Utils.getColorAccent(mContext)
- : Utils.getColorAttr(mContext, android.R.attr.colorForeground);
- final int alpha = useActiveColoring
+ ? Utils.getColorAccent(mContext).withAlpha(mDarkMode ?
+ SLIDER_PROGRESS_ALPHA_ACTIVE_DARK : SLIDER_PROGRESS_ALPHA_ACTIVE)
+ : Utils.getColorAccent(mContext).withAlpha(mDarkMode ?
+ SLIDER_PROGRESS_ALPHA_DARK : SLIDER_PROGRESS_ALPHA);
+ final int alpha = useActiveColoring
? Color.alpha(tint.getDefaultColor())
: getAlphaAttr(android.R.attr.secondaryContentAlpha);
+ final ColorStateList progressTint = useActiveColoring ? null : tint;
if (tint == row.cachedTint) return;
- row.slider.setProgressTintList(tint);
+ row.slider.setProgressTintList(progressTint);
row.slider.setThumbTintList(tint);
- row.slider.setProgressBackgroundTintList(tint);
row.slider.setAlpha(((float) alpha) / 255);
- row.icon.setImageTintList(tint);
- row.icon.setImageAlpha(alpha);
row.cachedTint = tint;
}
@@ -1192,11 +1688,11 @@ public class VolumeDialogImpl implements VolumeDialog,
return; // don't update if visible and in grace period
}
if (vlevel == level) {
- if (mShowing && rowVisible) {
+ if (mShowing && rowVisible && !row.ss.muted) {
return; // don't clamp if visible
}
}
- final int newProgress = vlevel * 100;
+ final int newProgress = row.ss.muted ? 0 : vlevel * 100;
if (progress != newProgress) {
if (mShowing && rowVisible) {
// animate!
@@ -1223,6 +1719,10 @@ public class VolumeDialogImpl implements VolumeDialog,
row.slider.setProgress(newProgress, true);
}
}
+
+ // update header text
+ Util.setText(row.header, Utils.formatPercentage((enable && !row.ss.muted)
+ ? vlevel : 0, row.ss.levelMax));
}
private void recheckH(VolumeRow row) {
@@ -1381,6 +1881,12 @@ public class VolumeDialogImpl implements VolumeDialog,
private static final int SET_STREAM_IMPORTANT = 5;
private static final int RESCHEDULE_TIMEOUT = 6;
private static final int STATE_CHANGED = 7;
+ private static final int PERFORM_HAPTIC_FEEDBACK = 8;
+ private static final int UPDATE_MEDIA_OUTPUT_VIEW = 9;
+
+ public H(Looper l) {
+ super(l);
+ }
public H() {
super(Looper.getMainLooper());
@@ -1396,6 +1902,8 @@ public class VolumeDialogImpl implements VolumeDialog,
case SET_STREAM_IMPORTANT: setStreamImportantH(msg.arg1, msg.arg2 != 0); break;
case RESCHEDULE_TIMEOUT: rescheduleTimeoutH(); break;
case STATE_CHANGED: onStateChangedH(mState); break;
+ case PERFORM_HAPTIC_FEEDBACK: provideSliderHapticFeedbackH(); break;
+ case UPDATE_MEDIA_OUTPUT_VIEW: updateMediaOutputViewH((List<MediaDevice>) msg.obj); break;
}
}
}
@@ -1426,10 +1934,8 @@ public class VolumeDialogImpl implements VolumeDialog,
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mShowing) {
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- dismissH(Events.DISMISS_REASON_TOUCH_OUTSIDE);
- return true;
- }
+ dismissH(Events.DISMISS_REASON_TOUCH_OUTSIDE);
+ return true;
}
return false;
}
@@ -1447,6 +1953,12 @@ public class VolumeDialogImpl implements VolumeDialog,
if (mRow.ss == null) return;
if (D.BUG) Log.d(TAG, AudioSystem.streamToString(mRow.stream)
+ " onProgressChanged " + progress + " fromUser=" + fromUser);
+ if ((mRow.stream == STREAM_RING || mRow.stream == STREAM_NOTIFICATION) && mHasAlertSlider) {
+ if (mRow.ss.muted) {
+ seekBar.setProgress(0);
+ return;
+ }
+ }
if (!fromUser) return;
if (mRow.ss.levelMin > 0) {
final int minProgress = mRow.ss.levelMin * 100;
@@ -1456,6 +1968,17 @@ public class VolumeDialogImpl implements VolumeDialog,
}
}
final int userLevel = getImpliedLevel(seekBar, progress);
+
+ if ((mRow.stream == STREAM_RING || mRow.stream == STREAM_NOTIFICATION) && mHasAlertSlider) {
+ if (mRow.ss.level > mRow.ss.levelMin && userLevel == 0) {
+ seekBar.setProgress((mRow.ss.levelMin + 1) * 100);
+ Util.setText(mRow.header,
+ Utils.formatPercentage(mRow.ss.levelMin + 1, mRow.ss.levelMax));
+ return;
+ }
+ }
+
+ Util.setText(mRow.header, Utils.formatPercentage(userLevel, mRow.ss.levelMax));
if (mRow.ss.level != userLevel || mRow.ss.muted && userLevel > 0) {
mRow.userAttempt = SystemClock.uptimeMillis();
if (mRow.requestedLevel != userLevel) {
@@ -1464,6 +1987,10 @@ public class VolumeDialogImpl implements VolumeDialog,
mRow.requestedLevel = userLevel;
Events.writeEvent(Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
userLevel);
+
+ if (mVibrateOnSlider && !mHandler.hasMessages(H.PERFORM_HAPTIC_FEEDBACK)) {
+ mHandler.sendEmptyMessageDelayed(H.PERFORM_HAPTIC_FEEDBACK, 20);
+ }
}
}
}
@@ -1516,7 +2043,7 @@ public class VolumeDialogImpl implements VolumeDialog,
private static class VolumeRow {
private View view;
private TextView header;
- private ImageButton icon;
+ private ImageView icon;
private SeekBar slider;
private int stream;
private StreamState ss;
@@ -1528,10 +2055,18 @@ public class VolumeDialogImpl implements VolumeDialog,
private boolean important;
private boolean defaultStream;
private ColorStateList cachedTint;
- private int iconState; // from Events
private ObjectAnimator anim; // slider progress animation for non-touch-related updates
private int animTargetProgress;
- private int lastAudibleLevel = 1;
private FrameLayout dndIcon;
}
+
+ private static class MediaOutputRow {
+ private View view;
+ private TextView name;
+ private TextView summary;
+ private ImageView icon;
+ private ImageView selected;
+ private MediaDevice device;
+ private boolean addedToGroup;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
index 1de55856f942..44a76f536a7e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
@@ -17,6 +17,8 @@
package com.android.systemui.volume;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
@@ -60,9 +62,20 @@ public class VolumeToolTipView extends LinearLayout {
private void drawArrow() {
View arrowView = findViewById(R.id.arrow);
+
+ boolean isLandscape = getContext().getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_LANDSCAPE;
ViewGroup.LayoutParams arrowLp = arrowView.getLayoutParams();
- ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.createHorizontal(
- arrowLp.width, arrowLp.height, false));
+ int arrowHeight = arrowLp.height;
+ int arrowWidth = arrowLp.width;
+
+ ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(arrowWidth, arrowHeight, true));
+ if (isLandscape) {
+ boolean isPointingLeft = getContext().getResources().getBoolean(
+ R.bool.config_audioPanelOnLeftSide);
+ arrowView.setRotation(isPointingLeft ? 270 : 90);
+ }
+
Paint arrowPaint = arrowDrawable.getPaint();
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
@@ -71,6 +84,5 @@ public class VolumeToolTipView extends LinearLayout {
arrowPaint.setPathEffect(new CornerPathEffect(
getResources().getDimension(R.dimen.volume_tool_tip_arrow_corner_radius)));
arrowView.setBackground(arrowDrawable);
-
}
}