Volume dialog: Add zen mode icons and notification access.
- Add icon above text to all three zen mode states, update text style. - Remove zentoast. - Update shared borderless rect background, masks now support shapes. - Update size of volume stream icons. - Ensure all volume icons are expressions of white. - Make volume icons testable via new demo mode command. - Add a divider + secondary icon to access the notification slider. - Animate the transition when accessing notification slider. Bug: 18206097 Bug: 16303068 Bug: 18102850 Change-Id: I5eb6f820dc317e89be272cc78f6c80ed969ad5e9
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2014 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.
|
||||
-->
|
||||
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||
android:duration="@integer/zen_toast_animation_duration" />
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2014 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.
|
||||
-->
|
||||
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/accelerate_quad"
|
||||
android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||
android:duration="@integer/zen_toast_animation_duration" />
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:color="@android:color/white"/>
|
||||
<item android:color="@color/segmented_button_text_inactive"/>
|
||||
<item android:state_selected="true" android:color="@color/segmented_button_selected"/>
|
||||
<item android:color="@color/segmented_button_unselected"/>
|
||||
|
||||
</selector>
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
<item android:id="@android:id/mask">
|
||||
<shape>
|
||||
<corners android:radius="@dimen/borderless_button_radius" />
|
||||
<solid android:color="@android:color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32.0dp"
|
||||
android:height="32.0dp"
|
||||
android:width="28.0dp"
|
||||
android:height="28.0dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32.0dp"
|
||||
android:height="32.0dp"
|
||||
android:width="28.0dp"
|
||||
android:height="28.0dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
|
||||
25
packages/SystemUI/res/drawable/ic_audio_bt.xml
Normal file
25
packages/SystemUI/res/drawable/ic_audio_bt.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
|
||||
</vector>
|
||||
25
packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
Normal file
25
packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
|
||||
</vector>
|
||||
23
packages/SystemUI/res/drawable/ic_audio_phone.xml
Normal file
23
packages/SystemUI/res/drawable/ic_audio_phone.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2014, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@*android:drawable/ic_audio_phone_am_alpha"
|
||||
android:autoMirrored="true"
|
||||
android:tint="#ffffffff" />
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32.0dp"
|
||||
android:height="32.0dp"
|
||||
android:width="28.0dp"
|
||||
android:height="28.0dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32.0dp"
|
||||
android:height="32.0dp"
|
||||
android:width="28.0dp"
|
||||
android:height="28.0dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
|
||||
24
packages/SystemUI/res/drawable/ic_zen_all.xml
Normal file
24
packages/SystemUI/res/drawable/ic_zen_all.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M6.6,3.6L5.2,2.2C2.8,4.0 1.2,6.8 1.0,10.0l2.0,0.0C3.2,7.3 4.5,5.0 6.6,3.6zM20.0,10.0l2.0,0.0c-0.2,-3.2 -1.7,-6.0 -4.1,-7.8l-1.4,1.4C18.5,5.0 19.8,7.3 20.0,10.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.0,10.5zM11.5,22.0c0.1,0.0 0.3,0.0 0.4,0.0c0.7,-0.1 1.2,-0.6 1.4,-1.2c0.1,-0.2 0.2,-0.5 0.2,-0.8l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0z"/>
|
||||
</vector>
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/system_primary_color" />
|
||||
<corners android:radius="@dimen/notification_material_rounded_rect_radius" />
|
||||
</shape>
|
||||
@@ -19,8 +19,10 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/segmented_button_spacing"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_horizontal|top"
|
||||
android:textColor="@color/segmented_button_text_selector"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:textAppearance="@style/TextAppearance.QS.SegmentedButton"
|
||||
android:minHeight="36dp"
|
||||
android:padding="4dp" />
|
||||
android:minHeight="64dp"
|
||||
android:paddingTop="11dp"
|
||||
android:drawablePadding="6dp" />
|
||||
|
||||
@@ -55,4 +55,20 @@
|
||||
android:paddingTop="0dp" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:background="@color/volume_panel_divider" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/secondary_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:scaleType="center"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:contentDescription="@null" />
|
||||
</LinearLayout>
|
||||
@@ -25,7 +25,7 @@
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="12dp"
|
||||
android:minHeight="8dp"
|
||||
android:elevation="4dp"
|
||||
android:background="@drawable/qs_background_secondary" >
|
||||
|
||||
@@ -33,9 +33,8 @@
|
||||
android:id="@+id/zen_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/qs_panel_padding"
|
||||
android:layout_marginRight="@dimen/qs_panel_padding"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clipChildren="false" />
|
||||
</FrameLayout>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/zen_toast_background"
|
||||
android:translationZ="@dimen/volume_panel_z"
|
||||
android:padding="18dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:scaleType="center" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/TextAppearance.QS.ZenToast" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -101,8 +101,6 @@
|
||||
<!-- The color of the circle around the primary user in the user switcher -->
|
||||
<color name="current_user_border_color">@color/system_accent_color</color>
|
||||
|
||||
<color name="segmented_button_text_inactive">#99afbdc4</color><!-- 60% -->
|
||||
|
||||
<!-- The "inside" of a notification, reached via longpress -->
|
||||
<color name="notification_guts_bg_color">@color/system_secondary_color</color>
|
||||
<color name="notification_guts_title_color">#FFFFFFFF</color>
|
||||
@@ -124,9 +122,11 @@
|
||||
<!-- Shadow color for the furthest pixels around the fake shadow for recents. -->
|
||||
<color name="fake_shadow_end_color">#03000000</color>
|
||||
|
||||
<!-- 25% deep teal 200 -->
|
||||
<color name="screen_pinning_nav_icon_highlight_outer">#4080cbc4</color>
|
||||
<!-- deep teal 500 -->
|
||||
<color name="screen_pinning_request_bg">#ff009688</color>
|
||||
<color name="screen_pinning_nav_icon_highlight_outer">#4080cbc4</color><!-- 25% deep teal 200 -->
|
||||
<color name="screen_pinning_request_bg">#ff009688</color><!-- deep teal 500 -->
|
||||
<color name="screen_pinning_request_window_bg">#80000000</color>
|
||||
|
||||
<color name="segmented_button_selected">#FFFFFFFF</color>
|
||||
<color name="segmented_button_unselected">#B3B0BEC5</color><!-- 70% blue grey 200 -->
|
||||
<color name="volume_panel_divider">#1FFFFFFF</color><!-- 12% white -->
|
||||
</resources>
|
||||
|
||||
@@ -250,12 +250,6 @@
|
||||
<!-- Number of times to show the strong alarm warning text in the volume dialog -->
|
||||
<integer name="zen_mode_alarm_warning_threshold">5</integer>
|
||||
|
||||
<!-- Zen toast fade in/out duration -->
|
||||
<integer name="zen_toast_animation_duration">500</integer>
|
||||
|
||||
<!-- Zen toast visibility duration -->
|
||||
<integer name="zen_toast_visible_duration">500</integer>
|
||||
|
||||
<!-- Enable the default volume dialog -->
|
||||
<bool name="enable_volume_ui">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -191,17 +191,14 @@
|
||||
<dimen name="qs_data_usage_text_size">14sp</dimen>
|
||||
<dimen name="qs_data_usage_usage_text_size">36sp</dimen>
|
||||
|
||||
<dimen name="segmented_button_spacing">4dp</dimen>
|
||||
<dimen name="segmented_button_radius">2dp</dimen>
|
||||
<dimen name="segmented_button_spacing">8dp</dimen>
|
||||
<dimen name="borderless_button_radius">2dp</dimen>
|
||||
|
||||
<!-- How far the expanded QS panel peeks from the header in collapsed state. -->
|
||||
<dimen name="qs_peek_height">8dp</dimen>
|
||||
|
||||
<dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
|
||||
|
||||
<!-- Explicit width of the zen toast window -->
|
||||
<dimen name="zen_toast_width">224dp</dimen>
|
||||
|
||||
<!-- used by DessertCase -->
|
||||
<dimen name="dessert_case_cell_size">192dp</dimen>
|
||||
|
||||
|
||||
@@ -167,14 +167,8 @@
|
||||
<item name="android:textColor">@color/qs_subhead</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.ZenToast">
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.SegmentedButton">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.DataUsage">
|
||||
@@ -266,9 +260,4 @@
|
||||
<style name="UserDetailView">
|
||||
<item name="numColumns">3</item>
|
||||
</style>
|
||||
|
||||
<style name="ZenToastAnimations">
|
||||
<item name="android:windowEnterAnimation">@anim/zen_toast_enter</item>
|
||||
<item name="android:windowExitAnimation">@anim/zen_toast_exit</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -32,4 +32,5 @@ public interface DemoMode {
|
||||
public static final String COMMAND_BARS = "bars";
|
||||
public static final String COMMAND_STATUS = "status";
|
||||
public static final String COMMAND_NOTIFICATIONS = "notifications";
|
||||
public static final String COMMAND_VOLUME = "volume";
|
||||
}
|
||||
|
||||
@@ -3444,6 +3444,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
dispatchDemoCommand(COMMAND_ENTER, new Bundle());
|
||||
}
|
||||
boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
|
||||
if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
|
||||
mVolumeComponent.dispatchDemoCommand(command, args);
|
||||
}
|
||||
if (modeChange || command.equals(COMMAND_CLOCK)) {
|
||||
dispatchDemoCommandToView(command, args, R.id.clock);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -30,8 +29,6 @@ import com.android.systemui.R;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SegmentedButtons extends LinearLayout {
|
||||
private static final Typeface MEDIUM = Typeface.create("sans-serif-medium", Typeface.NORMAL);
|
||||
private static final Typeface BOLD = Typeface.create("sans-serif", Typeface.BOLD);
|
||||
private static final int LABEL_RES_KEY = R.id.label;
|
||||
|
||||
private final Context mContext;
|
||||
@@ -63,15 +60,17 @@ public class SegmentedButtons extends LinearLayout {
|
||||
final Object tag = c.getTag();
|
||||
final boolean selected = Objects.equals(mSelectedValue, tag);
|
||||
c.setSelected(selected);
|
||||
c.setTypeface(selected ? BOLD : MEDIUM);
|
||||
c.getCompoundDrawables()[1].setTint(mContext.getResources().getColor(selected
|
||||
? R.color.segmented_button_selected : R.color.segmented_button_unselected));
|
||||
}
|
||||
fireOnSelected();
|
||||
}
|
||||
|
||||
public void addButton(int labelResId, Object value) {
|
||||
public void addButton(int labelResId, int iconResId, Object value) {
|
||||
final Button b = (Button) mInflater.inflate(R.layout.segmented_button, this, false);
|
||||
b.setTag(LABEL_RES_KEY, labelResId);
|
||||
b.setText(labelResId);
|
||||
b.setCompoundDrawablesWithIntrinsicBounds(0, iconResId, 0, 0);
|
||||
final LayoutParams lp = (LayoutParams) b.getLayoutParams();
|
||||
if (getChildCount() == 0) {
|
||||
lp.leftMargin = lp.rightMargin = 0; // first button has no margin
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import com.android.systemui.DemoMode;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
|
||||
public interface VolumeComponent {
|
||||
public interface VolumeComponent extends DemoMode {
|
||||
ZenModeController getZenController();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -42,6 +45,8 @@ import android.media.VolumeProvider;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaController.PlaybackInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -59,12 +64,15 @@ import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.systemui.DemoMode;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
|
||||
@@ -76,7 +84,7 @@ import java.io.PrintWriter;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class VolumePanel extends Handler {
|
||||
public class VolumePanel extends Handler implements DemoMode {
|
||||
private static final String TAG = "VolumePanel";
|
||||
private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
@@ -129,6 +137,8 @@ public class VolumePanel extends Handler {
|
||||
|
||||
private static final int IC_AUDIO_VOL = com.android.systemui.R.drawable.ic_audio_vol;
|
||||
private static final int IC_AUDIO_VOL_MUTE = com.android.systemui.R.drawable.ic_audio_vol_mute;
|
||||
private static final int IC_AUDIO_BT = com.android.systemui.R.drawable.ic_audio_bt;
|
||||
private static final int IC_AUDIO_BT_MUTE = com.android.systemui.R.drawable.ic_audio_bt_mute;
|
||||
|
||||
private final String mTag;
|
||||
protected final Context mContext;
|
||||
@@ -142,6 +152,7 @@ public class VolumePanel extends Handler {
|
||||
private float mDisabledAlpha;
|
||||
private int mLastRingerMode = AudioManager.RINGER_MODE_NORMAL;
|
||||
private int mLastRingerProgress = 0;
|
||||
private int mDemoIcon;
|
||||
|
||||
// True if we want to play tones on the system stream when the master stream is specified.
|
||||
private final boolean mPlayMasterStreamTones;
|
||||
@@ -166,12 +177,13 @@ public class VolumePanel extends Handler {
|
||||
/** All the slider controls mapped by stream type */
|
||||
private SparseArray<StreamControl> mStreamControls;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final SecondaryIconTransition mSecondaryIconTransition;
|
||||
|
||||
private enum StreamResources {
|
||||
BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
|
||||
R.string.volume_icon_description_bluetooth,
|
||||
R.drawable.ic_audio_bt,
|
||||
R.drawable.ic_audio_bt,
|
||||
IC_AUDIO_BT,
|
||||
IC_AUDIO_BT_MUTE,
|
||||
false),
|
||||
RingerStream(AudioManager.STREAM_RING,
|
||||
R.string.volume_icon_description_ringer,
|
||||
@@ -180,8 +192,8 @@ public class VolumePanel extends Handler {
|
||||
false),
|
||||
VoiceStream(AudioManager.STREAM_VOICE_CALL,
|
||||
R.string.volume_icon_description_incall,
|
||||
R.drawable.ic_audio_phone,
|
||||
R.drawable.ic_audio_phone,
|
||||
com.android.systemui.R.drawable.ic_audio_phone,
|
||||
com.android.systemui.R.drawable.ic_audio_phone,
|
||||
false),
|
||||
AlarmStream(AudioManager.STREAM_ALARM,
|
||||
R.string.volume_alarm,
|
||||
@@ -246,6 +258,8 @@ public class VolumePanel extends Handler {
|
||||
ImageView icon;
|
||||
SeekBar seekbarView;
|
||||
TextView suppressorView;
|
||||
View divider;
|
||||
ImageView secondaryIcon;
|
||||
int iconRes;
|
||||
int iconMuteRes;
|
||||
int iconSuppressedRes;
|
||||
@@ -339,6 +353,7 @@ public class VolumePanel extends Handler {
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
|
||||
Context.ACCESSIBILITY_SERVICE);
|
||||
mSecondaryIconTransition = new SecondaryIconTransition();
|
||||
|
||||
// For now, only show master volume if master volume is supported
|
||||
final Resources res = context.getResources();
|
||||
@@ -381,6 +396,8 @@ public class VolumePanel extends Handler {
|
||||
mActiveStreamType = -1;
|
||||
mAudioManager.forceVolumeControlStream(mActiveStreamType);
|
||||
setZenPanelVisible(false);
|
||||
mDemoIcon = 0;
|
||||
mSecondaryIconTransition.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -604,10 +621,12 @@ public class VolumePanel extends Handler {
|
||||
|
||||
mStreamControls = new SparseArray<StreamControl>(STREAMS.length);
|
||||
|
||||
final StreamResources notificationStream = StreamResources.NotificationStream;
|
||||
for (int i = 0; i < STREAMS.length; i++) {
|
||||
StreamResources streamRes = STREAMS[i];
|
||||
|
||||
final int streamType = streamRes.streamType;
|
||||
final boolean isNotification = isNotificationOrRing(streamType);
|
||||
|
||||
final StreamControl sc = new StreamControl();
|
||||
sc.streamType = streamType;
|
||||
@@ -620,8 +639,8 @@ public class VolumePanel extends Handler {
|
||||
sc.iconRes = streamRes.iconRes;
|
||||
sc.iconMuteRes = streamRes.iconMuteRes;
|
||||
sc.icon.setImageResource(sc.iconRes);
|
||||
sc.icon.setClickable(isNotificationOrRing(streamType));
|
||||
if (sc.icon.isClickable()) {
|
||||
sc.icon.setClickable(isNotification);
|
||||
if (isNotification) {
|
||||
sc.icon.setSoundEffectsEnabled(false);
|
||||
sc.icon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
@@ -636,6 +655,23 @@ public class VolumePanel extends Handler {
|
||||
sc.suppressorView =
|
||||
(TextView) sc.group.findViewById(com.android.systemui.R.id.suppressor);
|
||||
sc.suppressorView.setVisibility(View.GONE);
|
||||
final boolean showSecondary = !isNotification && notificationStream.show;
|
||||
sc.divider = sc.group.findViewById(com.android.systemui.R.id.divider);
|
||||
sc.secondaryIcon = (ImageView) sc.group
|
||||
.findViewById(com.android.systemui.R.id.secondary_icon);
|
||||
sc.secondaryIcon.setImageResource(com.android.systemui.R.drawable.ic_ringer_audible);
|
||||
sc.secondaryIcon.setContentDescription(res.getString(notificationStream.descRes));
|
||||
sc.secondaryIcon.setClickable(showSecondary);
|
||||
sc.divider.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
|
||||
sc.secondaryIcon.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
|
||||
if (showSecondary) {
|
||||
sc.secondaryIcon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mSecondaryIconTransition.start(sc);
|
||||
}
|
||||
});
|
||||
}
|
||||
final int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
|
||||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
|
||||
sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne);
|
||||
@@ -696,7 +732,7 @@ public class VolumePanel extends Handler {
|
||||
}
|
||||
muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
|
||||
}
|
||||
sc.icon.setImageResource(muted ? sc.iconMuteRes : sc.iconRes);
|
||||
sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon : muted ? sc.iconMuteRes : sc.iconRes);
|
||||
}
|
||||
|
||||
private void updateSliderSupressor(StreamControl sc) {
|
||||
@@ -800,7 +836,8 @@ public class VolumePanel extends Handler {
|
||||
}
|
||||
|
||||
private void updateTimeoutDelay() {
|
||||
mTimeoutDelay = sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
|
||||
mTimeoutDelay = mDemoIcon != 0 ? TIMEOUT_DELAY_EXPANDED
|
||||
: sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
|
||||
: mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
|
||||
: mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
|
||||
: isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
|
||||
@@ -995,7 +1032,7 @@ public class VolumePanel extends Handler {
|
||||
(AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
|
||||
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
|
||||
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
|
||||
setMusicIcon(R.drawable.ic_audio_bt, R.drawable.ic_audio_bt_mute);
|
||||
setMusicIcon(IC_AUDIO_BT, IC_AUDIO_BT_MUTE);
|
||||
} else {
|
||||
setMusicIcon(IC_AUDIO_VOL, IC_AUDIO_VOL_MUTE);
|
||||
}
|
||||
@@ -1075,6 +1112,12 @@ public class VolumePanel extends Handler {
|
||||
updateSliderProgress(sc, index);
|
||||
updateSliderEnabled(sc, isMuted(streamType),
|
||||
(flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
|
||||
// check for secondary-icon transition completion
|
||||
if (isNotificationOrRing(streamType) && mSecondaryIconTransition.isRunning()) {
|
||||
mSecondaryIconTransition.cancel(); // safe to reset
|
||||
sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
|
||||
mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isShowing()) {
|
||||
@@ -1406,6 +1449,22 @@ public class VolumePanel extends Handler {
|
||||
return mZenController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDemoCommand(String command, Bundle args) {
|
||||
if (!COMMAND_VOLUME.equals(command)) return;
|
||||
String icon = args.getString("icon");
|
||||
final String iconMute = args.getString("iconmute");
|
||||
final boolean mute = iconMute != null;
|
||||
icon = mute ? iconMute : icon;
|
||||
icon = icon.endsWith("Stream") ? icon : (icon + "Stream");
|
||||
final StreamResources sr = StreamResources.valueOf(icon);
|
||||
mDemoIcon = mute ? sr.iconMuteRes : sr.iconRes;
|
||||
final int forcedStreamType = StreamResources.MediaStream.streamType;
|
||||
mAudioManager.forceVolumeControlStream(forcedStreamType);
|
||||
mAudioManager.adjustStreamVolume(forcedStreamType, AudioManager.ADJUST_SAME,
|
||||
AudioManager.FLAG_SHOW_UI);
|
||||
}
|
||||
|
||||
private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
@@ -1445,6 +1504,80 @@ public class VolumePanel extends Handler {
|
||||
}
|
||||
};
|
||||
|
||||
private final class SecondaryIconTransition extends AnimatorListenerAdapter
|
||||
implements Runnable {
|
||||
private static final int ANIMATION_TIME = 400;
|
||||
private static final int WAIT_FOR_SWITCH_TIME = 1000;
|
||||
|
||||
private final int mAnimationTime = (int)(ANIMATION_TIME * ValueAnimator.getDurationScale());
|
||||
private final int mFadeOutTime = mAnimationTime / 2;
|
||||
private final int mDelayTime = mAnimationTime / 3;
|
||||
|
||||
private final Interpolator mIconInterpolator =
|
||||
AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
|
||||
|
||||
private StreamControl mTarget;
|
||||
|
||||
public void start(StreamControl sc) {
|
||||
if (sc == null) throw new IllegalArgumentException();
|
||||
if (mTarget != null) {
|
||||
cancel();
|
||||
}
|
||||
mTarget = sc;
|
||||
mTimeoutDelay = mAnimationTime + WAIT_FOR_SWITCH_TIME;
|
||||
resetTimeout();
|
||||
mTarget.secondaryIcon.setClickable(false);
|
||||
final int N = mTarget.group.getChildCount();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final View child = mTarget.group.getChildAt(i);
|
||||
if (child != mTarget.secondaryIcon) {
|
||||
child.animate().alpha(0).setDuration(mFadeOutTime).start();
|
||||
}
|
||||
}
|
||||
mTarget.secondaryIcon.animate()
|
||||
.translationXBy(mTarget.icon.getX() - mTarget.secondaryIcon.getX())
|
||||
.setInterpolator(mIconInterpolator)
|
||||
.setStartDelay(mDelayTime)
|
||||
.setDuration(mAnimationTime - mDelayTime)
|
||||
.setListener(this)
|
||||
.start();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return mTarget != null;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (mTarget == null) return;
|
||||
mTarget.secondaryIcon.setClickable(true);
|
||||
final int N = mTarget.group.getChildCount();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final View child = mTarget.group.getChildAt(i);
|
||||
if (child != mTarget.secondaryIcon) {
|
||||
child.animate().cancel();
|
||||
child.setAlpha(1);
|
||||
}
|
||||
}
|
||||
mTarget.secondaryIcon.animate().cancel();
|
||||
mTarget.secondaryIcon.setTranslationX(0);
|
||||
mTarget = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mTarget == null) return;
|
||||
AsyncTask.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mTarget == null) return;
|
||||
mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
|
||||
mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
|
||||
AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onZenSettings();
|
||||
void onInteraction();
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.media.session.ISessionController;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
@@ -184,6 +185,11 @@ public class VolumeUI extends SystemUI {
|
||||
public ZenModeController getZenController() {
|
||||
return mPanel.getZenController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDemoCommand(String command, Bundle args) {
|
||||
mPanel.dispatchDemoCommand(command, args);
|
||||
}
|
||||
}
|
||||
|
||||
private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
|
||||
|
||||
@@ -80,7 +80,6 @@ public class ZenModePanel extends LinearLayout {
|
||||
private final Interpolator mFastOutSlowInInterpolator;
|
||||
private final int mSubheadWarningColor;
|
||||
private final int mSubheadColor;
|
||||
private final ZenToast mZenToast;
|
||||
|
||||
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
|
||||
|
||||
@@ -115,7 +114,6 @@ public class ZenModePanel extends LinearLayout {
|
||||
final Resources res = mContext.getResources();
|
||||
mSubheadWarningColor = res.getColor(R.color.system_warning_color);
|
||||
mSubheadColor = res.getColor(R.color.qs_subhead);
|
||||
mZenToast = new ZenToast(mContext);
|
||||
if (DEBUG) Log.d(mTag, "new ZenModePanel");
|
||||
}
|
||||
|
||||
@@ -124,10 +122,12 @@ public class ZenModePanel extends LinearLayout {
|
||||
super.onFinishInflate();
|
||||
|
||||
mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
|
||||
mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS);
|
||||
mZenButtons.addButton(R.string.interruption_level_priority,
|
||||
mZenButtons.addButton(R.string.interruption_level_none, R.drawable.ic_zen_none,
|
||||
Global.ZEN_MODE_NO_INTERRUPTIONS);
|
||||
mZenButtons.addButton(R.string.interruption_level_priority, R.drawable.ic_zen_important,
|
||||
Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||
mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
|
||||
mZenButtons.addButton(R.string.interruption_level_all, R.drawable.ic_zen_all,
|
||||
Global.ZEN_MODE_OFF);
|
||||
mZenButtons.setCallback(mZenButtonsCallback);
|
||||
|
||||
mZenSubhead = findViewById(R.id.zen_subhead);
|
||||
@@ -160,7 +160,6 @@ public class ZenModePanel extends LinearLayout {
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (DEBUG) Log.d(mTag, "onAttachedToWindow");
|
||||
mZenToast.hide();
|
||||
mAttachedZen = getSelectedZen(-1);
|
||||
mSessionZen = mAttachedZen;
|
||||
mSessionExitCondition = copy(mExitCondition);
|
||||
@@ -193,10 +192,6 @@ public class ZenModePanel extends LinearLayout {
|
||||
if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
|
||||
mPrefs.trackNoneSelected();
|
||||
}
|
||||
if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS
|
||||
|| selectedZen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
|
||||
mZenToast.show(selectedZen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnAttachStateChangeListener;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
public class ZenToast {
|
||||
private static final String ACTION_SHOW = ZenToast.class.getName() + ".SHOW";
|
||||
private static final String ACTION_HIDE = ZenToast.class.getName() + ".HIDE";
|
||||
private static final String EXTRA_ZEN = "zen";
|
||||
private static final String EXTRA_TEXT = "text";
|
||||
|
||||
private static final int MSG_SHOW = 1;
|
||||
private static final int MSG_HIDE = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final WindowManager mWindowManager;
|
||||
|
||||
private View mZenToast;
|
||||
|
||||
public ZenToast(Context context) {
|
||||
mContext = context;
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_SHOW);
|
||||
filter.addAction(ACTION_HIDE);
|
||||
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
|
||||
}
|
||||
|
||||
public void show(int zen) {
|
||||
mHandler.removeMessages(MSG_HIDE);
|
||||
mHandler.removeMessages(MSG_SHOW);
|
||||
mHandler.obtainMessage(MSG_SHOW, zen, 0).sendToTarget();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
mHandler.removeMessages(MSG_HIDE);
|
||||
mHandler.removeMessages(MSG_SHOW);
|
||||
mHandler.obtainMessage(MSG_HIDE).sendToTarget();
|
||||
}
|
||||
|
||||
private void handleShow(int zen, String overrideText) {
|
||||
handleHide();
|
||||
|
||||
String text;
|
||||
final int iconRes;
|
||||
switch (zen) {
|
||||
case ZEN_MODE_NO_INTERRUPTIONS:
|
||||
text = mContext.getString(R.string.zen_no_interruptions);
|
||||
iconRes = R.drawable.ic_zen_none;
|
||||
break;
|
||||
case ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
text = mContext.getString(R.string.zen_important_interruptions);
|
||||
iconRes = R.drawable.ic_zen_important;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (overrideText != null) {
|
||||
text = overrideText;
|
||||
}
|
||||
final Resources res = mContext.getResources();
|
||||
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
params.width = res.getDimensionPixelSize(R.dimen.zen_toast_width);
|
||||
params.format = PixelFormat.TRANSLUCENT;
|
||||
params.windowAnimations = R.style.ZenToastAnimations;
|
||||
params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
|
||||
params.setTitle(getClass().getSimpleName());
|
||||
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||
params.gravity = Gravity.CENTER;
|
||||
params.packageName = mContext.getPackageName();
|
||||
mZenToast = LayoutInflater.from(mContext).inflate(R.layout.zen_toast, null);
|
||||
final TextView message = (TextView) mZenToast.findViewById(android.R.id.message);
|
||||
message.setText(text);
|
||||
final ImageView icon = (ImageView) mZenToast.findViewById(android.R.id.icon);
|
||||
icon.setImageResource(iconRes);
|
||||
mZenToast.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
mZenToast.announceForAccessibility(message.getText());
|
||||
}
|
||||
});
|
||||
mWindowManager.addView(mZenToast, params);
|
||||
final int animDuration = res.getInteger(R.integer.zen_toast_animation_duration);
|
||||
final int visibleDuration = res.getInteger(R.integer.zen_toast_visible_duration);
|
||||
mHandler.sendEmptyMessageDelayed(MSG_HIDE, animDuration + visibleDuration);
|
||||
}
|
||||
|
||||
private void handleHide() {
|
||||
if (mZenToast != null) {
|
||||
mWindowManager.removeView(mZenToast);
|
||||
mZenToast = null;
|
||||
}
|
||||
}
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_SHOW:
|
||||
handleShow(msg.arg1, null);
|
||||
break;
|
||||
case MSG_HIDE:
|
||||
handleHide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_SHOW.equals(intent.getAction())) {
|
||||
final int zen = intent.getIntExtra(EXTRA_ZEN, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||
final String text = intent.getStringExtra(EXTRA_TEXT);
|
||||
handleShow(zen, text);
|
||||
} else if (ACTION_HIDE.equals(intent.getAction())) {
|
||||
handleHide();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user