Snap for 9631680 from ae2c14a039 to udc-release

Change-Id: Ic4775f1e8a531b64661f84c9b518963c408cc69b
This commit is contained in:
Android Build Coastguard Worker
2023-02-21 02:27:50 +00:00
31 changed files with 1065 additions and 627 deletions

33
res-product/values/config.xml Executable file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- The illustration for those screen are not in one of below type. This file should be a video in JSON format. -->
<item name="a11y_timeout_banner" type="raw" product="default">@raw/accessibility_timeout_banner</item>
<item name="a11y_timeout_banner" type="raw" product="tablet">@raw/accessibility_timeout_banner_tablet</item>
<item name="a11y_shortcut_type_triple_tap" type="raw" product="default">@raw/accessibility_shortcut_type_triple_tap</item>
<item name="a11y_shortcut_type_triple_tap" type="raw" product="tablet">@raw/accessibility_shortcut_type_triple_tap_tablet</item>
<item name="a11y_color_inversion_banner" type="raw" product="default">@raw/accessibility_color_inversion_banner</item>
<item name="a11y_color_inversion_banner" type="raw" product="tablet">@raw/accessibility_color_inversion_banner_tablet</item>
<item name="a11y_magnification_banner" type="raw" product="default">@raw/accessibility_magnification_banner</item>
<item name="a11y_magnification_banner" type="raw" product="tablet">@raw/accessibility_magnification_banner_tablet</item>
<item name="a11y_extra_dim_banner" type="raw" product="default">@raw/extra_dim_banner</item>
<item name="a11y_extra_dim_banner" type="raw" product="tablet">@raw/extra_dim_banner_tablet</item>
</resources>

View File

@@ -14,9 +14,6 @@
limitations under the License.
-->
<resources>
<drawable name="a11y_shortcut_type_software_gesture_talkback" product="default">@drawable/accessibility_shortcut_type_software_gesture_talkback</drawable>
<drawable name="a11y_shortcut_type_software_gesture_talkback" product="tablet">@drawable/accessibility_shortcut_type_software_gesture_talkback_tablet</drawable>
<drawable name="a11y_button_preview_base" product="default">@drawable/accessibility_button_preview_base</drawable>
<drawable name="a11y_button_preview_base" product="tablet">@drawable/accessibility_button_preview_base_tablet</drawable>
@@ -26,12 +23,6 @@
<drawable name="a11y_button_preview_small_floating_menu" product="default">@drawable/accessibility_button_preview_small_floating_menu</drawable>
<drawable name="a11y_button_preview_small_floating_menu" product="tablet">@drawable/accessibility_button_preview_small_floating_menu_tablet</drawable>
<drawable name="a11y_button_preview_three_finger" product="default">@drawable/accessibility_button_preview_three_finger</drawable>
<drawable name="a11y_button_preview_three_finger" product="tablet">@drawable/accessibility_button_preview_three_finger_tablet</drawable>
<drawable name="a11y_button_preview_two_finger" product="default">@drawable/accessibility_button_preview_two_finger</drawable>
<drawable name="a11y_button_preview_two_finger" product="tablet">@drawable/accessibility_button_preview_two_finger_tablet</drawable>
<drawable name="a11y_button_navigation" product="default">@drawable/accessibility_button_navigation</drawable>
<drawable name="a11y_button_navigation" product="tablet">@drawable/accessibility_button_navigation_tablet</drawable>
@@ -50,6 +41,21 @@
<drawable name="a11y_shortcut_type_software_gesture" product="default">@drawable/accessibility_shortcut_type_software_gesture</drawable>
<drawable name="a11y_shortcut_type_software_gesture" product="tablet">@drawable/accessibility_shortcut_type_software_gesture_tablet</drawable>
<drawable name="a11y_shortcut_type_software_gesture_talkback" product="default">@drawable/accessibility_shortcut_type_software_gesture_talkback</drawable>
<drawable name="a11y_shortcut_type_software_gesture_talkback" product="tablet">@drawable/accessibility_shortcut_type_software_gesture_talkback_tablet</drawable>
<drawable name="a11y_gesture_navigation_two_finger_preview" product="default">@drawable/accessibility_gesture_navigation_two_finger_preview</drawable>
<drawable name="a11y_gesture_navigation_two_finger_preview" product="tablet">@drawable/accessibility_gesture_navigation_two_finger_preview_tablet</drawable>
<drawable name="a11y_gesture_navigation_three_finger_preview" product="default">@drawable/accessibility_gesture_navigation_three_finger_preview</drawable>
<drawable name="a11y_gesture_navigation_three_finger_preview" product="tablet">@drawable/accessibility_gesture_navigation_three_finger_preview_tablet</drawable>
<drawable name="a11y_button_preview_two_finger" product="default">@drawable/accessibility_button_preview_two_finger</drawable>
<drawable name="a11y_button_preview_two_finger" product="tablet">@drawable/accessibility_button_preview_two_finger_tablet</drawable>
<drawable name="a11y_button_preview_three_finger" product="default">@drawable/accessibility_button_preview_three_finger</drawable>
<drawable name="a11y_button_preview_three_finger" product="tablet">@drawable/accessibility_button_preview_three_finger_tablet</drawable>
<drawable name="a11y_magnification_mode_fullscreen" product="default">@drawable/accessibility_magnification_mode_fullscreen</drawable>
<drawable name="a11y_magnification_mode_fullscreen" product="tablet">@drawable/accessibility_magnification_mode_fullscreen_tablet</drawable>
@@ -58,4 +64,4 @@
<drawable name="a11y_magnification_mode_window" product="default">@drawable/accessibility_magnification_mode_window</drawable>
<drawable name="a11y_magnification_mode_window" product="tablet">@drawable/accessibility_magnification_mode_window_tablet</drawable>
</resources>
</resources>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M176.84,188.94C173.14,188.94 170.24,191.94 170.24,195.54V220.14H183.54V195.54C183.54,191.94 180.54,188.94 176.84,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="176.89"
android:startY="220.23"
android:endX="176.89"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M206.14,188.94C202.44,188.94 199.54,191.94 199.54,195.54V220.14H212.84V195.54C212.74,191.94 209.84,188.94 206.14,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="206.19"
android:startY="220.23"
android:endX="206.19"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M235.44,188.94C231.74,188.94 228.84,191.94 228.84,195.54V220.14H242.14V195.54C242.04,191.94 239.14,188.94 235.44,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="235.49"
android:startY="220.23"
android:endX="235.49"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M188.15,188.94C184.45,188.94 181.55,191.94 181.55,195.54V220.14H194.85V195.54C194.85,191.94 191.85,188.94 188.15,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="188.2"
android:startY="220.23"
android:endX="188.2"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M222.95,188.94C219.25,188.94 216.35,191.94 216.35,195.54V220.14H229.55V195.54C229.55,191.94 226.65,188.94 222.95,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="222.95"
android:startY="220.23"
android:endX="222.95"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@@ -19,22 +19,22 @@
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<path
android:fillColor="#FF000000"
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"/>
<path
android:pathData="M139.5,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9v-17c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H139.5c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.7c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C125.1,218.8 131.6,225.3 139.5,225.3z"
android:fillColor="#80868B"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#80868B"/>
<path
android:pathData="M198.4,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C201.6,208.4 200.2,206.5 198.4,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M217.7,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C220.9,208.4 219.6,206.5 217.7,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M206.1,19.1c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4C88.8,217.9 75.1,185 75.1,150s13.6,-67.9 38.4,-92.6C138.2,32.7 171.1,19.1 206.1,19.1M206.1,17.1c-73.4,0 -133,59.5 -133,132.9S132.6,282.9 206,282.9S339,223.4 339,150S279.5,17.1 206.1,17.1L206.1,17.1z"
android:fillColor="#3C4043"/>
</vector>
<path
android:fillColor="#FF000000"
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"/>
<path
android:pathData="M139.5,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9v-17c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H139.5c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.7c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C125.1,218.8 131.6,225.3 139.5,225.3z"
android:fillColor="#80868B"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#80868B"/>
<path
android:pathData="M198.4,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C201.6,208.4 200.2,206.5 198.4,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M217.7,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C220.9,208.4 219.6,206.5 217.7,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M206.1,19.1c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4C88.8,217.9 75.1,185 75.1,150s13.6,-67.9 38.4,-92.6C138.2,32.7 171.1,19.1 206.1,19.1M206.1,17.1c-73.4,0 -133,59.5 -133,132.9S132.6,282.9 206,282.9S339,223.4 339,150S279.5,17.1 206.1,17.1L206.1,17.1z"
android:fillColor="#3C4043"/>
</vector>

View File

@@ -1,50 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M188.15,188.94C184.45,188.94 181.55,191.94 181.55,195.54V220.14H194.85V195.54C194.85,191.94 191.85,188.94 188.15,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="188.2"
android:startY="220.23"
android:endX="188.2"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M222.95,188.94C219.25,188.94 216.35,191.94 216.35,195.54V220.14H229.55V195.54C229.55,191.94 226.65,188.94 222.95,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="222.95"
android:startY="220.23"
android:endX="222.95"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
</group>
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M170.9,232.14L241.9,232.14A2,2 0,0 1,243.9 234.14L243.9,234.14A2,2 0,0 1,241.9 236.14L170.9,236.14A2,2 0,0 1,168.9 234.14L168.9,234.14A2,2 0,0 1,170.9 232.14z"
android:fillColor="#80868B"/>
<path
android:pathData="M198.35,229.14V217.74H203.25L196.35,205.54L189.45,217.74H194.35V229.14C192.45,229.94 191.15,231.74 191.15,233.94C191.15,236.84 193.45,239.14 196.35,239.14C199.25,239.14 201.55,236.84 201.55,233.94C201.55,231.84 200.15,229.94 198.35,229.14Z"
android:fillColor="#669DF6"/>
<path
android:pathData="M217.65,229.14V217.74H222.55L215.65,205.54L208.75,217.74H213.65V229.14C211.75,229.94 210.45,231.74 210.45,233.94C210.45,236.84 212.75,239.14 215.65,239.14C218.55,239.14 220.85,236.84 220.85,233.94C220.85,231.84 219.55,229.94 217.65,229.14Z"
android:fillColor="#669DF6"/>
</group>
</vector>

View File

@@ -19,25 +19,25 @@
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<path
android:fillColor="#FF000000"
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"/>
<path
android:pathData="M138,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9V45.7c-1.9,-1.5 -3.8,-2.9 -5.8,-4.3v169.4c0,6.4 -5.2,11.6 -11.6,11.6H138c-6.4,0 -11.6,-5.2 -11.6,-11.6V43.5c-1,0.7 -1.9,1.5 -2.9,2.2v165C123.5,218.8 130,225.3 138,225.3z"
android:fillColor="#80868B"/>
<path
android:pathData="M206,283.9c-73.9,0 -133.9,-60.1 -133.9,-133.9S132.1,16.1 206,16.1c73.9,0 133.9,60.1 133.9,133.9S279.9,283.9 206,283.9zM206,18.1C133.2,18.1 74.1,77.2 74.1,150S133.2,281.9 206,281.9S337.9,222.8 337.9,150S278.8,18.1 206,18.1z"
android:fillColor="#3C4043"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#80868B"/>
<path
android:pathData="M190.9,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C194.1,208.4 192.8,206.5 190.9,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M208,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C211.2,208.4 209.9,206.5 208,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M225.1,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C228.2,208.4 226.9,206.5 225.1,205.7z"
android:fillColor="#669DF6"/>
</vector>
<path
android:fillColor="#FF000000"
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"/>
<path
android:pathData="M138,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9V45.7c-1.9,-1.5 -3.8,-2.9 -5.8,-4.3v169.4c0,6.4 -5.2,11.6 -11.6,11.6H138c-6.4,0 -11.6,-5.2 -11.6,-11.6V43.5c-1,0.7 -1.9,1.5 -2.9,2.2v165C123.5,218.8 130,225.3 138,225.3z"
android:fillColor="#80868B"/>
<path
android:pathData="M206,283.9c-73.9,0 -133.9,-60.1 -133.9,-133.9S132.1,16.1 206,16.1c73.9,0 133.9,60.1 133.9,133.9S279.9,283.9 206,283.9zM206,18.1C133.2,18.1 74.1,77.2 74.1,150S133.2,281.9 206,281.9S337.9,222.8 337.9,150S278.8,18.1 206,18.1z"
android:fillColor="#3C4043"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#80868B"/>
<path
android:pathData="M190.9,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C194.1,208.4 192.8,206.5 190.9,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M208,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C211.2,208.4 209.9,206.5 208,205.7z"
android:fillColor="#669DF6"/>
<path
android:pathData="M225.1,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C228.2,208.4 226.9,206.5 225.1,205.7z"
android:fillColor="#669DF6"/>
</vector>

View File

@@ -1,64 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M176.84,188.94C173.14,188.94 170.24,191.94 170.24,195.54V220.14H183.54V195.54C183.54,191.94 180.54,188.94 176.84,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="176.89"
android:startY="220.23"
android:endX="176.89"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M206.14,188.94C202.44,188.94 199.54,191.94 199.54,195.54V220.14H212.84V195.54C212.74,191.94 209.84,188.94 206.14,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="206.19"
android:startY="220.23"
android:endX="206.19"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M235.44,188.94C231.74,188.94 228.84,191.94 228.84,195.54V220.14H242.14V195.54C242.04,191.94 239.14,188.94 235.44,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="235.49"
android:startY="220.23"
android:endX="235.49"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#00669DF6"/>
<item android:offset="0.69" android:color="#FF669DF6"/>
</gradient>
</aapt:attr>
</path>
</group>
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#000000"
android:strokeColor="#80868B"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#80868B"/>
<path
android:pathData="M170.9,232.14L241.9,232.14A2,2 0,0 1,243.9 234.14L243.9,234.14A2,2 0,0 1,241.9 236.14L170.9,236.14A2,2 0,0 1,168.9 234.14L168.9,234.14A2,2 0,0 1,170.9 232.14z"
android:fillColor="#80868B"/>
<path
android:pathData="M188.7,229.14V217.74H193.6L186.7,205.54L179.8,217.74H184.7V229.14C182.8,229.94 181.5,231.74 181.5,233.94C181.5,236.84 183.8,239.14 186.7,239.14C189.6,239.14 191.9,236.84 191.9,233.94C191.9,231.84 190.5,229.94 188.7,229.14Z"
android:fillColor="#669DF6"/>
<path
android:pathData="M208,229.14V217.74H212.9L206,205.54L199.1,217.74H204V229.14C202.1,229.94 200.8,231.74 200.8,233.94C200.8,236.84 203.1,239.14 206,239.14C208.9,239.14 211.2,236.84 211.2,233.94C211.2,231.84 209.9,229.94 208,229.14Z"
android:fillColor="#669DF6"/>
<path
android:pathData="M227.29,229.14V217.74H232.2L225.29,205.54L218.4,217.74H223.29V229.14C221.4,229.94 220.1,231.74 220.1,233.94C220.1,236.84 222.4,239.14 225.29,239.14C228.2,239.14 230.49,236.84 230.49,233.94C230.49,231.84 229.2,229.94 227.29,229.14Z"
android:fillColor="#669DF6"/>
</group>
</vector>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M176.84,188.94C173.14,188.94 170.24,191.94 170.24,195.54V220.14H183.54V195.54C183.54,191.94 180.54,188.94 176.84,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="176.89"
android:startY="220.23"
android:endX="176.89"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M206.14,188.94C202.44,188.94 199.54,191.94 199.54,195.54V220.14H212.84V195.54C212.74,191.94 209.84,188.94 206.14,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="206.19"
android:startY="220.23"
android:endX="206.19"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M235.44,188.94C231.74,188.94 228.84,191.94 228.84,195.54V220.14H242.14V195.54C242.04,191.94 239.14,188.94 235.44,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="235.49"
android:startY="220.23"
android:endX="235.49"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M188.15,188.94C184.45,188.94 181.55,191.94 181.55,195.54V220.14H194.85V195.54C194.85,191.94 191.85,188.94 188.15,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="188.2"
android:startY="220.23"
android:endX="188.2"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M222.95,188.94C219.25,188.94 216.35,191.94 216.35,195.54V220.14H229.55V195.54C229.55,191.94 226.65,188.94 222.95,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="222.95"
android:startY="220.23"
android:endX="222.95"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@@ -19,40 +19,40 @@
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<path
android:fillColor="#FF000000"
android:pathData="M842.3,299.9H485.9c-15.3,0 -27.8,-12.8 -27.8,-28.5v-243c0,-15.7 12.5,-28.5 27.8,-28.5h356.5c15.2,0 27.7,12.8 27.7,28.5v243.2C870.1,287.1 857.6,299.9 842.3,299.9z"/>
<path
android:pathData="M597.6,225.2h133.1c8,0 14.5,-6.5 14.5,-14.5V68.9c1.6,0 2.9,-1.3 2.9,-2.9V49c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H597.6c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.6c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C583.2,218.7 589.7,225.2 597.6,225.2z"
android:fillColor="#80868B"/>
<path
android:pathData="M688,207.8h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2H688c1.1,0 2,-0.9 2,-2S689.1,207.8 688,207.8z"
android:fillColor="#80868B"/>
<path
android:pathData="M656.5,205.6v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C659.7,208.3 658.3,206.4 656.5,205.6z"
android:fillColor="#669DF6"/>
<path
android:pathData="M675.8,205.6v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C679,208.3 677.7,206.4 675.8,205.6z"
android:fillColor="#669DF6"/>
<path
android:pathData="M664.2,19c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4c-24.7,-24.8 -38.4,-57.7 -38.4,-92.7s13.6,-67.9 38.4,-92.6C596.3,32.6 629.2,19 664.2,19M664.2,17c-73.4,0 -133,59.5 -133,132.9s59.5,132.9 132.9,132.9s133,-59.5 133,-132.9S737.6,17 664.2,17L664.2,17z"
android:fillColor="#3C4043"/>
<path
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M139.4,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9v-17c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H139.4c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.7c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C125,218.8 131.5,225.3 139.4,225.3z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M198.4,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C201.5,208.4 200.1,206.5 198.4,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M217.6,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C220.9,208.4 219.5,206.5 217.6,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M206.1,19.1c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4S75.1,185 75.1,150s13.6,-67.9 38.4,-92.6C138.2,32.7 171.1,19.1 206.1,19.1M206.1,17.1c-73.4,0 -133,59.5 -133,132.9S132.6,282.9 206,282.9S339,223.4 339,150S279.5,17.1 206.1,17.1L206.1,17.1z"
android:fillColor="#E8EAED"/>
<path
android:fillColor="#FF000000"
android:pathData="M842.3,299.9H485.9c-15.3,0 -27.8,-12.8 -27.8,-28.5v-243c0,-15.7 12.5,-28.5 27.8,-28.5h356.5c15.2,0 27.7,12.8 27.7,28.5v243.2C870.1,287.1 857.6,299.9 842.3,299.9z"/>
<path
android:pathData="M597.6,225.2h133.1c8,0 14.5,-6.5 14.5,-14.5V68.9c1.6,0 2.9,-1.3 2.9,-2.9V49c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H597.6c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.6c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C583.2,218.7 589.7,225.2 597.6,225.2z"
android:fillColor="#80868B"/>
<path
android:pathData="M688,207.8h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2H688c1.1,0 2,-0.9 2,-2S689.1,207.8 688,207.8z"
android:fillColor="#80868B"/>
<path
android:pathData="M656.5,205.6v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C659.7,208.3 658.3,206.4 656.5,205.6z"
android:fillColor="#669DF6"/>
<path
android:pathData="M675.8,205.6v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C679,208.3 677.7,206.4 675.8,205.6z"
android:fillColor="#669DF6"/>
<path
android:pathData="M664.2,19c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4c-24.7,-24.8 -38.4,-57.7 -38.4,-92.7s13.6,-67.9 38.4,-92.6C596.3,32.6 629.2,19 664.2,19M664.2,17c-73.4,0 -133,59.5 -133,132.9s59.5,132.9 132.9,132.9s133,-59.5 133,-132.9S737.6,17 664.2,17L664.2,17z"
android:fillColor="#3C4043"/>
<path
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M139.4,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9v-17c-1.9,-1.6 -3.8,-3.2 -5.8,-4.7v166.4c0,6.4 -5.2,11.6 -11.6,11.6H139.4c-6.4,0 -11.6,-5.2 -11.6,-11.6V42.7c-1,0.7 -1.9,1.4 -2.9,2.1v166.1C125,218.8 131.5,225.3 139.4,225.3z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M198.4,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C201.5,208.4 200.1,206.5 198.4,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M217.6,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2s5.2,-2.3 5.2,-5.2C220.9,208.4 219.5,206.5 217.6,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M206.1,19.1c35,0 67.9,13.6 92.6,38.4c24.7,24.7 38.4,57.6 38.4,92.6s-13.6,67.9 -38.4,92.6c-24.7,24.7 -57.6,38.4 -92.6,38.4s-67.9,-13.6 -92.6,-38.4S75.1,185 75.1,150s13.6,-67.9 38.4,-92.6C138.2,32.7 171.1,19.1 206.1,19.1M206.1,17.1c-73.4,0 -133,59.5 -133,132.9S132.6,282.9 206,282.9S339,223.4 339,150S279.5,17.1 206.1,17.1L206.1,17.1z"
android:fillColor="#E8EAED"/>
</vector>

View File

@@ -1,50 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M188.15,188.94C184.45,188.94 181.55,191.94 181.55,195.54V220.14H194.85V195.54C194.85,191.94 191.85,188.94 188.15,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="188.2"
android:startY="220.23"
android:endX="188.2"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M222.95,188.94C219.25,188.94 216.35,191.94 216.35,195.54V220.14H229.55V195.54C229.55,191.94 226.65,188.94 222.95,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="222.95"
android:startY="220.23"
android:endX="222.95"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
</group>
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M170.9,232.14L241.9,232.14A2,2 0,0 1,243.9 234.14L243.9,234.14A2,2 0,0 1,241.9 236.14L170.9,236.14A2,2 0,0 1,168.9 234.14L168.9,234.14A2,2 0,0 1,170.9 232.14z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M198.35,229.14V217.74H203.25L196.35,205.54L189.45,217.74H194.35V229.14C192.45,229.94 191.15,231.74 191.15,233.94C191.15,236.84 193.45,239.14 196.35,239.14C199.25,239.14 201.55,236.84 201.55,233.94C201.55,231.84 200.15,229.94 198.35,229.14Z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M217.65,229.14V217.74H222.55L215.65,205.54L208.75,217.74H213.65V229.14C211.75,229.94 210.45,231.74 210.45,233.94C210.45,236.84 212.75,239.14 215.65,239.14C218.55,239.14 220.85,236.84 220.85,233.94C220.85,231.84 219.55,229.94 217.65,229.14Z"
android:fillColor="#1A73E8"/>
</group>
</vector>

View File

@@ -19,25 +19,25 @@
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<path
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M138,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9V45.7c-1.9,-1.5 -3.8,-2.9 -5.8,-4.3v169.4c0,6.4 -5.2,11.6 -11.6,11.6H138c-6.4,0 -11.6,-5.2 -11.6,-11.6V43.5c-1,0.7 -1.9,1.5 -2.9,2.2v165C123.5,218.8 130,225.3 138,225.3z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M206,283.9c-73.9,0 -133.9,-60.1 -133.9,-133.9S132.1,16.1 206,16.1c73.9,0 133.9,60.1 133.9,133.9S279.9,283.9 206,283.9zM206,18.1C133.2,18.1 74.1,77.2 74.1,150S133.2,281.9 206,281.9S337.9,222.8 337.9,150S278.8,18.1 206,18.1z"
android:fillColor="#E8EAED"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M190.9,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C194.1,208.4 192.8,206.5 190.9,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M208,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C211.2,208.4 209.9,206.5 208,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M225.1,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C228.2,208.4 226.9,206.5 225.1,205.7z"
android:fillColor="#1A73E8"/>
</vector>
<path
android:pathData="M384.2,300H27.8C12.5,300 0,287.2 0,271.5v-243C0,12.8 12.5,0 27.8,0h356.5C399.5,0 412,12.8 412,28.5v243.2C412,287.2 399.5,300 384.2,300z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M138,225.3h133.1c8,0 14.5,-6.5 14.5,-14.5V69c1.6,0 2.9,-1.3 2.9,-2.9V45.7c-1.9,-1.5 -3.8,-2.9 -5.8,-4.3v169.4c0,6.4 -5.2,11.6 -11.6,11.6H138c-6.4,0 -11.6,-5.2 -11.6,-11.6V43.5c-1,0.7 -1.9,1.5 -2.9,2.2v165C123.5,218.8 130,225.3 138,225.3z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M206,283.9c-73.9,0 -133.9,-60.1 -133.9,-133.9S132.1,16.1 206,16.1c73.9,0 133.9,60.1 133.9,133.9S279.9,283.9 206,283.9zM206,18.1C133.2,18.1 74.1,77.2 74.1,150S133.2,281.9 206,281.9S337.9,222.8 337.9,150S278.8,18.1 206,18.1z"
android:fillColor="#E8EAED"/>
<path
android:pathData="M229.9,207.9h-47.8c-1.1,0 -2,0.9 -2,2s0.9,2 2,2h47.8c1.1,0 2,-0.9 2,-2S231,207.9 229.9,207.9z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M190.9,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C194.1,208.4 192.8,206.5 190.9,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M208,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C211.2,208.4 209.9,206.5 208,205.7z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M225.1,205.7v-11.4h4.9l-6.9,-12.2l-6.9,12.2h4.9v11.4c-1.9,0.8 -3.2,2.6 -3.2,4.8c0,2.9 2.3,5.2 5.2,5.2c2.9,0 5.2,-2.3 5.2,-5.2C228.2,208.4 226.9,206.5 225.1,205.7z"
android:fillColor="#1A73E8"/>
</vector>

View File

@@ -1,64 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="412dp"
android:height="300dp"
android:viewportWidth="412"
android:viewportHeight="300">
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M176.84,188.94C173.14,188.94 170.24,191.94 170.24,195.54V220.14H183.54V195.54C183.54,191.94 180.54,188.94 176.84,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="176.89"
android:startY="220.23"
android:endX="176.89"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M206.14,188.94C202.44,188.94 199.54,191.94 199.54,195.54V220.14H212.84V195.54C212.74,191.94 209.84,188.94 206.14,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="206.19"
android:startY="220.23"
android:endX="206.19"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M235.44,188.94C231.74,188.94 228.84,191.94 228.84,195.54V220.14H242.14V195.54C242.04,191.94 239.14,188.94 235.44,188.94Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="235.49"
android:startY="220.23"
android:endX="235.49"
android:endY="188.97"
android:type="linear">
<item android:offset="0" android:color="#001A73E8"/>
<item android:offset="0.69" android:color="#FF1A73E8"/>
</gradient>
</aapt:attr>
</path>
</group>
<group>
<clip-path
android:pathData="M0,0h412v300h-412z"/>
<path
android:pathData="M263.59,50.35C263.59,48.98 264.7,47.86 266.06,47.86L287.85,47.86C289.22,47.86 290.33,48.98 290.33,50.35L277.45,51.34L263.59,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M364.52,66.19L364.52,236.14A14.75,14.75 0,0 1,349.77 250.89L62.23,250.89A14.75,14.75 0,0 1,47.48 236.14L47.48,66.19A14.75,14.75 0,0 1,62.23 51.44L349.77,51.44A14.75,14.75 0,0 1,364.52 66.19z"
android:strokeWidth="2.5"
android:fillColor="#ffffff"
android:strokeColor="#DADCE0"/>
<path
android:pathData="M311.45,50.35C311.45,48.98 312.56,47.86 313.92,47.86L322.84,47.86C324.2,47.86 325.32,48.98 325.32,50.35L319.37,51.34L311.45,50.35Z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M170.9,232.14L241.9,232.14A2,2 0,0 1,243.9 234.14L243.9,234.14A2,2 0,0 1,241.9 236.14L170.9,236.14A2,2 0,0 1,168.9 234.14L168.9,234.14A2,2 0,0 1,170.9 232.14z"
android:fillColor="#DADCE0"/>
<path
android:pathData="M188.7,229.14V217.74H193.6L186.7,205.54L179.8,217.74H184.7V229.14C182.8,229.94 181.5,231.74 181.5,233.94C181.5,236.84 183.8,239.14 186.7,239.14C189.6,239.14 191.9,236.84 191.9,233.94C191.9,231.84 190.5,229.94 188.7,229.14Z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M208,229.14V217.74H212.9L206,205.54L199.1,217.74H204V229.14C202.1,229.94 200.8,231.74 200.8,233.94C200.8,236.84 203.1,239.14 206,239.14C208.9,239.14 211.2,236.84 211.2,233.94C211.2,231.84 209.9,229.94 208,229.14Z"
android:fillColor="#1A73E8"/>
<path
android:pathData="M227.29,229.14V217.74H232.2L225.29,205.54L218.4,217.74H223.29V229.14C221.4,229.94 220.1,231.74 220.1,233.94C220.1,236.84 222.4,239.14 225.29,239.14C228.2,239.14 230.49,236.84 230.49,233.94C230.49,231.84 229.2,229.94 227.29,229.14Z"
android:fillColor="#1A73E8"/>
</group>
</vector>

View File

@@ -695,20 +695,4 @@
<!-- Whether auto data switching on secondary SIM enables cross-SIM calling on both SIMs. -->
<bool name="config_auto_data_switch_enables_cross_sim_calling">false</bool>
<!-- The illustration for those screen are not in one of below type. This file should be a video in JSON format. -->
<item name="a11y_timeout_banner" type="raw" product="default">@raw/accessibility_timeout_banner</item>
<item name="a11y_timeout_banner" type="raw" product="tablet">@raw/accessibility_timeout_banner_tablet</item>
<item name="a11y_shortcut_type_triple_tap" type="raw" product="default">@raw/accessibility_shortcut_type_triple_tap</item>
<item name="a11y_shortcut_type_triple_tap" type="raw" product="tablet">@raw/accessibility_shortcut_type_triple_tap_tablet</item>
<item name="a11y_color_inversion_banner" type="raw" product="default">@raw/accessibility_color_inversion_banner</item>
<item name="a11y_color_inversion_banner" type="raw" product="tablet">@raw/accessibility_color_inversion_banner_tablet</item>
<item name="a11y_magnification_banner" type="raw" product="default">@raw/accessibility_magnification_banner</item>
<item name="a11y_magnification_banner" type="raw" product="tablet">@raw/accessibility_magnification_banner_tablet</item>
<item name="a11y_extra_dim_banner" type="raw" product="default">@raw/extra_dim_banner</item>
<item name="a11y_extra_dim_banner" type="raw" product="tablet">@raw/extra_dim_banner_tablet</item>
</resources>

View File

@@ -230,8 +230,8 @@ public final class AccessibilityGestureNavigationTutorial {
final ImageView imageView = view.findViewById(R.id.image);
final int gestureSettingsImageResId =
isTouchExploreEnabled ? R.drawable.illustration_accessibility_gesture_three_finger
: R.drawable.illustration_accessibility_gesture_two_finger;
isTouchExploreEnabled ? R.drawable.a11y_gesture_navigation_three_finger_preview
: R.drawable.a11y_gesture_navigation_two_finger_preview;
imageView.setImageResource(gestureSettingsImageResId);
final TextView textView = view.findViewById(R.id.gesture_tutorial_message);

View File

@@ -16,8 +16,12 @@
package com.android.settings.biometrics2.data.repository;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
/**
* This repository is used to call all APIs in {@link AccessibilityManager}
*/
@@ -44,4 +48,21 @@ public class AccessibilityRepository {
public boolean isEnabled() {
return mAccessibilityManager.isEnabled();
}
/**
* Sends an {@link AccessibilityEvent}.
*
* @param event The event to send.
*
* @throws IllegalStateException if accessibility is not enabled.
*
* <strong>Note:</strong> The preferred mechanism for sending custom accessibility
* events is through calling
* {@link android.view.ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
* instead of this method to allow predecessors to augment/filter events sent by
* their descendants.
*/
public void sendAccessibilityEvent(@NonNull AccessibilityEvent event) {
mAccessibilityManager.sendAccessibilityEvent(event);
}
}

View File

@@ -410,12 +410,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
}
}
@Override
public void onDestroy() {
// TODO stopListenOrientationEvent();
super.onDestroy();
}
private void animateProgress(int progress) {
if (mProgressAnim != null) {
mProgressAnim.cancel();

View File

@@ -27,35 +27,34 @@ import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.RelativeLayout;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.transition.Transition;
import androidx.transition.TransitionSet;
import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog;
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel;
import com.android.settingslib.display.DisplayDensityUtils;
import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieCompositionFactory;
@@ -73,8 +72,10 @@ import com.google.android.setupdesign.template.HeaderMixin;
public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
private static final String TAG = FingerprintEnrollEnrollingSfpsFragment.class.getSimpleName();
private static final boolean DEBUG = false;
private static final int PROGRESS_BAR_MAX = 10000;
private static final long ANIMATION_DURATION = 250L;
private static final long ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN = 500;
private static final int ICON_TOUCH_COUNT_SHOW_UNTIL_DIALOG_SHOWN = 3;
@@ -86,101 +87,75 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
private static final int SFPS_STAGE_RIGHT_EDGE = 4;
private FingerprintEnrollEnrollingViewModel mEnrollingViewModel;
private DeviceRotationViewModel mRotationViewModel;
private FingerprintEnrollProgressViewModel mProgressViewModel;
private Interpolator mFastOutSlowInInterpolator;
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
private boolean mAnimationCancelled;
private GlifLayout mView;
private ProgressBar mProgressBar;
private ObjectAnimator mProgressAnim;
private TextView mErrorText;
private FooterBarMixin mFooterBarMixin;
private AnimatedVectorDrawable mIconAnimationDrawable;
private AnimatedVectorDrawable mIconBackgroundBlinksDrawable;
private LottieAnimationView mIllustrationLottie;
private boolean mShouldShowLottie;
private boolean mIsAccessibilityEnabled;
private boolean mHaveShownSfpsNoAnimationLottie;
private boolean mHaveShownSfpsCenterLottie;
private boolean mHaveShownSfpsTipLottie;
private boolean mHaveShownSfpsLeftEdgeLottie;
private boolean mHaveShownSfpsRightEdgeLottie;
private ObjectAnimator mHelpAnimation;
private int mIconTouchCount;
private final View.OnClickListener mOnSkipClickListener =
(v) -> mEnrollingViewModel.onCancelledDueToOnSkipPressed();
private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
// TODO
};
private final Observer<EnrollmentStatusMessage> mHelpMessageObserver = helpMessage -> {
// TODO
};
private final Observer<EnrollmentStatusMessage> mErrorMessageObserver = errorMessage -> {
// TODO
};
private final Observer<Boolean> mAcquireObserver = isAcquiredGood -> {
// TODO
};
private final Observer<Integer> mPointerDownObserver = sensorId -> {
// TODO
};
private final Observer<Integer> mPointerUpObserver = sensorId -> {
// TODO
if (DEBUG) {
Log.d(TAG, "mProgressObserver(" + progress + ")");
}
if (progress != null && progress.getSteps() >= 0) {
onEnrollmentProgressChange(progress);
}
};
private int mIconTouchCount;
private final Observer<EnrollmentStatusMessage> mHelpMessageObserver = helpMessage -> {
if (DEBUG) {
Log.d(TAG, "mHelpMessageObserver(" + helpMessage + ")");
}
if (helpMessage != null) {
onEnrollmentHelp(helpMessage);
}
};
private final Observer<EnrollmentStatusMessage> mErrorMessageObserver = errorMessage -> {
if (DEBUG) {
Log.d(TAG, "mErrorMessageObserver(" + errorMessage + ")");
}
if (errorMessage != null) {
onEnrollmentError(errorMessage);
}
};
@Override
public void onAttach(@NonNull Context context) {
final FragmentActivity activity = getActivity();
final ViewModelProvider provider = new ViewModelProvider(activity);
mEnrollingViewModel = provider.get(FingerprintEnrollEnrollingViewModel.class);
mRotationViewModel = provider.get(DeviceRotationViewModel.class);
mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class);
super.onAttach(context);
final TransitionSet transitionSet = (TransitionSet) getSharedElementEnterTransition();
if (transitionSet != null) {
transitionSet.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(@NonNull Transition transition) {
}
@Override
public void onTransitionEnd(@NonNull Transition transition) {
transition.removeListener(this);
mAnimationCancelled = false;
startIconAnimation();
}
@Override
public void onTransitionCancel(@NonNull Transition transition) {
}
@Override
public void onTransitionPause(@NonNull Transition transition) {
}
@Override
public void onTransitionResume(@NonNull Transition transition) {
}
});
}
requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(false);
mEnrollingViewModel.setOnBackPressed();
cancelEnrollment();
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mEnrollingViewModel.restoreSavedState(savedInstanceState);
mIsAccessibilityEnabled = mEnrollingViewModel.isAccessibilityEnabled();
}
@Override
@@ -193,6 +168,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = initSfpsLayout(inflater, container);
maybeHideSfpsText(getActivity().getResources().getConfiguration());
return mView;
}
@@ -204,13 +180,22 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
new GlifLayoutHelper(activity, containView).setDescriptionText(
getString(R.string.security_settings_fingerprint_enroll_start_message));
mShouldShowLottie = shouldShowLottie(); // Move shouldShowLottie into updateOrientation()?
// setHelpAnimation()
final float translationX = 40;
final int duration = 550;
final RelativeLayout progressLottieLayout = containView.findViewById(R.id.progress_lottie);
mHelpAnimation = ObjectAnimator.ofFloat(progressLottieLayout,
"translationX" /* propertyName */,
0, translationX, -1 * translationX, translationX, 0f);
mHelpAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
mHelpAnimation.setDuration(duration);
mHelpAnimation.setAutoCancel(false);
mIllustrationLottie = containView.findViewById(R.id.illustration_lottie);
mErrorText = containView.findViewById(R.id.error_text);
mProgressBar = containView.findViewById(R.id.fingerprint_progress_bar);
mFooterBarMixin = containView.getMixin(FooterBarMixin.class);
mFooterBarMixin.setSecondaryButton(
final FooterBarMixin footerBarMixin = containView.getMixin(FooterBarMixin.class);
footerBarMixin.setSecondaryButton(
new FooterButton.Builder(activity)
.setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
.setListener(mOnSkipClickListener)
@@ -221,10 +206,6 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
activity, android.R.interpolator.fast_out_slow_in);
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
activity, android.R.interpolator.linear_out_slow_in);
mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(
activity, android.R.interpolator.fast_out_linear_in);
mProgressBar.setProgressBackgroundTintMode(PorterDuff.Mode.SRC);
mProgressBar.setOnTouchListener((v, event) -> {
@@ -243,7 +224,6 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
return true;
});
maybeHideSfpsText(activity.getResources().getConfiguration());
return containView;
}
@@ -251,46 +231,135 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
public void onStart() {
super.onStart();
startEnrollment();
updateProgress(false /* animate */);
updateTitleAndDescription(new GlifLayoutHelper(getActivity(), mView));
if (true /* TODO mRestoring */) {
startIconAnimation();
}
updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue());
updateTitleAndDescription();
}
@Override
public void onStop() {
stopIconAnimation();
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver);
mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver);
mProgressViewModel.getAcquireLiveData().removeObserver(mAcquireObserver);
mProgressViewModel.getPointerDownLiveData().removeObserver(mPointerDownObserver);
mProgressViewModel.getPointerUpLiveData().removeObserver(mPointerUpObserver);
if (!getActivity().isChangingConfigurations()) {
removeEnrollmentObservers();
if (!getActivity().isChangingConfigurations() && mProgressViewModel.isEnrolling()) {
mProgressViewModel.cancelEnrollment();
}
super.onStop();
}
private void removeEnrollmentObservers() {
preRemoveEnrollmentObservers();
mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver);
}
private void preRemoveEnrollmentObservers() {
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver);
}
private void cancelEnrollment() {
preRemoveEnrollmentObservers();
mProgressViewModel.cancelEnrollment();
}
private void startEnrollment() {
final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_ENROLL);
if (!startResult) {
Log.e(TAG, "startEnrollment(), failed");
}
mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().observe(this, mHelpMessageObserver);
mProgressViewModel.getErrorMessageLiveData().observe(this, mErrorMessageObserver);
mProgressViewModel.getAcquireLiveData().observe(this, mAcquireObserver);
mProgressViewModel.getPointerDownLiveData().observe(this, mPointerDownObserver);
mProgressViewModel.getPointerUpLiveData().observe(this, mPointerUpObserver);
mProgressViewModel.startEnrollment(ENROLL_ENROLL);
}
private void updateProgress(boolean animate) {
private void configureEnrollmentStage(CharSequence description, @RawRes int lottie) {
new GlifLayoutHelper(getActivity(), mView).setDescriptionText(description);
LottieCompositionFactory.fromRawRes(getActivity(), lottie)
.addListener((c) -> {
mIllustrationLottie.setComposition(c);
mIllustrationLottie.setVisibility(View.VISIBLE);
mIllustrationLottie.playAnimation();
});
}
private int getCurrentSfpsStage() {
EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue();
if (progressLiveData == null) {
return STAGE_UNKNOWN;
}
final int progressSteps = progressLiveData.getSteps() - progressLiveData.getRemaining();
if (progressSteps < getStageThresholdSteps(0)) {
return SFPS_STAGE_NO_ANIMATION;
} else if (progressSteps < getStageThresholdSteps(1)) {
return SFPS_STAGE_CENTER;
} else if (progressSteps < getStageThresholdSteps(2)) {
return SFPS_STAGE_FINGERTIP;
} else if (progressSteps < getStageThresholdSteps(3)) {
return SFPS_STAGE_LEFT_EDGE;
} else {
return SFPS_STAGE_RIGHT_EDGE;
}
}
private void onEnrollmentHelp(@NonNull EnrollmentStatusMessage helpMessage) {
final CharSequence helpStr = helpMessage.getStr();
if (!TextUtils.isEmpty(helpStr)) {
showError(helpStr);
}
}
private void onEnrollmentError(@NonNull EnrollmentStatusMessage errorMessage) {
removeEnrollmentObservers();
if (mEnrollingViewModel.getOnBackPressed()
&& errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
mEnrollingViewModel.onCancelledDueToOnBackPressed();
} else if (mEnrollingViewModel.getOnSkipPressed()
&& errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
mEnrollingViewModel.onCancelledDueToOnSkipPressed();
} else {
final int errMsgId = errorMessage.getMsgId();
mEnrollingViewModel.showErrorDialog(
new FingerprintEnrollEnrollingViewModel.ErrorDialogData(
getString(FingerprintErrorDialog.getErrorMessage(errMsgId)),
getString(FingerprintErrorDialog.getErrorTitle(errMsgId)),
errMsgId
));
mProgressViewModel.cancelEnrollment();
}
}
private void announceEnrollmentProgress(CharSequence announcement) {
AccessibilityEvent event = new AccessibilityEvent();
event.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
event.setClassName(getClass().getName());
event.setPackageName(getClass().getPackageName());
event.getText().add(announcement);
mEnrollingViewModel.sendAccessibilityEvent(event);
}
private void onEnrollmentProgressChange(@NonNull EnrollmentProgress progress) {
updateProgress(true /* animate */, progress);
if (mEnrollingViewModel.isAccessibilityEnabled()) {
final int percent = (int) (((float) (progress.getSteps() - progress.getRemaining())
/ (float) progress.getSteps()) * 100);
CharSequence announcement = getString(
R.string.security_settings_sfps_enroll_progress_a11y_message, percent);
announceEnrollmentProgress(announcement);
mIllustrationLottie.setContentDescription(
getString(R.string.security_settings_sfps_animation_a11y_label, percent)
);
}
updateTitleAndDescription();
}
private void updateProgress(boolean animate, @NonNull EnrollmentProgress enrollmentProgress) {
if (!mProgressViewModel.isEnrolling()) {
Log.d(TAG, "Enrollment not started yet");
return;
}
final EnrollmentProgress enrollmentProgress =
mProgressViewModel.getProgressLiveData().getValue();
final int progress = getProgress(enrollmentProgress);
// Only clear the error when progress has been made.
// TODO (b/234772728) Add tests.
@@ -318,19 +387,43 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
return PROGRESS_BAR_MAX * displayProgress / (progress.getSteps() + 1);
}
private void showError(CharSequence error) {
mView.setHeaderText(error);
mView.getHeaderTextView().setContentDescription(error);
new GlifLayoutHelper(getActivity(), mView).setDescriptionText("");
if (!mHelpAnimation.isRunning()) {
mHelpAnimation.start();
}
applySfpsErrorDynamicColors(true);
if (isResumed() && mEnrollingViewModel.isAccessibilityEnabled()) {
mEnrollingViewModel.vibrateError(getClass().getSimpleName() + "::showError");
}
}
private void clearError() {
applySfpsErrorDynamicColors(false);
}
private void animateProgress(int progress) {
if (mProgressAnim != null) {
mProgressAnim.cancel();
}
ObjectAnimator anim = ObjectAnimator.ofInt(mProgressBar, "progress",
mProgressBar.getProgress(), progress);
anim.addListener(mProgressAnimationListener);
anim.setInterpolator(mFastOutSlowInInterpolator);
anim.setDuration(ANIMATION_DURATION);
anim.start();
mProgressAnim = anim;
}
/**
* Applies dynamic colors corresponding to showing or clearing errors on the progress bar
* and finger lottie for SFPS
*/
private void applySfpsErrorDynamicColors(boolean isError) {
applyProgressBarDynamicColor(isError);
if (mIllustrationLottie != null) {
applyLottieDynamicColor(isError);
}
applyLottieDynamicColor(isError);
}
private void applyProgressBarDynamicColor(boolean isError) {
@@ -358,36 +451,39 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
mIllustrationLottie.invalidate();
}
@Override
public void onDestroy() {
// TODO stopListenOrientationEvent();
super.onDestroy();
}
private int getStageThresholdSteps(int index) {
final EnrollmentProgress progressLiveData =
mProgressViewModel.getProgressLiveData().getValue();
private void animateProgress(int progress) {
if (mProgressAnim != null) {
mProgressAnim.cancel();
if (progressLiveData == null || progressLiveData.getSteps() == -1) {
Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet");
return 1;
}
ObjectAnimator anim = ObjectAnimator.ofInt(mProgressBar, "progress",
mProgressBar.getProgress(), progress);
anim.addListener(mProgressAnimationListener);
anim.setInterpolator(mFastOutSlowInInterpolator);
anim.setDuration(250);
anim.start();
mProgressAnim = anim;
return Math.round(progressLiveData.getSteps()
* mEnrollingViewModel.getEnrollStageThreshold(index));
}
private void updateTitleAndDescription(@NonNull GlifLayoutHelper glifLayoutHelper) {
if (mIsAccessibilityEnabled) {
private void updateTitleAndDescription() {
final GlifLayoutHelper glifLayoutHelper = new GlifLayoutHelper(getActivity(), mView);
if (mEnrollingViewModel.isAccessibilityEnabled()) {
mEnrollingViewModel.clearTalkback();
glifLayoutHelper.getGlifLayout().getDescriptionTextView().setAccessibilityLiveRegion(
View.ACCESSIBILITY_LIVE_REGION_POLITE);
}
switch (getCurrentSfpsStage()) {
final int stage = getCurrentSfpsStage();
if (DEBUG) {
Log.d(TAG, "updateTitleAndDescription, stage:" + stage
+ ", noAnimation:" + mHaveShownSfpsNoAnimationLottie
+ ", center:" + mHaveShownSfpsCenterLottie
+ ", tip:" + mHaveShownSfpsTipLottie
+ ", leftEdge:" + mHaveShownSfpsLeftEdgeLottie
+ ", rightEdge:" + mHaveShownSfpsRightEdgeLottie);
}
switch (stage) {
case SFPS_STAGE_NO_ANIMATION:
glifLayoutHelper.setHeaderText(
R.string.security_settings_fingerprint_enroll_repeat_title);
if (!mHaveShownSfpsNoAnimationLottie && mIllustrationLottie != null) {
if (!mHaveShownSfpsNoAnimationLottie) {
mHaveShownSfpsNoAnimationLottie = true;
mIllustrationLottie.setContentDescription(
getString(
@@ -405,7 +501,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
case SFPS_STAGE_CENTER:
glifLayoutHelper.setHeaderText(
R.string.security_settings_sfps_enroll_finger_center_title);
if (!mHaveShownSfpsCenterLottie && mIllustrationLottie != null) {
if (!mHaveShownSfpsCenterLottie) {
mHaveShownSfpsCenterLottie = true;
configureEnrollmentStage(
getString(R.string.security_settings_sfps_enroll_start_message),
@@ -417,7 +513,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
case SFPS_STAGE_FINGERTIP:
glifLayoutHelper.setHeaderText(
R.string.security_settings_sfps_enroll_fingertip_title);
if (!mHaveShownSfpsTipLottie && mIllustrationLottie != null) {
if (!mHaveShownSfpsTipLottie) {
mHaveShownSfpsTipLottie = true;
configureEnrollmentStage("", R.raw.sfps_lottie_tip);
}
@@ -426,7 +522,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
case SFPS_STAGE_LEFT_EDGE:
glifLayoutHelper.setHeaderText(
R.string.security_settings_sfps_enroll_left_edge_title);
if (!mHaveShownSfpsLeftEdgeLottie && mIllustrationLottie != null) {
if (!mHaveShownSfpsLeftEdgeLottie) {
mHaveShownSfpsLeftEdgeLottie = true;
configureEnrollmentStage("", R.raw.sfps_lottie_left_edge);
}
@@ -435,7 +531,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
case SFPS_STAGE_RIGHT_EDGE:
glifLayoutHelper.setHeaderText(
R.string.security_settings_sfps_enroll_right_edge_title);
if (!mHaveShownSfpsRightEdgeLottie && mIllustrationLottie != null) {
if (!mHaveShownSfpsRightEdgeLottie) {
mHaveShownSfpsRightEdgeLottie = true;
configureEnrollmentStage("", R.raw.sfps_lottie_right_edge);
}
@@ -460,7 +556,38 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
}
}
private void maybeHideSfpsText(@android.annotation.NonNull Configuration newConfig) {
private void showIconTouchDialog() {
mIconTouchCount = 0;
//TODO EnrollingActivity should observe live data and add dialog fragment
mEnrollingViewModel.onIconTouchDialogShow();
}
private final Runnable mShowDialogRunnable = () -> showIconTouchDialog();
private final Animator.AnimatorListener mProgressAnimationListener =
new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) { }
@Override
public void onAnimationRepeat(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) {
if (mProgressBar.getProgress() >= PROGRESS_BAR_MAX) {
mProgressBar.postDelayed(mDelayedFinishRunnable, ANIMATION_DURATION);
}
}
@Override
public void onAnimationCancel(Animator animation) { }
};
// Give the user a chance to see progress completed before jumping to the next stage.
private final Runnable mDelayedFinishRunnable = () -> mEnrollingViewModel.onEnrollingDone();
private void maybeHideSfpsText(@NonNull Configuration newConfig) {
final HeaderMixin headerMixin = ((GlifLayout) mView).getMixin(HeaderMixin.class);
final DescriptionMixin descriptionMixin = ((GlifLayout) mView).getMixin(
DescriptionMixin.class);
@@ -480,137 +607,4 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
}
}
private int getCurrentSfpsStage() {
EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue();
if (progressLiveData == null || progressLiveData.getSteps() == -1) {
return STAGE_UNKNOWN;
}
final int progressSteps = progressLiveData.getSteps() - progressLiveData.getRemaining();
if (progressSteps < getStageThresholdSteps(0)) {
return SFPS_STAGE_NO_ANIMATION;
} else if (progressSteps < getStageThresholdSteps(1)) {
return SFPS_STAGE_CENTER;
} else if (progressSteps < getStageThresholdSteps(2)) {
return SFPS_STAGE_FINGERTIP;
} else if (progressSteps < getStageThresholdSteps(3)) {
return SFPS_STAGE_LEFT_EDGE;
} else {
return SFPS_STAGE_RIGHT_EDGE;
}
}
private int getStageThresholdSteps(int index) {
final EnrollmentProgress progressLiveData =
mProgressViewModel.getProgressLiveData().getValue();
if (progressLiveData == null || progressLiveData.getSteps() == -1) {
Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet");
return 1;
}
return Math.round(progressLiveData.getSteps()
* mEnrollingViewModel.getEnrollStageThreshold(index));
}
private void updateOrientation() {
mIllustrationLottie = mView.findViewById(R.id.illustration_lottie);
}
private boolean shouldShowLottie() {
DisplayDensityUtils displayDensity = new DisplayDensityUtils(getContext());
int currentDensityIndex = displayDensity.getCurrentIndexForDefaultDisplay();
final int currentDensity = displayDensity.getDefaultDisplayDensityValues()
[currentDensityIndex];
final int defaultDensity = displayDensity.getDefaultDensityForDefaultDisplay();
return defaultDensity == currentDensity;
}
private void startIconAnimation() {
if (mIconAnimationDrawable != null) {
mIconAnimationDrawable.start();
}
}
private void stopIconAnimation() {
mAnimationCancelled = true;
if (mIconAnimationDrawable != null) {
mIconAnimationDrawable.stop();
}
}
private void showIconTouchDialog() {
mIconTouchCount = 0;
//TODO EnrollingActivity should observe live data and add dialog fragment
mEnrollingViewModel.onIconTouchDialogShow();
}
private void configureEnrollmentStage(CharSequence description, @RawRes int lottie) {
new GlifLayoutHelper(getActivity(), mView).setDescriptionText(description);
LottieCompositionFactory.fromRawRes(getActivity(), lottie)
.addListener((c) -> {
mIllustrationLottie.setComposition(c);
mIllustrationLottie.setVisibility(View.VISIBLE);
mIllustrationLottie.playAnimation();
});
}
private final Runnable mShowDialogRunnable = new Runnable() {
@Override
public void run() {
showIconTouchDialog();
}
};
private final Animator.AnimatorListener mProgressAnimationListener =
new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
startIconAnimation();
}
@Override
public void onAnimationRepeat(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) {
stopIconAnimation();
if (mProgressBar.getProgress() >= PROGRESS_BAR_MAX) {
mProgressBar.postDelayed(mDelayedFinishRunnable, 250L);
}
}
@Override
public void onAnimationCancel(Animator animation) { }
};
// Give the user a chance to see progress completed before jumping to the next stage.
private final Runnable mDelayedFinishRunnable = new Runnable() {
@Override
public void run() {
/* TODO launchFinish(); */
}
};
private final Animatable2.AnimationCallback mIconAnimationCallback =
new Animatable2.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable d) {
if (mAnimationCancelled) {
return;
}
// Start animation after it has ended.
mProgressBar.post(new Runnable() {
@Override
public void run() {
startIconAnimation();
}
});
}
};
}

View File

@@ -25,6 +25,7 @@ import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
@@ -32,6 +33,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
@@ -39,6 +41,7 @@ import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation;
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel;
@@ -67,12 +70,23 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
private FingerprintEnrollFindSensorViewModel mViewModel;
private FingerprintEnrollProgressViewModel mProgressViewModel;
private DeviceRotationViewModel mRotationViewModel;
private View mView;
private GlifLayout mGlifLayout;
private FooterBarMixin mFooterBarMixin;
private final OnClickListener mOnSkipClickListener = (v) -> mViewModel.onSkipButtonClick();
@Nullable private FingerprintFindSensorAnimation mAnimation;
@Surface.Rotation private int mLastRotation = -1;
private final Observer<Integer> mRotationObserver = rotation -> {
if (DEBUG) {
Log.d(TAG, "rotationObserver " + rotation);
}
if (rotation != null) {
onRotationChanged(rotation);
}
};
private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
if (DEBUG) {
@@ -85,15 +99,10 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
private final Observer<EnrollmentStatusMessage> mLastCancelMessageObserver = errorMessage -> {
if (DEBUG) {
Log.d(TAG, "mErrorMessageObserver(" + errorMessage + ")");
Log.d(TAG, "mLastCancelMessageObserver(" + errorMessage + ")");
}
if (errorMessage != null) {
if (errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
mProgressViewModel.clearProgressLiveData();
mViewModel.onStartButtonClick();
} else {
Log.e(TAG, "mErrorMessageObserver(" + errorMessage + ")");
}
onLastCancelMessage(errorMessage);
}
};
@@ -144,6 +153,10 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
@Override
public void onResume() {
final LiveData<Integer> rotationLiveData = mRotationViewModel.getLiveData();
mLastRotation = rotationLiveData.getValue();
rotationLiveData.observe(this, mRotationObserver);
if (mAnimation != null) {
if (DEBUG) {
Log.d(TAG, "onResume(), start animation");
@@ -198,15 +211,39 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
return;
}
if (waitForLastCancelErrMsg) {
mProgressViewModel.clearErrorMessageLiveData(); // Prevent got previous error message
mProgressViewModel.getErrorMessageLiveData().observe(this,
mLastCancelMessageObserver);
}
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
final boolean cancelResult = mProgressViewModel.cancelEnrollment();
if (!cancelResult) {
Log.e(TAG, "stopLookingForFingerprint(), failed to cancel enrollment");
}
}
if (waitForLastCancelErrMsg) {
mProgressViewModel.getErrorMessageLiveData().observe(this,
mLastCancelMessageObserver);
private void onRotationChanged(@Surface.Rotation int newRotation) {
if (DEBUG) {
Log.d(TAG, "onRotationChanged() from " + mLastRotation + " to " + newRotation);
}
if (newRotation % 2 != mLastRotation % 2) {
// Fragment is going to be recreated, just stopLookingForFingerprint() here.
stopLookingForFingerprint(true);
}
}
private void onLastCancelMessage(@NonNull EnrollmentStatusMessage errorMessage) {
if (errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
final EnrollmentProgress progress = mProgressViewModel.getProgressLiveData().getValue();
mProgressViewModel.clearProgressLiveData();
mProgressViewModel.getErrorMessageLiveData().removeObserver(mLastCancelMessageObserver);
if (progress != null && !progress.isInitialStep()) {
mViewModel.onStartButtonClick();
}
} else {
Log.e(TAG, "mErrorMessageObserver(" + errorMessage + ")");
}
}
@@ -227,6 +264,7 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
final ViewModelProvider provider = new ViewModelProvider(activity);
mViewModel = provider.get(FingerprintEnrollFindSensorViewModel.class);
mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class);
mRotationViewModel = provider.get(DeviceRotationViewModel.class);
super.onAttach(context);
}
}

View File

@@ -20,6 +20,7 @@ import static android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR
import android.app.Activity;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -39,6 +40,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.android.settings.R;
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel;
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
@@ -75,30 +77,36 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
private DeviceRotationViewModel mRotationViewModel;
private DeviceFoldedViewModel mFoldedViewModel;
private GlifLayout mView;
private FooterBarMixin mFooterBarMixin;
private final OnClickListener mOnSkipClickListener = (v) -> mViewModel.onSkipButtonClick();
private LottieAnimationView mIllustrationLottie;
@Surface.Rotation private int mAnimationRotation = -1;
private final Observer<Integer> mRotationObserver = rotation -> {
if (DEBUG) {
Log.d(TAG, "rotationObserver " + rotation);
}
if (rotation == null) {
return;
if (rotation != null) {
onRotationChanged(rotation);
}
onRotationChanged(rotation);
};
@Surface.Rotation private int mAnimationRotation = -1;
private View mView;
private GlifLayout mGlifLayout;
private FooterBarMixin mFooterBarMixin;
private final OnClickListener mOnSkipClickListener = (v) -> mViewModel.onSkipButtonClick();
private LottieAnimationView mIllustrationLottie;
private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
if (DEBUG) {
Log.d(TAG, "mProgressObserver(" + progress + ")");
}
if (progress != null && !progress.isInitialStep()) {
mViewModel.onStartButtonClick();
stopLookingForFingerprint(true);
}
};
private final Observer<EnrollmentStatusMessage> mLastCancelMessageObserver = errorMessage -> {
if (DEBUG) {
Log.d(TAG, "mLastCancelMessageObserver(" + errorMessage + ")");
}
if (errorMessage != null) {
onLastCancelMessage(errorMessage);
}
};
@@ -107,10 +115,10 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
final Context context = inflater.getContext();
mView = inflater.inflate(R.layout.sfps_enroll_find_sensor_layout, container, false);
mGlifLayout = mView.findViewById(R.id.setup_wizard_layout);
mView = (GlifLayout) inflater.inflate(R.layout.sfps_enroll_find_sensor_layout, container,
false);
mIllustrationLottie = mView.findViewById(R.id.illustration_lottie);
mFooterBarMixin = mGlifLayout.getMixin(FooterBarMixin.class);
mFooterBarMixin = mView.getMixin(FooterBarMixin.class);
mFooterBarMixin.setSecondaryButton(
new FooterButton.Builder(context)
.setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
@@ -125,7 +133,7 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final Activity activity = getActivity();
final GlifLayoutHelper glifLayoutHelper = new GlifLayoutHelper(activity, mGlifLayout);
final GlifLayoutHelper glifLayoutHelper = new GlifLayoutHelper(activity, mView);
glifLayoutHelper.setHeaderText(R.string.security_settings_sfps_enroll_find_sensor_title);
glifLayoutHelper.setDescriptionText(
getText(R.string.security_settings_sfps_enroll_find_sensor_message));
@@ -136,10 +144,13 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
public void onStart() {
super.onStart();
final boolean isEnrolling = mProgressViewModel.isEnrolling();
if (DEBUG) {
Log.d(TAG, "onStart(), start looking for fingerprint");
Log.d(TAG, "onStart(), isEnrolling:" + isEnrolling);
}
if (!isEnrolling) {
startLookingForFingerprint();
}
startLookingForFingerprint();
}
@Override
@@ -159,10 +170,13 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
@Override
public void onStop() {
super.onStop();
final boolean isEnrolling = mProgressViewModel.isEnrolling();
if (DEBUG) {
Log.d(TAG, "onStop(), stop looking for fingerprint");
Log.d(TAG, "onStop(), isEnrolling:" + isEnrolling);
}
if (isEnrolling) {
stopLookingForFingerprint(false);
}
stopLookingForFingerprint();
}
private void startLookingForFingerprint() {
@@ -180,13 +194,19 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
}
}
private void stopLookingForFingerprint() {
private void stopLookingForFingerprint(boolean waitForLastCancelErrMsg) {
if (!mProgressViewModel.isEnrolling()) {
Log.d(TAG, "stopLookingForFingerprint(), failed because isEnrolling is false before"
+ " stopping");
return;
}
if (waitForLastCancelErrMsg) {
mProgressViewModel.clearErrorMessageLiveData(); // Prevent got previous error message
mProgressViewModel.getErrorMessageLiveData().observe(this,
mLastCancelMessageObserver);
}
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
final boolean cancelResult = mProgressViewModel.cancelEnrollment();
if (!cancelResult) {
@@ -199,10 +219,25 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
Log.d(TAG, "onRotationChanged() from " + mAnimationRotation + " to " + newRotation);
}
if ((newRotation + 2) % 4 == mAnimationRotation) {
// Fragment not changed, we just need to play correct rotation animation
playLottieAnimation(newRotation);
} else if (newRotation % 2 != mAnimationRotation % 2) {
// Fragment is going to be recreated, just stopLookingForFingerprint() here.
stopLookingForFingerprint(true);
}
}
private void onLastCancelMessage(@NonNull EnrollmentStatusMessage errorMessage) {
if (errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
final EnrollmentProgress progress = mProgressViewModel.getProgressLiveData().getValue();
mProgressViewModel.clearProgressLiveData();
mProgressViewModel.getErrorMessageLiveData().removeObserver(mLastCancelMessageObserver);
if (progress != null && !progress.isInitialStep()) {
mViewModel.onStartButtonClick();
}
} else {
Log.e(TAG, "mErrorMessageObserver(" + errorMessage + ")");
}
// Fragment will be re-created if it's changed between landscape and portrait, so no need to
// handle other cases.
}
private void playLottieAnimation(@Surface.Rotation int rotation) {

View File

@@ -23,6 +23,8 @@ import android.os.Bundle;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
@@ -278,6 +280,23 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
return mAccessibilityRepository.isEnabled();
}
/**
* Sends an {@link AccessibilityEvent}.
*
* @param event The event to send.
*
* @throws IllegalStateException if accessibility is not enabled.
*
* <strong>Note:</strong> The preferred mechanism for sending custom accessibility
* events is through calling
* {@link android.view.ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
* instead of this method to allow predecessors to augment/filter events sent by
* their descendants.
*/
public void sendAccessibilityEvent(@NonNull AccessibilityEvent event) {
mAccessibilityRepository.sendAccessibilityEvent(event);
}
/**
* Like {@link #vibrate(VibrationEffect, VibrationAttributes)}, but allows the
* caller to specify the vibration is owned by someone else and set a reason for vibration.

View File

@@ -92,6 +92,9 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
if (DEBUG) {
Log.d(TAG, "onEnrollmentError(" + errMsgId + ", " + errString + ")");
}
mErrorMessageLiveData.postValue(new EnrollmentStatusMessage(errMsgId, errString));
}
@@ -146,6 +149,13 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
mErrorMessageLiveData.setValue(null);
}
/**
* clear error message
*/
public void clearErrorMessageLiveData() {
mErrorMessageLiveData.setValue(null);
}
public LiveData<EnrollmentProgress> getProgressLiveData() {
return mProgressLiveData;
}

View File

@@ -27,6 +27,7 @@ import android.icu.util.MeasureUnit;
import android.net.NetworkPolicy;
import android.net.NetworkTemplate;
import android.os.Bundle;
import android.provider.Settings;
import android.text.method.NumberKeyListener;
import android.util.Log;
import android.view.LayoutInflater;
@@ -54,6 +55,7 @@ import com.android.settingslib.search.SearchIndexable;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Optional;
import java.util.TimeZone;
@SearchIndexable
@@ -115,6 +117,18 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements
Bundle args = getArguments();
mNetworkTemplate = args.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE);
if (mNetworkTemplate == null && getIntent() != null) {
mNetworkTemplate = getIntent().getParcelableExtra(Settings.EXTRA_NETWORK_TEMPLATE);
}
if (mNetworkTemplate == null) {
Optional<NetworkTemplate> mobileNetworkTemplateFromSim =
DataUsageUtils.getMobileNetworkTemplateFromSubId(context, getIntent());
if (mobileNetworkTemplateFromSim.isPresent()) {
mNetworkTemplate = mobileNetworkTemplateFromSim.get();
}
}
if (mNetworkTemplate == null) {
mNetworkTemplate = DataUsageUtils.getDefaultTemplate(context,
DataUsageUtils.getDefaultSubscriptionId(context));

View File

@@ -69,6 +69,7 @@ import com.android.settingslib.net.UidDetailProvider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* Panel showing data usage history across various networks, including options
@@ -266,6 +267,14 @@ public class DataUsageList extends DataUsageBaseFragment
mSubId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mTemplate = intent.getParcelableExtra(Settings.EXTRA_NETWORK_TEMPLATE);
if (mTemplate == null) {
Optional<NetworkTemplate> mobileNetworkTemplateFromSim =
DataUsageUtils.getMobileNetworkTemplateFromSubId(getContext(), getIntent());
if (mobileNetworkTemplateFromSim.isPresent()) {
mTemplate = mobileNetworkTemplateFromSim.get();
}
}
}
}

View File

@@ -22,11 +22,13 @@ import static android.telephony.TelephonyManager.SIM_STATE_READY;
import android.app.usage.NetworkStats.Bucket;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkTemplate;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -39,6 +41,7 @@ import com.android.settings.datausage.lib.DataUsageLib;
import com.android.settings.network.ProxySubscriptionManager;
import java.util.List;
import java.util.Optional;
/**
* Utility methods for data usage classes.
@@ -193,4 +196,22 @@ public final class DataUsageUtils extends com.android.settingslib.net.DataUsageU
}
}
/**
* Returns a mobile NetworkTemplate if EXTRA_SUB_ID of the Intent is available and the subId
* is valid & hasMobileData. Otherwise, returns empty data.
*/
public static Optional<NetworkTemplate> getMobileNetworkTemplateFromSubId(Context context,
Intent intent) {
if (intent == null || !intent.hasExtra(Settings.EXTRA_SUB_ID)) {
return Optional.empty();
}
int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
if (SubscriptionManager.isValidSubscriptionId(subId) && hasMobileData(context)) {
return Optional.of(DataUsageLib.getMobileTemplate(context, subId));
}
return Optional.empty();
}
}

View File

@@ -56,9 +56,11 @@ import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.content.PackageMonitor;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexableRaw;
@@ -85,6 +87,7 @@ import java.util.List;
/** Test for {@link AccessibilitySettings}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothUtils.class})
public class AccessibilitySettingsTest {
private static final String PACKAGE_NAME = "com.android.test";
private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service";
@@ -116,6 +119,8 @@ public class AccessibilitySettingsTest {
private ShadowAccessibilityManager mShadowAccessibilityManager;
@Mock
private AppOpsManager mAppOpsManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
private Lifecycle mLifecycle;
@@ -134,6 +139,7 @@ public class AccessibilitySettingsTest {
anyInt(), anyString())).thenReturn(AppOpsManager.MODE_ALLOWED);
mLifecycle = new Lifecycle(() -> mLifecycle);
when(mFragment.getSettingsLifecycle()).thenReturn(mLifecycle);
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
}
@Test