Add tool tip view for first run of volume dialog to notify users of odi
captions functionality. Bug:128970574 Change-Id: I4710fd1d84f4116e003c14720a2ce55c5b3ff899 Test: manual
This commit is contained in:
@@ -60,7 +60,8 @@ public interface VolumeDialogController {
|
||||
|
||||
boolean areCaptionsEnabled();
|
||||
void setCaptionsEnabled(boolean isEnabled);
|
||||
void getCaptionsComponentState();
|
||||
|
||||
void getCaptionsComponentState(boolean fromTooltip);
|
||||
|
||||
@ProvidesInterface(version = StreamState.VERSION)
|
||||
public static final class StreamState {
|
||||
@@ -190,6 +191,6 @@ public interface VolumeDialogController {
|
||||
void onScreenOff();
|
||||
void onShowSafetyWarning(int flags);
|
||||
void onAccessibilityModeChanged(Boolean showA11yStream);
|
||||
void onCaptionComponentStateChanged(Boolean isComponentEnabled);
|
||||
void onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
28
packages/SystemUI/res/drawable/ic_remove_no_shadow.xml
Normal file
28
packages/SystemUI/res/drawable/ic_remove_no_shadow.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/textColorPrimary" >
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M13.41,12l5.29-5.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0L12,10.59L6.71,
|
||||
5.29c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41L10.59,12l-5.29,5.29c-0.39,0.39-0.39,1.02,
|
||||
0,1.41c0.39,0.39,1.02,0.39,1.41,0L12,13.41l5.29,5.29c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L13.41,12z"/>
|
||||
</vector>
|
||||
@@ -19,6 +19,23 @@
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,4C21.1,4 22,4.9 22,6L22,18C22,19.1 21.1,20 20,20L4,20C2.9,20 2,19.1 2,18L2,6C2,4.9 2.9,4 4,4L20,4ZM20,18L20,6L4,6L4,18L20,18ZM6,10L8,10L8,12L6,12L6,10ZM6,14L14,14L14,16L6,16L6,14ZM16,14L18,14L18,16L16,16L16,14ZM10,10L18,10L18,12L10,12L10,10Z"/>
|
||||
android:pathData="M16,12h2v2h-2z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M6,12h8v2h-8z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M20,2C21.1046,2 22,2.8954 22,4L22,16C22,17.1046 21.1046,18 20,18L6,18L2,22L2,4C2,2.8954 2.8954,2 4,2L20,2ZM20,16L20,4L4,4L4,16L20,16Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M6,8h2v2h-2z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M10,8h8v2h-8z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
</vector>
|
||||
|
||||
@@ -19,6 +19,19 @@
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.9675,14L18,14L18,15.0275L16.9675,14ZM20,17.0176L20,6L8.9281,6L6.9182,4L20,4C21.1,4 22,4.9 22,6L22,18C22,18.2949 21.9353,18.5755 21.8194,18.8281L20,17.0176ZM12.9478,10L18,10L18,12L14.9576,12L12.9478,10ZM1.2823,0.8824L22.8489,22.4489L21.6337,23.6641L17.9696,20L4,20C2.9,20 2,19.1 2,18L2,6C2,5.4577 2.2188,4.964 2.5724,4.6028L0.0672,2.0975L1.2823,0.8824ZM13.9696,16L6,16L6,14L11.9696,14L8,10.0304L8,12L6,12L6,10L7.9696,10L4,6.0304L4,18L15.9696,18L13.9696,16Z"/>
|
||||
android:pathData="M2.07,0.64L22,20.59L20.6,22L16.6,18L6,18L2,22L2,4C2.0006,3.8236 2.0276,3.6484 2.08,3.48L0.66,2.05L2.07,0.64ZM5.17,16L14.6,16L12.6,14L6,14L6,12L10.6,12L8,9.4L8,10L6,10L6,8L6.6,8L4,5.4L4,16L5.17,16Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M18,12l-1.74,0l1.74,1.74z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M18,8l-5.74,0l2,2l3.74,0z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M20,4L20,15.74L21.53,17.27C21.8296,16.9142 21.9958,16.4651 22,16L22,4C22,2.8954 21.1046,2 20,2L6.26,2L8.26,4L20,4Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="nonZero"/>
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<solid android:color="?android:attr/colorAccent" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
143
packages/SystemUI/res/layout-land/volume_dialog.xml
Normal file
143
packages/SystemUI/res/layout-land/volume_dialog.xml
Normal file
@@ -0,0 +1,143 @@
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/volume_dialog_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:layout_gravity="right"
|
||||
android:background="@android:color/transparent"
|
||||
android:theme="@style/volume_dialog_theme">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/volume_dialog"
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"
|
||||
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">
|
||||
|
||||
<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">
|
||||
<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: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"/>
|
||||
</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: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>
|
||||
</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.keyguard.AlphaOptimizedImageButton
|
||||
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/accent_tint_color_selector"
|
||||
android:layout_gravity="center"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</FrameLayout>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/odi_captions_tooltip_stub"
|
||||
android:inflatedId="@+id/odi_captions_tooltip_view"
|
||||
android:layout="@layout/volume_tool_tip_view"
|
||||
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"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -15,32 +15,38 @@
|
||||
-->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/volume_dialog_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:layout_gravity="right"
|
||||
android:background="@android:color/transparent"
|
||||
android:theme="@style/qs_theme">
|
||||
android:theme="@style/volume_dialog_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:layout_gravity="center_vertical|right"
|
||||
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:orientation="vertical"
|
||||
android:clipToPadding="false" >
|
||||
android:clipToPadding="false">
|
||||
|
||||
<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:gravity="right"
|
||||
android:layout_gravity="right"
|
||||
android:translationZ="@dimen/volume_dialog_elevation"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/rounded_bg_full">
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
@@ -62,11 +68,14 @@
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main"
|
||||
android:layout_width="wrap_content"
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"
|
||||
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
|
||||
@@ -103,10 +112,10 @@
|
||||
android:layout_width="@dimen/volume_dialog_caption_size"
|
||||
android:layout_height="@dimen/volume_dialog_caption_size"
|
||||
android:layout_marginTop="@dimen/volume_dialog_spacer"
|
||||
android:translationZ="@dimen/volume_dialog_elevation"
|
||||
android:gravity="right"
|
||||
android:layout_gravity="right"
|
||||
android:clipToPadding="false"
|
||||
android:visibility="gone"
|
||||
android:translationZ="@dimen/volume_dialog_elevation"
|
||||
android:background="@drawable/rounded_bg_full">
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/odi_captions_icon"
|
||||
@@ -121,4 +130,15 @@
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/odi_captions_tooltip_stub"
|
||||
android:inflatedId="@+id/odi_captions_tooltip_view"
|
||||
android:layout="@layout/volume_tool_tip_view"
|
||||
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"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -20,7 +20,7 @@
|
||||
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:theme="@style/qs_theme">
|
||||
android:theme="@style/volume_dialog_theme">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
63
packages/SystemUI/res/layout/volume_tool_tip_view.xml
Normal file
63
packages/SystemUI/res/layout/volume_tool_tip_view.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?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:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="4dp"
|
||||
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:textColor="@android:color/white"
|
||||
android:text="@string/volume_odi_captions_tip"
|
||||
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>
|
||||
|
||||
<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>
|
||||
@@ -34,4 +34,7 @@
|
||||
<bool name="quick_settings_wide">true</bool>
|
||||
<dimen name="qs_detail_margin_top">0dp</dimen>
|
||||
<dimen name="qs_paged_tile_layout_padding_bottom">0dp</dimen>
|
||||
|
||||
<dimen name="volume_tool_tip_right_margin">136dp</dimen>
|
||||
<dimen name="volume_tool_tip_top_margin">12dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -351,6 +351,12 @@
|
||||
|
||||
<dimen name="volume_dialog_elevation">9dp</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_corner_radius">2dp</dimen>
|
||||
|
||||
<!-- Gravity for the notification panel -->
|
||||
<integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
|
||||
|
||||
|
||||
@@ -1307,6 +1307,12 @@
|
||||
<!-- Content description for accessibility (not shown on the screen): volume dialog collapse button. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_volume_collapse">Collapse</string>
|
||||
|
||||
<!-- Label for the odi caption initial tool tip. [CHAR LIMIT=28] -->
|
||||
<string name="volume_odi_captions_tip">Automatically caption media</string>
|
||||
|
||||
<!-- Content description for accessibility: Clear the odi caption tool tip. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_volume_close_odi_captions_tip">Close captions tip</string>
|
||||
|
||||
<!-- content description for audio output chooser [CHAR LIMIT=NONE]-->
|
||||
<string name="accessibility_output_chooser">Switch output device</string>
|
||||
|
||||
|
||||
@@ -319,6 +319,10 @@
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
</style>
|
||||
|
||||
<style name="volume_dialog_theme" parent="qs_theme">
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
</style>
|
||||
|
||||
<style name="systemui_theme_remote_input" parent="@android:style/Theme.DeviceDefault.Light">
|
||||
<item name="android:colorAccent">@color/remote_input_accent</item>
|
||||
</style>
|
||||
|
||||
@@ -57,7 +57,8 @@ public final class Prefs {
|
||||
Key.SEEN_RINGER_GUIDANCE_COUNT,
|
||||
Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
|
||||
Key.TOUCHED_RINGER_TOGGLE,
|
||||
Key.QUICK_STEP_INTERACTION_FLAGS
|
||||
Key.QUICK_STEP_INTERACTION_FLAGS,
|
||||
Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP
|
||||
})
|
||||
public @interface Key {
|
||||
@Deprecated
|
||||
@@ -103,6 +104,7 @@ public final class Prefs {
|
||||
String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
|
||||
String TOUCHED_RINGER_TOGGLE = "TouchedRingerToggle";
|
||||
String QUICK_STEP_INTERACTION_FLAGS = "QuickStepInteractionFlags";
|
||||
String HAS_SEEN_ODI_CAPTIONS_TOOLTIP = "HasSeenODICaptionsTooltip";
|
||||
}
|
||||
|
||||
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
|
||||
|
||||
@@ -50,6 +50,24 @@ public class TriangleShape extends PathShape {
|
||||
return new TriangleShape(triangularPath, width, height);
|
||||
}
|
||||
|
||||
/** Create an arrow TriangleShape that points to the left or the right */
|
||||
public static TriangleShape createHorizontal(
|
||||
float width, float height, boolean isPointingLeft) {
|
||||
Path triangularPath = new Path();
|
||||
if (isPointingLeft) {
|
||||
triangularPath.moveTo(0, height / 2);
|
||||
triangularPath.lineTo(width, height);
|
||||
triangularPath.lineTo(width, 0);
|
||||
triangularPath.close();
|
||||
} else {
|
||||
triangularPath.moveTo(0, height);
|
||||
triangularPath.lineTo(width, height / 2);
|
||||
triangularPath.lineTo(0, 0);
|
||||
triangularPath.close();
|
||||
}
|
||||
return new TriangleShape(triangularPath, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOutline(@NonNull Outline outline) {
|
||||
outline.setConvexPath(mTriangularPath);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class Events {
|
||||
public static final int EVENT_SHOW_USB_OVERHEAT_ALARM = 19; // (reason|int) (keyguard|bool)
|
||||
public static final int EVENT_DISMISS_USB_OVERHEAT_ALARM = 20; // (reason|int) (keyguard|bool)
|
||||
public static final int EVENT_ODI_CAPTIONS_CLICK = 21;
|
||||
public static final int EVENT_ODI_CAPTIONS_TOOLTIP_CLICK = 22;
|
||||
|
||||
private static final String[] EVENT_TAGS = {
|
||||
"show_dialog",
|
||||
@@ -79,7 +80,8 @@ public class Events {
|
||||
"ringer_toggle",
|
||||
"show_usb_overheat_alarm",
|
||||
"dismiss_usb_overheat_alarm",
|
||||
"odi_captions_click"
|
||||
"odi_captions_click",
|
||||
"odi_captions_tooltip_click"
|
||||
};
|
||||
|
||||
public static final int DISMISS_REASON_UNKNOWN = 0;
|
||||
|
||||
@@ -282,9 +282,9 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
public void getCaptionsComponentState() {
|
||||
public void getCaptionsComponentState(boolean fromTooltip) {
|
||||
if (mDestroyed) return;
|
||||
mWorker.sendEmptyMessage(W.GET_CAPTIONS_COMPONENT_STATE);
|
||||
mWorker.obtainMessage(W.GET_CAPTIONS_COMPONENT_STATE, fromTooltip).sendToTarget();
|
||||
}
|
||||
|
||||
public void notifyVisible(boolean visible) {
|
||||
@@ -382,13 +382,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
}
|
||||
}
|
||||
|
||||
private void onGetCaptionsComponentStateW() {
|
||||
private void onGetCaptionsComponentStateW(boolean fromTooltip) {
|
||||
try {
|
||||
String componentNameString = mContext.getString(
|
||||
com.android.internal.R.string.config_defaultSystemCaptionsService);
|
||||
if (TextUtils.isEmpty(componentNameString)) {
|
||||
// component doesn't exist
|
||||
mCallbacks.onCaptionComponentStateChanged(false);
|
||||
mCallbacks.onCaptionComponentStateChanged(false, fromTooltip);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -399,18 +399,18 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
|
||||
ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
|
||||
if (componentName == null) {
|
||||
mCallbacks.onCaptionComponentStateChanged(false);
|
||||
mCallbacks.onCaptionComponentStateChanged(false, fromTooltip);
|
||||
return;
|
||||
}
|
||||
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
mCallbacks.onCaptionComponentStateChanged(
|
||||
packageManager.getComponentEnabledSetting(componentName)
|
||||
== PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
|
||||
== PackageManager.COMPONENT_ENABLED_STATE_ENABLED, fromTooltip);
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG,
|
||||
"isCaptionsServiceEnabled failed to check for captions component", ex);
|
||||
mCallbacks.onCaptionComponentStateChanged(false);
|
||||
mCallbacks.onCaptionComponentStateChanged(false, fromTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +790,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
case NOTIFY_VISIBLE: onNotifyVisibleW(msg.arg1 != 0); break;
|
||||
case USER_ACTIVITY: onUserActivityW(); break;
|
||||
case SHOW_SAFETY_WARNING: onShowSafetyWarningW(msg.arg1); break;
|
||||
case GET_CAPTIONS_COMPONENT_STATE: onGetCaptionsComponentStateW(); break;
|
||||
case GET_CAPTIONS_COMPONENT_STATE:
|
||||
onGetCaptionsComponentStateW((Boolean) msg.obj); break;
|
||||
case ACCESSIBILITY_MODE_CHANGED: onAccessibilityModeChanged((Boolean) msg.obj);
|
||||
}
|
||||
}
|
||||
@@ -933,11 +934,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptionComponentStateChanged(Boolean isComponentEnabled) {
|
||||
public void onCaptionComponentStateChanged(
|
||||
Boolean isComponentEnabled, Boolean fromTooltip) {
|
||||
boolean componentEnabled = isComponentEnabled == null ? false : isComponentEnabled;
|
||||
for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
|
||||
entry.getValue().post(
|
||||
() -> entry.getKey().onCaptionComponentStateChanged(componentEnabled));
|
||||
() -> entry.getKey().onCaptionComponentStateChanged(
|
||||
componentEnabled, fromTooltip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ 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.VISIBLE;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_ODI_CAPTIONS_CLICKED;
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
|
||||
@@ -64,11 +65,13 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.AccessibilityDelegate;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.view.ViewStub;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
@@ -113,7 +116,10 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
static final int DIALOG_TIMEOUT_MILLIS = 3000;
|
||||
static final int DIALOG_SAFETYWARNING_TIMEOUT_MILLIS = 5000;
|
||||
static final int DIALOG_ODI_CAPTIONS_TOOLTIP_TIMEOUT_MILLIS = 5000;
|
||||
static final int DIALOG_HOVERING_TIMEOUT_MILLIS = 16000;
|
||||
static final int DIALOG_SHOW_ANIMATION_DURATION = 300;
|
||||
static final int DIALOG_HIDE_ANIMATION_DURATION = 250;
|
||||
|
||||
private final Context mContext;
|
||||
private final H mHandler = new H();
|
||||
@@ -152,15 +158,21 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private boolean mHovering = false;
|
||||
private boolean mShowActiveStreamOnly;
|
||||
private boolean mConfigChanged = false;
|
||||
private boolean mHasSeenODICaptionsTooltip;
|
||||
private ViewStub mODICaptionsTooltipViewStub;
|
||||
private View mODICaptionsTooltipView = null;
|
||||
|
||||
public VolumeDialogImpl(Context context) {
|
||||
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
|
||||
mContext =
|
||||
new ContextThemeWrapper(context, com.android.systemui.R.style.volume_dialog_theme);
|
||||
mController = Dependency.get(VolumeDialogController.class);
|
||||
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
|
||||
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
|
||||
mShowActiveStreamOnly = showActiveStreamOnly();
|
||||
mHasSeenODICaptionsTooltip =
|
||||
Prefs.getBoolean(context, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
|
||||
}
|
||||
|
||||
public void init(int windowType, Callback callback) {
|
||||
@@ -201,8 +213,9 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
lp.format = PixelFormat.TRANSLUCENT;
|
||||
lp.setTitle(VolumeDialogImpl.class.getSimpleName());
|
||||
lp.windowAnimations = -1;
|
||||
lp.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
|
||||
mWindow.setAttributes(lp);
|
||||
mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);
|
||||
|
||||
mDialog.setContentView(R.layout.volume_dialog);
|
||||
mDialogView = mDialog.findViewById(R.id.volume_dialog);
|
||||
@@ -213,12 +226,13 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mDialogView.animate()
|
||||
.alpha(1)
|
||||
.translationX(0)
|
||||
.setDuration(300)
|
||||
.setDuration(DIALOG_SHOW_ANIMATION_DURATION)
|
||||
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
|
||||
.withEndAction(() -> {
|
||||
if (!Prefs.getBoolean(mContext, Prefs.Key.TOUCHED_RINGER_TOGGLE, false)) {
|
||||
if (mRingerIcon != null) {
|
||||
mRingerIcon.postOnAnimationDelayed(mSinglePress, 1500);
|
||||
mRingerIcon.postOnAnimationDelayed(
|
||||
getSinglePressFor(mRingerIcon), 1500);
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -233,20 +247,23 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
return true;
|
||||
});
|
||||
|
||||
lp = mWindow.getAttributes();
|
||||
lp.gravity = ((FrameLayout.LayoutParams) mDialogView.getLayoutParams()).gravity;
|
||||
mWindow.setAttributes(lp);
|
||||
|
||||
mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows);
|
||||
mRinger = mDialog.findViewById(R.id.ringer);
|
||||
if (mRinger != null) {
|
||||
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
|
||||
mZenIcon = mRinger.findViewById(R.id.dnd_icon);
|
||||
}
|
||||
|
||||
mODICaptionsView = mDialog.findViewById(R.id.odi_captions);
|
||||
if (mODICaptionsView != null) {
|
||||
mODICaptionsIcon = mODICaptionsView.findViewById(R.id.odi_captions_icon);
|
||||
}
|
||||
mODICaptionsTooltipViewStub = mDialog.findViewById(R.id.odi_captions_tooltip_stub);
|
||||
if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipViewStub != null) {
|
||||
mDialogView.removeView(mODICaptionsTooltipViewStub);
|
||||
mODICaptionsTooltipViewStub = null;
|
||||
}
|
||||
|
||||
mSettingsView = mDialog.findViewById(R.id.settings_container);
|
||||
mSettingsIcon = mDialog.findViewById(R.id.settings);
|
||||
|
||||
@@ -495,10 +512,70 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
});
|
||||
}
|
||||
|
||||
mController.getCaptionsComponentState();
|
||||
mController.getCaptionsComponentState(false);
|
||||
}
|
||||
|
||||
private void updateODICaptionsH(boolean isServiceComponentEnabled) {
|
||||
private void checkODICaptionsTooltip(boolean fromDismiss) {
|
||||
if (!mHasSeenODICaptionsTooltip && !fromDismiss && mODICaptionsTooltipViewStub != null) {
|
||||
mController.getCaptionsComponentState(true);
|
||||
} else {
|
||||
if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
|
||||
hideCaptionsTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void showCaptionsTooltip() {
|
||||
if (!mHasSeenODICaptionsTooltip && mODICaptionsTooltipViewStub != null) {
|
||||
mODICaptionsTooltipView = mODICaptionsTooltipViewStub.inflate();
|
||||
mODICaptionsTooltipView.findViewById(R.id.dismiss).setOnClickListener(v -> {
|
||||
hideCaptionsTooltip();
|
||||
Events.writeEvent(mContext, Events.EVENT_ODI_CAPTIONS_TOOLTIP_CLICK);
|
||||
});
|
||||
mODICaptionsTooltipViewStub = null;
|
||||
rescheduleTimeoutH();
|
||||
}
|
||||
|
||||
if (mODICaptionsTooltipView != null) {
|
||||
mODICaptionsTooltipView.setAlpha(0.f);
|
||||
mODICaptionsTooltipView.animate()
|
||||
.alpha(1.f)
|
||||
.setStartDelay(DIALOG_SHOW_ANIMATION_DURATION)
|
||||
.withEndAction(() -> {
|
||||
if (D.BUG) Log.d(TAG, "tool:checkODICaptionsTooltip() putBoolean true");
|
||||
Prefs.putBoolean(mContext,
|
||||
Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, true);
|
||||
mHasSeenODICaptionsTooltip = true;
|
||||
if (mODICaptionsIcon != null) {
|
||||
mODICaptionsIcon
|
||||
.postOnAnimation(getSinglePressFor(mODICaptionsIcon));
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideCaptionsTooltip() {
|
||||
if (mODICaptionsTooltipView != null) {
|
||||
mODICaptionsTooltipView.animate().cancel();
|
||||
mODICaptionsTooltipView.setAlpha(1.f);
|
||||
mODICaptionsTooltipView.animate()
|
||||
.alpha(0.f)
|
||||
.setStartDelay(0)
|
||||
.setDuration(DIALOG_HIDE_ANIMATION_DURATION)
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
protected void tryToRemoveCaptionsTooltip() {
|
||||
if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
|
||||
ViewGroup container = mDialog.findViewById(R.id.volume_dialog_container);
|
||||
container.removeView(mODICaptionsTooltipView);
|
||||
mODICaptionsTooltipView = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateODICaptionsH(boolean isServiceComponentEnabled, boolean fromTooltip) {
|
||||
if (mODICaptionsView != null) {
|
||||
mODICaptionsView.setVisibility(isServiceComponentEnabled ? VISIBLE : GONE);
|
||||
}
|
||||
@@ -506,6 +583,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
if (!isServiceComponentEnabled) return;
|
||||
|
||||
updateCaptionsIcon();
|
||||
if (fromTooltip) showCaptionsTooltip();
|
||||
}
|
||||
|
||||
private void updateCaptionsIcon() {
|
||||
@@ -602,7 +680,8 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mDialog.show();
|
||||
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
|
||||
mController.notifyVisible(true);
|
||||
mController.getCaptionsComponentState();
|
||||
mController.getCaptionsComponentState(false);
|
||||
checkODICaptionsTooltip(false);
|
||||
}
|
||||
|
||||
protected void rescheduleTimeoutH() {
|
||||
@@ -625,11 +704,21 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
AccessibilityManager.FLAG_CONTENT_TEXT
|
||||
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
if (!mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
|
||||
return mAccessibilityMgr.getRecommendedTimeoutMillis(
|
||||
DIALOG_ODI_CAPTIONS_TOOLTIP_TIMEOUT_MILLIS,
|
||||
AccessibilityManager.FLAG_CONTENT_TEXT
|
||||
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS,
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
|
||||
protected void dismissH(int reason) {
|
||||
if (D.BUG) {
|
||||
Log.d(TAG, "mDialog.dismiss() reason: " + Events.DISMISS_REASONS[reason]
|
||||
+ " from: " + Debug.getCaller());
|
||||
}
|
||||
mHandler.removeMessages(H.DISMISS);
|
||||
mHandler.removeMessages(H.SHOW);
|
||||
mDialogView.animate().cancel();
|
||||
@@ -642,14 +731,15 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mDialogView.setAlpha(1);
|
||||
ViewPropertyAnimator animator = mDialogView.animate()
|
||||
.alpha(0)
|
||||
.setDuration(250)
|
||||
.setDuration(DIALOG_HIDE_ANIMATION_DURATION)
|
||||
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
|
||||
.withEndAction(() -> mHandler.postDelayed(() -> {
|
||||
if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
|
||||
mDialog.dismiss();
|
||||
tryToRemoveCaptionsTooltip();
|
||||
}, 50));
|
||||
if (!isLandscape()) animator.translationX(mDialogView.getWidth() / 2);
|
||||
animator.start();
|
||||
checkODICaptionsTooltip(true);
|
||||
mController.notifyVisible(false);
|
||||
synchronized (mSafetyWarningLock) {
|
||||
if (mSafetyWarning != null) {
|
||||
@@ -822,6 +912,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
|
||||
protected void onStateChangedH(State state) {
|
||||
if (D.BUG) Log.d(TAG, "onStateChangedH() state: " + state.toString());
|
||||
if (mState != null && state != null
|
||||
&& mState.ringerModeInternal != state.ringerModeInternal
|
||||
&& state.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
@@ -847,7 +938,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mActiveStream = state.activeStream;
|
||||
VolumeRow activeRow = getActiveRow();
|
||||
updateRowsH(activeRow);
|
||||
rescheduleTimeoutH();
|
||||
if (mShowing) rescheduleTimeoutH();
|
||||
}
|
||||
for (VolumeRow row : mRows) {
|
||||
updateVolumeRowH(row);
|
||||
@@ -1114,24 +1205,22 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable mSinglePress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mRingerIcon != null) {
|
||||
mRingerIcon.setPressed(true);
|
||||
mRingerIcon.postOnAnimationDelayed(mSingleUnpress, 200);
|
||||
private Runnable getSinglePressFor(ImageButton button) {
|
||||
return () -> {
|
||||
if (button != null) {
|
||||
button.setPressed(true);
|
||||
button.postOnAnimationDelayed(getSingleUnpressFor(button), 200);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
private Runnable mSingleUnpress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mRingerIcon != null) {
|
||||
mRingerIcon.setPressed(false);
|
||||
private Runnable getSingleUnpressFor(ImageButton button) {
|
||||
return () -> {
|
||||
if (button != null) {
|
||||
button.setPressed(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
private final VolumeDialogController.Callbacks mControllerCallbackH
|
||||
= new VolumeDialogController.Callbacks() {
|
||||
@@ -1198,8 +1287,9 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptionComponentStateChanged(Boolean isComponentEnabled) {
|
||||
updateODICaptionsH(isComponentEnabled);
|
||||
public void onCaptionComponentStateChanged(
|
||||
Boolean isComponentEnabled, Boolean fromTooltip) {
|
||||
updateODICaptionsH(isComponentEnabled, fromTooltip);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1232,7 +1322,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
private final class CustomDialog extends Dialog implements DialogInterface {
|
||||
public CustomDialog(Context context) {
|
||||
super(context, com.android.systemui.R.style.qs_theme);
|
||||
super(context, com.android.systemui.R.style.volume_dialog_theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.CornerPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.TriangleShape;
|
||||
|
||||
/**
|
||||
* Tool tip view that draws an arrow that points to the volume dialog.
|
||||
*/
|
||||
public class VolumeToolTipView extends LinearLayout {
|
||||
public VolumeToolTipView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public VolumeToolTipView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public VolumeToolTipView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public VolumeToolTipView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
drawArrow();
|
||||
}
|
||||
|
||||
private void drawArrow() {
|
||||
View arrowView = findViewById(R.id.arrow);
|
||||
ViewGroup.LayoutParams arrowLp = arrowView.getLayoutParams();
|
||||
ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.createHorizontal(
|
||||
arrowLp.width, arrowLp.height, false));
|
||||
Paint arrowPaint = arrowDrawable.getPaint();
|
||||
TypedValue typedValue = new TypedValue();
|
||||
getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
|
||||
arrowPaint.setColor(ContextCompat.getColor(getContext(), typedValue.resourceId));
|
||||
// The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
|
||||
arrowPaint.setPathEffect(new CornerPathEffect(
|
||||
getResources().getDimension(R.dimen.volume_tool_tip_arrow_corner_radius)));
|
||||
arrowView.setBackground(arrowDrawable);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,17 @@ public class VolumeDialogImplTest extends SysuiTestCase {
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeTimeout_tooltip() {
|
||||
Mockito.reset(mAccessibilityMgr);
|
||||
mDialog.showCaptionsTooltip();
|
||||
verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
|
||||
VolumeDialogImpl.DIALOG_ODI_CAPTIONS_TOOLTIP_TIMEOUT_MILLIS,
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS
|
||||
| AccessibilityManager.FLAG_CONTENT_TEXT);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testComputeTimeout_withHovering() {
|
||||
Mockito.reset(mAccessibilityMgr);
|
||||
@@ -146,6 +157,16 @@ public class VolumeDialogImplTest extends SysuiTestCase {
|
||||
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeTimeout_standard() {
|
||||
Mockito.reset(mAccessibilityMgr);
|
||||
mDialog.tryToRemoveCaptionsTooltip();
|
||||
mDialog.rescheduleTimeoutH();
|
||||
verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
|
||||
VolumeDialogImpl.DIALOG_TIMEOUT_MILLIS,
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void testContentDescriptions() {
|
||||
|
||||
Reference in New Issue
Block a user