Merge "Only return true in getPageScrolls if it actually changes" into sc-dev
diff --git a/quickstep/res/drawable/bg_sandbox_close_button.xml b/quickstep/res/drawable/bg_sandbox_close_button.xml
new file mode 100644
index 0000000..2811071
--- /dev/null
+++ b/quickstep/res/drawable/bg_sandbox_close_button.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="#303030"/>
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/bg_sandbox_feedback.xml b/quickstep/res/drawable/bg_sandbox_feedback.xml
index 1b3265d..83a3dea 100644
--- a/quickstep/res/drawable/bg_sandbox_feedback.xml
+++ b/quickstep/res/drawable/bg_sandbox_feedback.xml
@@ -1,10 +1,20 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="394dp"
- android:height="172dp"
- android:viewportWidth="394"
- android:viewportHeight="172">
- <path
- android:pathData="M20,0L374,0A20,20 0,0 1,394 20L394,152A20,20 0,0 1,374 172L20,172A20,20 0,0 1,0 152L0,20A20,20 0,0 1,20 0z"
- android:fillColor="?android:attr/colorBackgroundFloating"
- android:fillAlpha="0.9"/>
-</vector>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="28dp"/>
+ <solid android:color="?android:attr/colorBackgroundFloating"/>
+</shape>
diff --git a/quickstep/res/drawable/close_icon.xml b/quickstep/res/drawable/close_icon.xml
new file mode 100644
index 0000000..07f4336
--- /dev/null
+++ b/quickstep/res/drawable/close_icon.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="#909090"
+ android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_action_button_background.xml b/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
index 3f3b288..6fc2b76 100644
--- a/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
+++ b/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
@@ -15,6 +15,6 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <corners android:radius="@dimen/default_dialog_corner_radius"/>
+ <corners android:radius="50dp"/>
<solid android:color="@color/gesture_tutorial_primary_color"/>
</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_back_left.xml b/quickstep/res/drawable/gesture_tutorial_back_left.xml
new file mode 100644
index 0000000..92ae202
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_back_left.xml
@@ -0,0 +1,559 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="892dp" android:width="412dp" android:viewportHeight="892" android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_7_G" android:translateX="206" android:translateY="446">
+ <path android:name="_R_G_L_7_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_6_G" android:pivotX="206" android:pivotY="446" android:scaleX="1" android:scaleY="1">
+ <group android:name="_R_G_L_6_G_L_3_G" android:translateX="206" android:translateY="446" android:scaleX="1.2" android:scaleY="1.2">
+ <path android:name="_R_G_L_6_G_L_3_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G">
+ <group android:name="_R_G_L_6_G_L_2_G_L_11_G" android:translateX="206" android:translateY="496.5">
+ <path android:name="_R_G_L_6_G_L_2_G_L_11_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M235.5 -452.14 C235.5,-452.14 235.5,452.14 235.5,452.14 C235.5,452.14 -235.5,452.14 -235.5,452.14 C-235.5,452.14 -235.5,-452.14 -235.5,-452.14 C-235.5,-452.14 235.5,-452.14 235.5,-452.14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_10_G" android:translateX="182.5" android:translateY="831">
+ <path android:name="_R_G_L_6_G_L_2_G_L_10_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_9_G" android:translateX="186" android:translateY="801">
+ <path android:name="_R_G_L_6_G_L_2_G_L_9_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -7 C162,-7 162,7 162,7 C162,9.21 160.21,11 158,11 C158,11 -158,11 -158,11 C-160.21,11 -162,9.21 -162,7 C-162,7 -162,-7 -162,-7 C-162,-9.21 -160.21,-11 -158,-11 C-158,-11 158,-11 158,-11 C160.21,-11 162,-9.21 162,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_8_G" android:translateX="119" android:translateY="755">
+ <path android:name="_R_G_L_6_G_L_2_G_L_8_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M95 -7 C95,-7 95,7 95,7 C95,9.21 93.21,11 91,11 C91,11 -91,11 -91,11 C-93.21,11 -95,9.21 -95,7 C-95,7 -95,-7 -95,-7 C-95,-9.21 -93.21,-11 -91,-11 C-91,-11 91,-11 91,-11 C93.21,-11 95,-9.21 95,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_7_G" android:translateX="182.5" android:translateY="725">
+ <path android:name="_R_G_L_6_G_L_2_G_L_7_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_6_G" android:translateX="197.5" android:translateY="695">
+ <path android:name="_R_G_L_6_G_L_2_G_L_6_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M173.5 -7 C173.5,-7 173.5,7 173.5,7 C173.5,9.21 171.71,11 169.5,11 C169.5,11 -169.5,11 -169.5,11 C-171.71,11 -173.5,9.21 -173.5,7 C-173.5,7 -173.5,-7 -173.5,-7 C-173.5,-9.21 -171.71,-11 -169.5,-11 C-169.5,-11 169.5,-11 169.5,-11 C171.71,-11 173.5,-9.21 173.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_5_G" android:translateX="192" android:translateY="665">
+ <path android:name="_R_G_L_6_G_L_2_G_L_5_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M168 -7 C168,-7 168,7 168,7 C168,9.21 166.21,11 164,11 C164,11 -164,11 -164,11 C-166.21,11 -168,9.21 -168,7 C-168,7 -168,-7 -168,-7 C-168,-9.21 -166.21,-11 -164,-11 C-164,-11 164,-11 164,-11 C166.21,-11 168,-9.21 168,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_4_G" android:translateX="105.5" android:translateY="360">
+ <path android:name="_R_G_L_6_G_L_2_G_L_4_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_3_G" android:translateX="47.5" android:translateY="360">
+ <path android:name="_R_G_L_6_G_L_2_G_L_3_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_2_G" android:translateX="142.5" android:translateY="328">
+ <path android:name="_R_G_L_6_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M118.5 -14 C118.5,-14 118.5,14 118.5,14 C118.5,16.21 116.71,18 114.5,18 C114.5,18 -114.5,18 -114.5,18 C-116.71,18 -118.5,16.21 -118.5,14 C-118.5,14 -118.5,-14 -118.5,-14 C-118.5,-16.21 -116.71,-18 -114.5,-18 C-114.5,-18 114.5,-18 114.5,-18 C116.71,-18 118.5,-16.21 118.5,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_1_G" android:translateX="186" android:translateY="284">
+ <path android:name="_R_G_L_6_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -14 C162,-14 162,14 162,14 C162,16.21 160.21,18 158,18 C158,18 -158,18 -158,18 C-160.21,18 -162,16.21 -162,14 C-162,14 -162,-14 -162,-14 C-162,-16.21 -160.21,-18 -158,-18 C-158,-18 158,-18 158,-18 C160.21,-18 162,-16.21 162,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_0_G" android:translateX="155" android:translateY="240">
+ <path android:name="_R_G_L_6_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M131 -14 C131,-14 131,14 131,14 C131,16.21 129.21,18 127,18 C127,18 -127,18 -127,18 C-129.21,18 -131,16.21 -131,14 C-131,14 -131,-14 -131,-14 C-131,-16.21 -129.21,-18 -127,-18 C-127,-18 127,-18 127,-18 C129.21,-18 131,-16.21 131,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G" android:translateX="24" android:translateY="390">
+ <group android:name="_R_G_L_6_G_L_1_G_L_7_G" android:translateX="182" android:translateY="120"/>
+ <group android:name="_R_G_L_6_G_L_1_G_L_6_G" android:translateX="182" android:translateY="120">
+ <path android:name="_R_G_L_6_G_L_1_G_L_6_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M182 -116 C182,-116 182,116 182,116 C182,118.21 180.21,120 178,120 C178,120 -178,120 -178,120 C-180.21,120 -182,118.21 -182,116 C-182,116 -182,-116 -182,-116 C-182,-118.21 -180.21,-120 -178,-120 C-178,-120 178,-120 178,-120 C180.21,-120 182,-118.21 182,-116c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_5_G" android:translateX="77.322" android:translateY="150.552">
+ <path android:name="_R_G_L_6_G_L_1_G_L_5_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_5_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_4_G" android:translateX="38.772" android:translateY="121.73">
+ <path android:name="_R_G_L_6_G_L_1_G_L_4_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_4_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_3_G" android:translateX="183" android:translateY="222">
+ <path android:name="_R_G_L_6_G_L_1_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_3_G_D_1_P_0" android:strokeColor="#9aa0a6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_2_G" android:translateX="265.619" android:translateY="162.331">
+ <path android:name="_R_G_L_6_G_L_1_G_L_2_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_2_G_D_1_P_0" android:strokeColor="#a8cbfe" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_1_G" android:translateX="319.271" android:translateY="37.945">
+ <path android:name="_R_G_L_6_G_L_1_G_L_1_G_D_0_P_0" android:fillColor="#feefc3" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.42 2.99 C14.95,-4.17 9.93,-11.31 2.21,-12.96 C-0.9,-13.62 -3.97,-13.3 -6.64,-12.2 C-6.58,-12.19 -6.53,-12.18 -6.48,-12.17 C-1.03,-11.01 2.52,-5.97 1.44,-0.92 C0.36,4.13 -4.94,7.28 -10.4,6.12 C-11.6,5.86 -12.7,5.42 -13.69,4.83 C-11.9,8.78 -8.15,11.93 -3.34,12.96 C4.38,14.61 11.88,10.14 13.42,2.99c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_0_G" android:translateX="179.5" android:translateY="73.351">
+ <path android:name="_R_G_L_6_G_L_1_G_L_0_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M51.08 -40.95 C51.08,-40.95 50.55,-42.54 50.55,-42.54 C50.55,-42.54 49.67,-41.13 49.67,-41.13 C49.67,-41.13 48.17,-41.21 48.17,-41.21 C48.17,-41.21 49.05,-39.8 49.05,-39.8 C49.05,-39.8 48.61,-38.22 48.61,-38.22 C48.61,-38.22 50.02,-38.74 50.02,-38.74 C50.02,-38.74 51.35,-37.69 51.35,-37.69 C51.35,-37.69 51.26,-39.45 51.26,-39.45 C51.26,-39.45 52.59,-40.42 52.59,-40.42 C52.59,-40.42 51.08,-40.95 51.08,-40.95c M8.78 30.58 C8.78,30.58 8.25,28.99 8.25,28.99 C8.25,28.99 7.37,30.4 7.37,30.4 C7.37,30.4 5.87,30.31 5.87,30.31 C5.87,30.31 6.75,31.72 6.75,31.72 C6.75,31.72 6.31,33.31 6.31,33.31 C6.31,33.31 7.72,32.78 7.72,32.78 C7.72,32.78 9.05,33.84 9.05,33.84 C9.05,33.84 8.96,32.08 8.96,32.08 C8.96,32.08 10.29,31.11 10.29,31.11 C10.29,31.11 8.78,30.58 8.78,30.58c M19.38 -61.67 C19.38,-61.67 18.94,-63.35 18.94,-63.35 C18.94,-63.35 17.97,-61.94 17.97,-61.94 C17.97,-61.94 16.47,-61.94 16.47,-61.94 C16.47,-61.94 17.35,-60.62 17.35,-60.62 C17.35,-60.62 16.91,-58.94 16.91,-58.94 C16.91,-58.94 18.41,-59.56 18.41,-59.56 C18.41,-59.56 19.65,-58.5 19.65,-58.5 C19.65,-58.5 19.56,-60.18 19.56,-60.18 C19.56,-60.18 20.88,-61.23 20.88,-61.23 C20.88,-61.23 19.38,-61.67 19.38,-61.67c M-32.98 35.08 C-32.98,35.08 -33.51,33.4 -33.51,33.4 C-33.51,33.4 -34.4,34.81 -34.4,34.81 C-34.4,34.81 -35.9,34.81 -35.9,34.81 C-35.9,34.81 -35.01,36.22 -35.01,36.22 C-35.01,36.22 -35.45,37.81 -35.45,37.81 C-35.45,37.81 -34.04,37.28 -34.04,37.28 C-34.04,37.28 -32.72,38.25 -32.72,38.25 C-32.72,38.25 -32.81,36.58 -32.81,36.58 C-32.81,36.58 -31.48,35.6 -31.48,35.6 C-31.48,35.6 -32.98,35.08 -32.98,35.08c M45.34 7.56 C45.34,7.56 44.81,5.97 44.81,5.97 C44.81,5.97 43.93,7.38 43.93,7.38 C43.93,7.38 42.34,7.3 42.34,7.3 C42.34,7.3 43.31,8.71 43.31,8.71 C43.31,8.71 42.87,10.29 42.87,10.29 C42.87,10.29 44.28,9.77 44.28,9.77 C44.28,9.77 45.52,10.82 45.52,10.82 C45.52,10.82 45.52,9.06 45.52,9.06 C45.52,9.06 46.76,8.09 46.76,8.09 C46.76,8.09 45.34,7.56 45.34,7.56c M-9.59 -41.67 C-9.59,-41.67 -10.12,-43.35 -10.12,-43.35 C-10.12,-43.35 -11,-41.94 -11,-41.94 C-11,-41.94 -12.5,-41.94 -12.5,-41.94 C-12.5,-41.94 -11.62,-40.62 -11.62,-40.62 C-11.62,-40.62 -12.06,-38.94 -12.06,-38.94 C-12.06,-38.94 -10.65,-39.56 -10.65,-39.56 C-10.65,-39.56 -9.32,-38.5 -9.32,-38.5 C-9.32,-38.5 -9.41,-40.26 -9.41,-40.26 C-9.41,-40.26 -8.09,-41.23 -8.09,-41.23 C-8.09,-41.23 -9.59,-41.67 -9.59,-41.67c M97.74 -23.97 C97.74,-23.97 97.03,-26.35 97.03,-26.35 C97.03,-26.35 95.8,-24.32 95.8,-24.32 C95.8,-24.32 93.5,-24.32 93.5,-24.32 C93.5,-24.32 94.91,-22.38 94.91,-22.38 C94.91,-22.38 94.21,-20 94.21,-20 C94.21,-20 96.33,-20.88 96.33,-20.88 C96.33,-20.88 98.09,-19.38 98.09,-19.38 C98.09,-19.38 98.09,-21.85 98.09,-21.85 C98.09,-21.85 99.86,-23.26 99.86,-23.26 C99.86,-23.26 97.74,-23.97 97.74,-23.97c M167.29 43.28 C167.29,43.28 166.67,40.9 166.67,40.9 C166.67,40.9 165.35,42.93 165.35,42.93 C165.35,42.93 163.14,42.93 163.14,42.93 C163.14,42.93 164.47,44.87 164.47,44.87 C164.47,44.87 163.76,47.25 163.76,47.25 C163.76,47.25 165.88,46.37 165.88,46.37 C165.88,46.37 167.73,47.87 167.73,47.87 C167.73,47.87 167.65,45.4 167.65,45.4 C167.65,45.4 169.5,43.98 169.5,43.98 C169.5,43.98 167.29,43.28 167.29,43.28c M-1.1 -1.79 C-1.1,-1.79 -1.72,-4.08 -1.72,-4.08 C-1.72,-4.08 -3.05,-2.14 -3.05,-2.14 C-3.05,-2.14 -5.25,-2.14 -5.25,-2.14 C-5.25,-2.14 -3.93,-0.11 -3.93,-0.11 C-3.93,-0.11 -4.64,2.18 -4.64,2.18 C-4.64,2.18 -2.52,1.38 -2.52,1.38 C-2.52,1.38 -0.66,2.8 -0.66,2.8 C-0.66,2.8 -0.75,0.41 -0.75,0.41 C-0.75,0.41 1.1,-1.08 1.1,-1.08 C1.1,-1.08 -1.1,-1.79 -1.1,-1.79c M-60.89 -5.23 C-60.89,-5.23 -61.59,-7.61 -61.59,-7.61 C-61.59,-7.61 -62.83,-5.58 -62.83,-5.58 C-62.83,-5.58 -65.13,-5.58 -65.13,-5.58 C-65.13,-5.58 -63.71,-3.64 -63.71,-3.64 C-63.71,-3.64 -64.42,-1.26 -64.42,-1.26 C-64.42,-1.26 -62.39,-2.14 -62.39,-2.14 C-62.39,-2.14 -60.53,-0.64 -60.53,-0.64 C-60.53,-0.64 -60.62,-3.11 -60.62,-3.11 C-60.62,-3.11 -58.77,-4.52 -58.77,-4.52 C-58.77,-4.52 -60.89,-5.23 -60.89,-5.23c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-51.26 -42.98 C-51.26,-42.98 -54.09,-45.01 -54.09,-45.01 C-54.09,-45.01 -53.91,-41.57 -53.91,-41.57 C-53.91,-41.57 -56.65,-39.54 -56.65,-39.54 C-56.65,-39.54 -53.38,-38.57 -53.38,-38.57 C-53.38,-38.57 -52.32,-35.3 -52.32,-35.3 C-52.32,-35.3 -50.38,-38.13 -50.38,-38.13 C-50.38,-38.13 -46.94,-38.22 -46.94,-38.22 C-46.94,-38.22 -49.05,-40.86 -49.05,-40.86 C-49.05,-40.86 -47.99,-44.21 -47.99,-44.21 C-47.99,-44.21 -51.26,-42.98 -51.26,-42.98c M-92.06 -47.92 C-92.06,-47.92 -92.59,-49.59 -92.59,-49.59 C-92.59,-49.59 -93.47,-48.18 -93.47,-48.18 C-93.47,-48.18 -95.06,-48.18 -95.06,-48.18 C-95.06,-48.18 -94.09,-46.86 -94.09,-46.86 C-94.09,-46.86 -94.53,-45.18 -94.53,-45.18 C-94.53,-45.18 -93.12,-45.8 -93.12,-45.8 C-93.12,-45.8 -91.88,-44.74 -91.88,-44.74 C-91.88,-44.74 -91.88,-46.42 -91.88,-46.42 C-91.88,-46.42 -90.65,-47.47 -90.65,-47.47 C-90.65,-47.47 -92.06,-47.92 -92.06,-47.92c M62.83 -13.34 C62.83,-13.34 62.39,-14.93 62.39,-14.93 C62.39,-14.93 61.5,-13.52 61.5,-13.52 C61.5,-13.52 59.91,-13.52 59.91,-13.52 C59.91,-13.52 60.89,-12.2 60.89,-12.2 C60.89,-12.2 60.36,-10.52 60.36,-10.52 C60.36,-10.52 61.86,-11.14 61.86,-11.14 C61.86,-11.14 63.09,-10.08 63.09,-10.08 C63.09,-10.08 63.09,-11.84 63.09,-11.84 C63.09,-11.84 64.33,-12.81 64.33,-12.81 C64.33,-12.81 62.83,-13.34 62.83,-13.34c M-155.99 -40.95 C-155.99,-40.95 -156.43,-42.54 -156.43,-42.54 C-156.43,-42.54 -157.32,-41.13 -157.32,-41.13 C-157.32,-41.13 -158.91,-41.21 -158.91,-41.21 C-158.91,-41.21 -157.93,-39.8 -157.93,-39.8 C-157.93,-39.8 -158.46,-38.22 -158.46,-38.22 C-158.46,-38.22 -156.96,-38.74 -156.96,-38.74 C-156.96,-38.74 -155.73,-37.69 -155.73,-37.69 C-155.73,-37.69 -155.73,-39.45 -155.73,-39.45 C-155.73,-39.45 -154.49,-40.42 -154.49,-40.42 C-154.49,-40.42 -155.99,-40.95 -155.99,-40.95c M141.24 26.52 C141.24,26.52 140.71,24.85 140.71,24.85 C140.71,24.85 139.83,26.26 139.83,26.26 C139.83,26.26 138.33,26.26 138.33,26.26 C138.33,26.26 139.21,27.67 139.21,27.67 C139.21,27.67 138.77,29.26 138.77,29.26 C138.77,29.26 140.18,28.73 140.18,28.73 C140.18,28.73 141.51,29.7 141.51,29.7 C141.51,29.7 141.42,28.02 141.42,28.02 C141.42,28.02 142.74,27.05 142.74,27.05 C142.74,27.05 141.24,26.52 141.24,26.52c M111.4 -51.27 C111.4,-51.27 110.95,-52.94 110.95,-52.94 C110.95,-52.94 110.07,-51.53 110.07,-51.53 C110.07,-51.53 108.48,-51.53 108.48,-51.53 C108.48,-51.53 109.45,-50.21 109.45,-50.21 C109.45,-50.21 108.92,-48.53 108.92,-48.53 C108.92,-48.53 110.42,-49.15 110.42,-49.15 C110.42,-49.15 111.66,-48.09 111.66,-48.09 C111.66,-48.09 111.66,-49.86 111.66,-49.86 C111.66,-49.86 112.9,-50.83 112.9,-50.83 C112.9,-50.83 111.4,-51.27 111.4,-51.27c M-66.59 53.33 C-66.59,53.33 -67.03,51.65 -67.03,51.65 C-67.03,51.65 -67.91,53.06 -67.91,53.06 C-67.91,53.06 -69.5,53.06 -69.5,53.06 C-69.5,53.06 -68.53,54.47 -68.53,54.47 C-68.53,54.47 -69.06,56.06 -69.06,56.06 C-69.06,56.06 -67.56,55.53 -67.56,55.53 C-67.56,55.53 -66.32,56.5 -66.32,56.5 C-66.32,56.5 -66.32,54.82 -66.32,54.82 C-66.32,54.82 -65.08,53.77 -65.08,53.77 C-65.08,53.77 -66.59,53.33 -66.59,53.33c M-50.59 59.33 C-50.59,59.33 -51.12,57.65 -51.12,57.65 C-51.12,57.65 -52,59.06 -52,59.06 C-52,59.06 -53.5,59.06 -53.5,59.06 C-53.5,59.06 -52.62,60.38 -52.62,60.38 C-52.62,60.38 -53.06,62.06 -53.06,62.06 C-53.06,62.06 -51.65,61.53 -51.65,61.53 C-51.65,61.53 -50.32,62.5 -50.32,62.5 C-50.32,62.5 -50.41,60.82 -50.41,60.82 C-50.41,60.82 -49.08,59.77 -49.08,59.77 C-49.08,59.77 -50.59,59.33 -50.59,59.33c M29.98 -16.08 C29.98,-16.08 29.27,-18.46 29.27,-18.46 C29.27,-18.46 27.95,-16.43 27.95,-16.43 C27.95,-16.43 25.74,-16.43 25.74,-16.43 C25.74,-16.43 27.06,-14.49 27.06,-14.49 C27.06,-14.49 26.36,-12.11 26.36,-12.11 C26.36,-12.11 28.48,-12.9 28.48,-12.9 C28.48,-12.9 30.33,-11.49 30.33,-11.49 C30.33,-11.49 30.24,-13.96 30.24,-13.96 C30.24,-13.96 32.1,-15.37 32.1,-15.37 C32.1,-15.37 29.98,-16.08 29.98,-16.08c M81.28 55.98 C81.28,55.98 80.58,53.6 80.58,53.6 C80.58,53.6 79.25,55.63 79.25,55.63 C79.25,55.63 77.04,55.63 77.04,55.63 C77.04,55.63 78.37,57.57 78.37,57.57 C78.37,57.57 77.66,59.95 77.66,59.95 C77.66,59.95 79.78,59.07 79.78,59.07 C79.78,59.07 81.64,60.56 81.64,60.56 C81.64,60.56 81.55,58.1 81.55,58.1 C81.55,58.1 83.4,56.68 83.4,56.68 C83.4,56.68 81.28,55.98 81.28,55.98c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-74.05 21.76 C-74.05,21.76 -74.66,19.47 -74.66,19.47 C-74.66,19.47 -75.99,21.49 -75.99,21.49 C-75.99,21.49 -78.2,21.41 -78.2,21.41 C-78.2,21.41 -76.87,23.43 -76.87,23.43 C-76.87,23.43 -77.58,25.73 -77.58,25.73 C-77.58,25.73 -75.46,24.93 -75.46,24.93 C-75.46,24.93 -73.6,26.43 -73.6,26.43 C-73.6,26.43 -73.69,23.96 -73.69,23.96 C-73.69,23.96 -71.84,22.46 -71.84,22.46 C-71.84,22.46 -74.05,21.76 -74.05,21.76c M8.98 55.68 C8.98,55.68 6.15,53.65 6.15,53.65 C6.15,53.65 6.24,57.09 6.24,57.09 C6.24,57.09 3.5,59.12 3.5,59.12 C3.5,59.12 6.86,60.09 6.86,60.09 C6.86,60.09 7.92,63.35 7.92,63.35 C7.92,63.35 9.86,60.44 9.86,60.44 C9.86,60.44 13.3,60.44 13.3,60.44 C13.3,60.44 11.18,57.71 11.18,57.71 C11.18,57.71 12.15,54.44 12.15,54.44 C12.15,54.44 8.98,55.68 8.98,55.68c M124.89 -2.41 C124.89,-2.41 122.06,-4.35 122.06,-4.35 C122.06,-4.35 122.24,-0.91 122.24,-0.91 C122.24,-0.91 119.5,1.12 119.5,1.12 C119.5,1.12 122.77,2 122.77,2 C122.77,2 123.83,5.26 123.83,5.26 C123.83,5.26 125.77,2.44 125.77,2.44 C125.77,2.44 129.21,2.44 129.21,2.44 C129.21,2.44 127.09,-0.29 127.09,-0.29 C127.09,-0.29 128.15,-3.56 128.15,-3.56 C128.15,-3.56 124.89,-2.41 124.89,-2.41c M77.31 19.91 C77.31,19.91 74.57,17.88 74.57,17.88 C74.57,17.88 74.66,21.32 74.66,21.32 C74.66,21.32 71.92,23.35 71.92,23.35 C71.92,23.35 75.19,24.32 75.19,24.32 C75.19,24.32 76.34,27.58 76.34,27.58 C76.34,27.58 78.19,24.67 78.19,24.67 C78.19,24.67 81.64,24.67 81.64,24.67 C81.64,24.67 79.52,21.94 79.52,21.94 C79.52,21.94 80.58,18.67 80.58,18.67 C80.58,18.67 77.31,19.91 77.31,19.91c M-28.11 7.68 C-28.11,7.68 -30.94,5.65 -30.94,5.65 C-30.94,5.65 -30.76,9.09 -30.76,9.09 C-30.76,9.09 -33.5,11.12 -33.5,11.12 C-33.5,11.12 -30.23,12.09 -30.23,12.09 C-30.23,12.09 -29.17,15.35 -29.17,15.35 C-29.17,15.35 -27.23,12.44 -27.23,12.44 C-27.23,12.44 -23.79,12.44 -23.79,12.44 C-23.79,12.44 -25.91,9.71 -25.91,9.71 C-25.91,9.71 -24.85,6.44 -24.85,6.44 C-24.85,6.44 -28.11,7.68 -28.11,7.68c M-119.43 -20.22 C-119.43,-20.22 -122.26,-22.16 -122.26,-22.16 C-122.26,-22.16 -122.08,-18.72 -122.08,-18.72 C-122.08,-18.72 -124.82,-16.7 -124.82,-16.7 C-124.82,-16.7 -121.55,-15.81 -121.55,-15.81 C-121.55,-15.81 -120.49,-12.55 -120.49,-12.55 C-120.49,-12.55 -118.55,-15.37 -118.55,-15.37 C-118.55,-15.37 -115.11,-15.37 -115.11,-15.37 C-115.11,-15.37 -117.23,-18.11 -117.23,-18.11 C-117.23,-18.11 -116.17,-21.37 -116.17,-21.37 C-116.17,-21.37 -119.43,-20.22 -119.43,-20.22c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G">
+ <group android:name="_R_G_L_6_G_L_0_G_L_2_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#e8eaed" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M230.57 -95.63 C230.57,-95.63 230.57,42.37 230.57,42.37 C230.57,43.47 229.56,44.37 228.33,44.37 C228.33,44.37 -228.33,44.37 -228.33,44.37 C-229.56,44.37 -230.57,43.47 -230.57,42.37 C-230.57,42.37 -230.57,-95.63 -230.57,-95.63 C-230.57,-96.73 -229.56,-97.63 -228.33,-97.63 C-228.33,-97.63 228.33,-97.63 228.33,-97.63 C229.56,-97.63 230.57,-96.73 230.57,-95.63c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G_L_1_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G_L_0_G" android:translateX="46" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_5_G" android:scaleY="0">
+ <group android:name="_R_G_L_5_G_L_11_G" android:translateX="206" android:translateY="446" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_11_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_10_G" android:translateX="148" android:translateY="441" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_10_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M48 -8 C48,-8 48,8 48,8 C48,10.21 46.21,12 44,12 C44,12 -44,12 -44,12 C-46.21,12 -48,10.21 -48,8 C-48,8 -48,-8 -48,-8 C-48,-10.21 -46.21,-12 -44,-12 C-44,-12 44,-12 44,-12 C46.21,-12 48,-10.21 48,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_9_G" android:translateX="264" android:translateY="441" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_9_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M48 -8 C48,-8 48,8 48,8 C48,10.21 46.21,12 44,12 C44,12 -44,12 -44,12 C-46.21,12 -48,10.21 -48,8 C-48,8 -48,-8 -48,-8 C-48,-10.21 -46.21,-12 -44,-12 C-44,-12 44,-12 44,-12 C46.21,-12 48,-10.21 48,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_8_G" android:translateX="206" android:translateY="380" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_8_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M176 0 C176,0 176,0 176,0 C176,14.9 163.9,27 149,27 C149,27 -149,27 -149,27 C-163.9,27 -176,14.9 -176,0 C-176,0 -176,0 -176,0 C-176,-14.9 -163.9,-27 -149,-27 C-149,-27 149,-27 149,-27 C163.9,-27 176,-14.9 176,0c "/>
+ <path android:name="_R_G_L_5_G_L_8_G_D_1_P_0" android:strokeColor="#bdc1c6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M176 0 C176,0 176,0 176,0 C176,14.9 163.9,27 149,27 C149,27 -149,27 -149,27 C-163.9,27 -176,14.9 -176,0 C-176,0 -176,0 -176,0 C-176,-14.9 -163.9,-27 -149,-27 C-149,-27 149,-27 149,-27 C163.9,-27 176,-14.9 176,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_7_G" android:translateX="120" android:translateY="268" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_7_G_D_0_P_0" android:fillColor="#4285f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M26 0 C26,0 26,0 26,0 C26,14.35 14.35,26 0,26 C0,26 0,26 0,26 C-14.35,26 -26,14.35 -26,0 C-26,0 -26,0 -26,0 C-26,-14.35 -14.35,-26 0,-26 C0,-26 0,-26 0,-26 C14.35,-26 26,-14.35 26,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_6_G" android:translateX="167" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_6_G_D_0_P_0" android:fillColor="#e94235" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_5_G" android:translateX="205" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_5_G_D_0_P_0" android:fillColor="#fabb05" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_4_G" android:translateX="243" android:translateY="286" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_4_G_D_0_P_0" android:fillColor="#4285f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 -8 C17,-8 17,8 17,8 C17,17.38 9.38,25 0,25 C0,25 0,25 0,25 C-9.38,25 -17,17.38 -17,8 C-17,8 -17,-8 -17,-8 C-17,-17.38 -9.38,-25 0,-25 C0,-25 0,-25 0,-25 C9.38,-25 17,-17.38 17,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_3_G" android:translateX="272" android:translateY="269" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_3_G_D_0_P_0" android:fillColor="#34a853" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8 -17 C8,-17 8,17 8,17 C8,21.42 4.42,25 0,25 C0,25 0,25 0,25 C-4.42,25 -8,21.42 -8,17 C-8,17 -8,-17 -8,-17 C-8,-21.42 -4.42,-25 0,-25 C0,-25 0,-25 0,-25 C4.42,-25 8,-21.42 8,-17c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_2_G" android:translateX="301" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_2_G_D_0_P_0" android:fillColor="#e94235" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_1_G" android:translateX="42" android:translateY="140" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M12 -8 C12,-8 12,8 12,8 C12,10.21 10.21,12 8,12 C8,12 -8,12 -8,12 C-10.21,12 -12,10.21 -12,8 C-12,8 -12,-8 -12,-8 C-12,-10.21 -10.21,-12 -8,-12 C-8,-12 8,-12 8,-12 C10.21,-12 12,-10.21 12,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_0_G" android:translateX="92.5" android:translateY="140" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M28.5 -5 C28.5,-5 28.5,5 28.5,5 C28.5,7.21 26.71,9 24.5,9 C24.5,9 -24.5,9 -24.5,9 C-26.71,9 -28.5,7.21 -28.5,5 C-28.5,5 -28.5,-5 -28.5,-5 C-28.5,-7.21 -26.71,-9 -24.5,-9 C-24.5,-9 24.5,-9 24.5,-9 C26.71,-9 28.5,-7.21 28.5,-5c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_4_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_4_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_3_G">
+ <group android:name="_R_G_L_3_G_L_1_G" android:translateX="206" android:translateY="50.5">
+ <path android:name="_R_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -50.5 C206,-50.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-50.5 -206,-50.5 C-206,-50.5 206,-50.5 206,-50.5c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_0_G" android:translateX="206" android:translateY="66.5">
+ <path android:name="_R_G_L_3_G_L_0_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_2_G" android:translateX="28.25" android:translateY="462.5" android:scaleY="0">
+ <group android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0" android:translateX="-60" android:translateY="0">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M28.25 0 C28.25,31.2 2.95,56.5 -28.25,56.5 C-28.25,56.5 -28.25,-56.5 -28.25,-56.5 C2.95,-56.5 28.25,-31.2 28.25,0c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G" android:translateX="-4.25" android:translateY="463" android:scaleX="0.5" android:scaleY="0" android:rotation="180">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M3.87 -13.45 C3.07,-14.21 1.8,-14.18 1.04,-13.38 C0.28,-12.58 0.31,-11.31 1.11,-10.55 C1.11,-10.55 9.75,-2.32 9.75,-2.32 C9.75,-2.32 -14.75,-2.32 -14.75,-2.32 C-15.85,-2.32 -16.75,-1.43 -16.75,-0.32 C-16.75,0.78 -15.85,1.68 -14.75,1.68 C-14.75,1.68 9.94,1.68 9.94,1.68 C9.94,1.68 1.07,10.59 1.07,10.59 C0.29,11.37 0.29,12.64 1.08,13.42 C1.86,14.2 3.13,14.19 3.9,13.41 C3.9,13.41 16.17,1.09 16.17,1.09 C16.55,0.71 16.76,0.19 16.75,-0.35 C16.74,-0.89 16.52,-1.4 16.13,-1.77 C16.13,-1.77 3.87,-13.45 3.87,-13.45c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-130.003" android:translateY="399" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M-166 64 C-130.65,64 -102,35.35 -102,0 C-102,-35.34 -130.65,-64 -166,-64 C-201.34,-64 -230,-35.34 -230,0 C-230,35.35 -201.34,64 -166,64c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="192" android:translateY="63.997" android:rotation="90" android:scaleX="-1" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0" android:translateX="-166" android:translateY="0">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 64 C35.35,64 64,35.35 64,0 C64,-35.34 35.35,-64 0,-64 C-35.34,-64 -64,-35.34 -64,0 C-64,35.35 -35.34,64 0,64c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_6_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2283" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2283" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="2133" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="2133" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="283" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.88012" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="283" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.88012" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2417" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_11_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_10_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2433" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_9_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2433" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_8_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1133" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -60,0C -50,0 -70,0 -60,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="667" android:startOffset="1133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -60,0C -50,0 -10,0 0,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="1800" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,0C 0,0 0,0 0,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0,0 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="2133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,0C -10,0 -50,0 -60,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2467" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1133" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -4.25,463C 0.75,463 -9.25,463 -4.25,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="583" android:startOffset="1133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -4.25,463C 0.75,463 20.75,463 25.75,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="417" android:startOffset="1717" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 25.75,463C 25.75,463 25.75,463 25.75,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0.667,0.667 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="2133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 25.75,463C 25.75,463 -4.25,463 -4.25,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="1300" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="1300" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="1300" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="1300" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="1717" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="1717" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="200" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="200" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1300" android:valueFrom="0" android:valueTo="0.5" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0.5" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1033" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="867" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="467" android:startOffset="1033" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 167.99 C35.35,167.99 64,139.34 64,104 C64,104 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,104 -64,104 C-64,139.34 -35.34,167.99 0,167.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1033" android:valueFrom="0" android:valueTo="-1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="-1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="167" android:startOffset="867" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -138.333,0 -193.667,0 -166,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="467" android:startOffset="1033" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -138.333,0 -27.667,0 0,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="4017" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_back_right.xml b/quickstep/res/drawable/gesture_tutorial_back_right.xml
new file mode 100644
index 0000000..77d9924
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_back_right.xml
@@ -0,0 +1,561 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="892dp" android:width="412dp" android:viewportHeight="892" android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_7_G" android:translateX="206" android:translateY="446">
+ <path android:name="_R_G_L_7_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_6_G" android:pivotX="206" android:pivotY="446" android:scaleX="1" android:scaleY="1">
+ <group android:name="_R_G_L_6_G_L_3_G" android:translateX="206" android:translateY="446" android:scaleX="1.2" android:scaleY="1.2">
+ <path android:name="_R_G_L_6_G_L_3_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G">
+ <group android:name="_R_G_L_6_G_L_2_G_L_11_G" android:translateX="206" android:translateY="496.5">
+ <path android:name="_R_G_L_6_G_L_2_G_L_11_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M235.5 -452.14 C235.5,-452.14 235.5,452.14 235.5,452.14 C235.5,452.14 -235.5,452.14 -235.5,452.14 C-235.5,452.14 -235.5,-452.14 -235.5,-452.14 C-235.5,-452.14 235.5,-452.14 235.5,-452.14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_10_G" android:translateX="182.5" android:translateY="831">
+ <path android:name="_R_G_L_6_G_L_2_G_L_10_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_9_G" android:translateX="186" android:translateY="801">
+ <path android:name="_R_G_L_6_G_L_2_G_L_9_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -7 C162,-7 162,7 162,7 C162,9.21 160.21,11 158,11 C158,11 -158,11 -158,11 C-160.21,11 -162,9.21 -162,7 C-162,7 -162,-7 -162,-7 C-162,-9.21 -160.21,-11 -158,-11 C-158,-11 158,-11 158,-11 C160.21,-11 162,-9.21 162,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_8_G" android:translateX="119" android:translateY="755">
+ <path android:name="_R_G_L_6_G_L_2_G_L_8_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M95 -7 C95,-7 95,7 95,7 C95,9.21 93.21,11 91,11 C91,11 -91,11 -91,11 C-93.21,11 -95,9.21 -95,7 C-95,7 -95,-7 -95,-7 C-95,-9.21 -93.21,-11 -91,-11 C-91,-11 91,-11 91,-11 C93.21,-11 95,-9.21 95,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_7_G" android:translateX="182.5" android:translateY="725">
+ <path android:name="_R_G_L_6_G_L_2_G_L_7_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_6_G" android:translateX="197.5" android:translateY="695">
+ <path android:name="_R_G_L_6_G_L_2_G_L_6_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M173.5 -7 C173.5,-7 173.5,7 173.5,7 C173.5,9.21 171.71,11 169.5,11 C169.5,11 -169.5,11 -169.5,11 C-171.71,11 -173.5,9.21 -173.5,7 C-173.5,7 -173.5,-7 -173.5,-7 C-173.5,-9.21 -171.71,-11 -169.5,-11 C-169.5,-11 169.5,-11 169.5,-11 C171.71,-11 173.5,-9.21 173.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_5_G" android:translateX="192" android:translateY="665">
+ <path android:name="_R_G_L_6_G_L_2_G_L_5_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M168 -7 C168,-7 168,7 168,7 C168,9.21 166.21,11 164,11 C164,11 -164,11 -164,11 C-166.21,11 -168,9.21 -168,7 C-168,7 -168,-7 -168,-7 C-168,-9.21 -166.21,-11 -164,-11 C-164,-11 164,-11 164,-11 C166.21,-11 168,-9.21 168,-7c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_4_G" android:translateX="105.5" android:translateY="360">
+ <path android:name="_R_G_L_6_G_L_2_G_L_4_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_3_G" android:translateX="47.5" android:translateY="360">
+ <path android:name="_R_G_L_6_G_L_2_G_L_3_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_2_G" android:translateX="142.5" android:translateY="328">
+ <path android:name="_R_G_L_6_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M118.5 -14 C118.5,-14 118.5,14 118.5,14 C118.5,16.21 116.71,18 114.5,18 C114.5,18 -114.5,18 -114.5,18 C-116.71,18 -118.5,16.21 -118.5,14 C-118.5,14 -118.5,-14 -118.5,-14 C-118.5,-16.21 -116.71,-18 -114.5,-18 C-114.5,-18 114.5,-18 114.5,-18 C116.71,-18 118.5,-16.21 118.5,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_1_G" android:translateX="186" android:translateY="284">
+ <path android:name="_R_G_L_6_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -14 C162,-14 162,14 162,14 C162,16.21 160.21,18 158,18 C158,18 -158,18 -158,18 C-160.21,18 -162,16.21 -162,14 C-162,14 -162,-14 -162,-14 C-162,-16.21 -160.21,-18 -158,-18 C-158,-18 158,-18 158,-18 C160.21,-18 162,-16.21 162,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_2_G_L_0_G" android:translateX="155" android:translateY="240">
+ <path android:name="_R_G_L_6_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M131 -14 C131,-14 131,14 131,14 C131,16.21 129.21,18 127,18 C127,18 -127,18 -127,18 C-129.21,18 -131,16.21 -131,14 C-131,14 -131,-14 -131,-14 C-131,-16.21 -129.21,-18 -127,-18 C-127,-18 127,-18 127,-18 C129.21,-18 131,-16.21 131,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G" android:translateX="24" android:translateY="390">
+ <group android:name="_R_G_L_6_G_L_1_G_L_7_G" android:translateX="182" android:translateY="120"/>
+ <group android:name="_R_G_L_6_G_L_1_G_L_6_G" android:translateX="182" android:translateY="120">
+ <path android:name="_R_G_L_6_G_L_1_G_L_6_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M182 -116 C182,-116 182,116 182,116 C182,118.21 180.21,120 178,120 C178,120 -178,120 -178,120 C-180.21,120 -182,118.21 -182,116 C-182,116 -182,-116 -182,-116 C-182,-118.21 -180.21,-120 -178,-120 C-178,-120 178,-120 178,-120 C180.21,-120 182,-118.21 182,-116c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_5_G" android:translateX="77.322" android:translateY="150.552">
+ <path android:name="_R_G_L_6_G_L_1_G_L_5_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_5_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_4_G" android:translateX="38.772" android:translateY="121.73">
+ <path android:name="_R_G_L_6_G_L_1_G_L_4_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_4_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_3_G" android:translateX="183" android:translateY="222">
+ <path android:name="_R_G_L_6_G_L_1_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_3_G_D_1_P_0" android:strokeColor="#9aa0a6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_2_G" android:translateX="265.619" android:translateY="162.331">
+ <path android:name="_R_G_L_6_G_L_1_G_L_2_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ <path android:name="_R_G_L_6_G_L_1_G_L_2_G_D_1_P_0" android:strokeColor="#a8cbfe" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_1_G" android:translateX="319.271" android:translateY="37.945">
+ <path android:name="_R_G_L_6_G_L_1_G_L_1_G_D_0_P_0" android:fillColor="#feefc3" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.42 2.99 C14.95,-4.17 9.93,-11.31 2.21,-12.96 C-0.9,-13.62 -3.97,-13.3 -6.64,-12.2 C-6.58,-12.19 -6.53,-12.18 -6.48,-12.17 C-1.03,-11.01 2.52,-5.97 1.44,-0.92 C0.36,4.13 -4.94,7.28 -10.4,6.12 C-11.6,5.86 -12.7,5.42 -13.69,4.83 C-11.9,8.78 -8.15,11.93 -3.34,12.96 C4.38,14.61 11.88,10.14 13.42,2.99c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_1_G_L_0_G" android:translateX="179.5" android:translateY="73.351">
+ <path android:name="_R_G_L_6_G_L_1_G_L_0_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M51.08 -40.95 C51.08,-40.95 50.55,-42.54 50.55,-42.54 C50.55,-42.54 49.67,-41.13 49.67,-41.13 C49.67,-41.13 48.17,-41.21 48.17,-41.21 C48.17,-41.21 49.05,-39.8 49.05,-39.8 C49.05,-39.8 48.61,-38.22 48.61,-38.22 C48.61,-38.22 50.02,-38.74 50.02,-38.74 C50.02,-38.74 51.35,-37.69 51.35,-37.69 C51.35,-37.69 51.26,-39.45 51.26,-39.45 C51.26,-39.45 52.59,-40.42 52.59,-40.42 C52.59,-40.42 51.08,-40.95 51.08,-40.95c M8.78 30.58 C8.78,30.58 8.25,28.99 8.25,28.99 C8.25,28.99 7.37,30.4 7.37,30.4 C7.37,30.4 5.87,30.31 5.87,30.31 C5.87,30.31 6.75,31.72 6.75,31.72 C6.75,31.72 6.31,33.31 6.31,33.31 C6.31,33.31 7.72,32.78 7.72,32.78 C7.72,32.78 9.05,33.84 9.05,33.84 C9.05,33.84 8.96,32.08 8.96,32.08 C8.96,32.08 10.29,31.11 10.29,31.11 C10.29,31.11 8.78,30.58 8.78,30.58c M19.38 -61.67 C19.38,-61.67 18.94,-63.35 18.94,-63.35 C18.94,-63.35 17.97,-61.94 17.97,-61.94 C17.97,-61.94 16.47,-61.94 16.47,-61.94 C16.47,-61.94 17.35,-60.62 17.35,-60.62 C17.35,-60.62 16.91,-58.94 16.91,-58.94 C16.91,-58.94 18.41,-59.56 18.41,-59.56 C18.41,-59.56 19.65,-58.5 19.65,-58.5 C19.65,-58.5 19.56,-60.18 19.56,-60.18 C19.56,-60.18 20.88,-61.23 20.88,-61.23 C20.88,-61.23 19.38,-61.67 19.38,-61.67c M-32.98 35.08 C-32.98,35.08 -33.51,33.4 -33.51,33.4 C-33.51,33.4 -34.4,34.81 -34.4,34.81 C-34.4,34.81 -35.9,34.81 -35.9,34.81 C-35.9,34.81 -35.01,36.22 -35.01,36.22 C-35.01,36.22 -35.45,37.81 -35.45,37.81 C-35.45,37.81 -34.04,37.28 -34.04,37.28 C-34.04,37.28 -32.72,38.25 -32.72,38.25 C-32.72,38.25 -32.81,36.58 -32.81,36.58 C-32.81,36.58 -31.48,35.6 -31.48,35.6 C-31.48,35.6 -32.98,35.08 -32.98,35.08c M45.34 7.56 C45.34,7.56 44.81,5.97 44.81,5.97 C44.81,5.97 43.93,7.38 43.93,7.38 C43.93,7.38 42.34,7.3 42.34,7.3 C42.34,7.3 43.31,8.71 43.31,8.71 C43.31,8.71 42.87,10.29 42.87,10.29 C42.87,10.29 44.28,9.77 44.28,9.77 C44.28,9.77 45.52,10.82 45.52,10.82 C45.52,10.82 45.52,9.06 45.52,9.06 C45.52,9.06 46.76,8.09 46.76,8.09 C46.76,8.09 45.34,7.56 45.34,7.56c M-9.59 -41.67 C-9.59,-41.67 -10.12,-43.35 -10.12,-43.35 C-10.12,-43.35 -11,-41.94 -11,-41.94 C-11,-41.94 -12.5,-41.94 -12.5,-41.94 C-12.5,-41.94 -11.62,-40.62 -11.62,-40.62 C-11.62,-40.62 -12.06,-38.94 -12.06,-38.94 C-12.06,-38.94 -10.65,-39.56 -10.65,-39.56 C-10.65,-39.56 -9.32,-38.5 -9.32,-38.5 C-9.32,-38.5 -9.41,-40.26 -9.41,-40.26 C-9.41,-40.26 -8.09,-41.23 -8.09,-41.23 C-8.09,-41.23 -9.59,-41.67 -9.59,-41.67c M97.74 -23.97 C97.74,-23.97 97.03,-26.35 97.03,-26.35 C97.03,-26.35 95.8,-24.32 95.8,-24.32 C95.8,-24.32 93.5,-24.32 93.5,-24.32 C93.5,-24.32 94.91,-22.38 94.91,-22.38 C94.91,-22.38 94.21,-20 94.21,-20 C94.21,-20 96.33,-20.88 96.33,-20.88 C96.33,-20.88 98.09,-19.38 98.09,-19.38 C98.09,-19.38 98.09,-21.85 98.09,-21.85 C98.09,-21.85 99.86,-23.26 99.86,-23.26 C99.86,-23.26 97.74,-23.97 97.74,-23.97c M167.29 43.28 C167.29,43.28 166.67,40.9 166.67,40.9 C166.67,40.9 165.35,42.93 165.35,42.93 C165.35,42.93 163.14,42.93 163.14,42.93 C163.14,42.93 164.47,44.87 164.47,44.87 C164.47,44.87 163.76,47.25 163.76,47.25 C163.76,47.25 165.88,46.37 165.88,46.37 C165.88,46.37 167.73,47.87 167.73,47.87 C167.73,47.87 167.65,45.4 167.65,45.4 C167.65,45.4 169.5,43.98 169.5,43.98 C169.5,43.98 167.29,43.28 167.29,43.28c M-1.1 -1.79 C-1.1,-1.79 -1.72,-4.08 -1.72,-4.08 C-1.72,-4.08 -3.05,-2.14 -3.05,-2.14 C-3.05,-2.14 -5.25,-2.14 -5.25,-2.14 C-5.25,-2.14 -3.93,-0.11 -3.93,-0.11 C-3.93,-0.11 -4.64,2.18 -4.64,2.18 C-4.64,2.18 -2.52,1.38 -2.52,1.38 C-2.52,1.38 -0.66,2.8 -0.66,2.8 C-0.66,2.8 -0.75,0.41 -0.75,0.41 C-0.75,0.41 1.1,-1.08 1.1,-1.08 C1.1,-1.08 -1.1,-1.79 -1.1,-1.79c M-60.89 -5.23 C-60.89,-5.23 -61.59,-7.61 -61.59,-7.61 C-61.59,-7.61 -62.83,-5.58 -62.83,-5.58 C-62.83,-5.58 -65.13,-5.58 -65.13,-5.58 C-65.13,-5.58 -63.71,-3.64 -63.71,-3.64 C-63.71,-3.64 -64.42,-1.26 -64.42,-1.26 C-64.42,-1.26 -62.39,-2.14 -62.39,-2.14 C-62.39,-2.14 -60.53,-0.64 -60.53,-0.64 C-60.53,-0.64 -60.62,-3.11 -60.62,-3.11 C-60.62,-3.11 -58.77,-4.52 -58.77,-4.52 C-58.77,-4.52 -60.89,-5.23 -60.89,-5.23c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-51.26 -42.98 C-51.26,-42.98 -54.09,-45.01 -54.09,-45.01 C-54.09,-45.01 -53.91,-41.57 -53.91,-41.57 C-53.91,-41.57 -56.65,-39.54 -56.65,-39.54 C-56.65,-39.54 -53.38,-38.57 -53.38,-38.57 C-53.38,-38.57 -52.32,-35.3 -52.32,-35.3 C-52.32,-35.3 -50.38,-38.13 -50.38,-38.13 C-50.38,-38.13 -46.94,-38.22 -46.94,-38.22 C-46.94,-38.22 -49.05,-40.86 -49.05,-40.86 C-49.05,-40.86 -47.99,-44.21 -47.99,-44.21 C-47.99,-44.21 -51.26,-42.98 -51.26,-42.98c M-92.06 -47.92 C-92.06,-47.92 -92.59,-49.59 -92.59,-49.59 C-92.59,-49.59 -93.47,-48.18 -93.47,-48.18 C-93.47,-48.18 -95.06,-48.18 -95.06,-48.18 C-95.06,-48.18 -94.09,-46.86 -94.09,-46.86 C-94.09,-46.86 -94.53,-45.18 -94.53,-45.18 C-94.53,-45.18 -93.12,-45.8 -93.12,-45.8 C-93.12,-45.8 -91.88,-44.74 -91.88,-44.74 C-91.88,-44.74 -91.88,-46.42 -91.88,-46.42 C-91.88,-46.42 -90.65,-47.47 -90.65,-47.47 C-90.65,-47.47 -92.06,-47.92 -92.06,-47.92c M62.83 -13.34 C62.83,-13.34 62.39,-14.93 62.39,-14.93 C62.39,-14.93 61.5,-13.52 61.5,-13.52 C61.5,-13.52 59.91,-13.52 59.91,-13.52 C59.91,-13.52 60.89,-12.2 60.89,-12.2 C60.89,-12.2 60.36,-10.52 60.36,-10.52 C60.36,-10.52 61.86,-11.14 61.86,-11.14 C61.86,-11.14 63.09,-10.08 63.09,-10.08 C63.09,-10.08 63.09,-11.84 63.09,-11.84 C63.09,-11.84 64.33,-12.81 64.33,-12.81 C64.33,-12.81 62.83,-13.34 62.83,-13.34c M-155.99 -40.95 C-155.99,-40.95 -156.43,-42.54 -156.43,-42.54 C-156.43,-42.54 -157.32,-41.13 -157.32,-41.13 C-157.32,-41.13 -158.91,-41.21 -158.91,-41.21 C-158.91,-41.21 -157.93,-39.8 -157.93,-39.8 C-157.93,-39.8 -158.46,-38.22 -158.46,-38.22 C-158.46,-38.22 -156.96,-38.74 -156.96,-38.74 C-156.96,-38.74 -155.73,-37.69 -155.73,-37.69 C-155.73,-37.69 -155.73,-39.45 -155.73,-39.45 C-155.73,-39.45 -154.49,-40.42 -154.49,-40.42 C-154.49,-40.42 -155.99,-40.95 -155.99,-40.95c M141.24 26.52 C141.24,26.52 140.71,24.85 140.71,24.85 C140.71,24.85 139.83,26.26 139.83,26.26 C139.83,26.26 138.33,26.26 138.33,26.26 C138.33,26.26 139.21,27.67 139.21,27.67 C139.21,27.67 138.77,29.26 138.77,29.26 C138.77,29.26 140.18,28.73 140.18,28.73 C140.18,28.73 141.51,29.7 141.51,29.7 C141.51,29.7 141.42,28.02 141.42,28.02 C141.42,28.02 142.74,27.05 142.74,27.05 C142.74,27.05 141.24,26.52 141.24,26.52c M111.4 -51.27 C111.4,-51.27 110.95,-52.94 110.95,-52.94 C110.95,-52.94 110.07,-51.53 110.07,-51.53 C110.07,-51.53 108.48,-51.53 108.48,-51.53 C108.48,-51.53 109.45,-50.21 109.45,-50.21 C109.45,-50.21 108.92,-48.53 108.92,-48.53 C108.92,-48.53 110.42,-49.15 110.42,-49.15 C110.42,-49.15 111.66,-48.09 111.66,-48.09 C111.66,-48.09 111.66,-49.86 111.66,-49.86 C111.66,-49.86 112.9,-50.83 112.9,-50.83 C112.9,-50.83 111.4,-51.27 111.4,-51.27c M-66.59 53.33 C-66.59,53.33 -67.03,51.65 -67.03,51.65 C-67.03,51.65 -67.91,53.06 -67.91,53.06 C-67.91,53.06 -69.5,53.06 -69.5,53.06 C-69.5,53.06 -68.53,54.47 -68.53,54.47 C-68.53,54.47 -69.06,56.06 -69.06,56.06 C-69.06,56.06 -67.56,55.53 -67.56,55.53 C-67.56,55.53 -66.32,56.5 -66.32,56.5 C-66.32,56.5 -66.32,54.82 -66.32,54.82 C-66.32,54.82 -65.08,53.77 -65.08,53.77 C-65.08,53.77 -66.59,53.33 -66.59,53.33c M-50.59 59.33 C-50.59,59.33 -51.12,57.65 -51.12,57.65 C-51.12,57.65 -52,59.06 -52,59.06 C-52,59.06 -53.5,59.06 -53.5,59.06 C-53.5,59.06 -52.62,60.38 -52.62,60.38 C-52.62,60.38 -53.06,62.06 -53.06,62.06 C-53.06,62.06 -51.65,61.53 -51.65,61.53 C-51.65,61.53 -50.32,62.5 -50.32,62.5 C-50.32,62.5 -50.41,60.82 -50.41,60.82 C-50.41,60.82 -49.08,59.77 -49.08,59.77 C-49.08,59.77 -50.59,59.33 -50.59,59.33c M29.98 -16.08 C29.98,-16.08 29.27,-18.46 29.27,-18.46 C29.27,-18.46 27.95,-16.43 27.95,-16.43 C27.95,-16.43 25.74,-16.43 25.74,-16.43 C25.74,-16.43 27.06,-14.49 27.06,-14.49 C27.06,-14.49 26.36,-12.11 26.36,-12.11 C26.36,-12.11 28.48,-12.9 28.48,-12.9 C28.48,-12.9 30.33,-11.49 30.33,-11.49 C30.33,-11.49 30.24,-13.96 30.24,-13.96 C30.24,-13.96 32.1,-15.37 32.1,-15.37 C32.1,-15.37 29.98,-16.08 29.98,-16.08c M81.28 55.98 C81.28,55.98 80.58,53.6 80.58,53.6 C80.58,53.6 79.25,55.63 79.25,55.63 C79.25,55.63 77.04,55.63 77.04,55.63 C77.04,55.63 78.37,57.57 78.37,57.57 C78.37,57.57 77.66,59.95 77.66,59.95 C77.66,59.95 79.78,59.07 79.78,59.07 C79.78,59.07 81.64,60.56 81.64,60.56 C81.64,60.56 81.55,58.1 81.55,58.1 C81.55,58.1 83.4,56.68 83.4,56.68 C83.4,56.68 81.28,55.98 81.28,55.98c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-74.05 21.76 C-74.05,21.76 -74.66,19.47 -74.66,19.47 C-74.66,19.47 -75.99,21.49 -75.99,21.49 C-75.99,21.49 -78.2,21.41 -78.2,21.41 C-78.2,21.41 -76.87,23.43 -76.87,23.43 C-76.87,23.43 -77.58,25.73 -77.58,25.73 C-77.58,25.73 -75.46,24.93 -75.46,24.93 C-75.46,24.93 -73.6,26.43 -73.6,26.43 C-73.6,26.43 -73.69,23.96 -73.69,23.96 C-73.69,23.96 -71.84,22.46 -71.84,22.46 C-71.84,22.46 -74.05,21.76 -74.05,21.76c M8.98 55.68 C8.98,55.68 6.15,53.65 6.15,53.65 C6.15,53.65 6.24,57.09 6.24,57.09 C6.24,57.09 3.5,59.12 3.5,59.12 C3.5,59.12 6.86,60.09 6.86,60.09 C6.86,60.09 7.92,63.35 7.92,63.35 C7.92,63.35 9.86,60.44 9.86,60.44 C9.86,60.44 13.3,60.44 13.3,60.44 C13.3,60.44 11.18,57.71 11.18,57.71 C11.18,57.71 12.15,54.44 12.15,54.44 C12.15,54.44 8.98,55.68 8.98,55.68c M124.89 -2.41 C124.89,-2.41 122.06,-4.35 122.06,-4.35 C122.06,-4.35 122.24,-0.91 122.24,-0.91 C122.24,-0.91 119.5,1.12 119.5,1.12 C119.5,1.12 122.77,2 122.77,2 C122.77,2 123.83,5.26 123.83,5.26 C123.83,5.26 125.77,2.44 125.77,2.44 C125.77,2.44 129.21,2.44 129.21,2.44 C129.21,2.44 127.09,-0.29 127.09,-0.29 C127.09,-0.29 128.15,-3.56 128.15,-3.56 C128.15,-3.56 124.89,-2.41 124.89,-2.41c M77.31 19.91 C77.31,19.91 74.57,17.88 74.57,17.88 C74.57,17.88 74.66,21.32 74.66,21.32 C74.66,21.32 71.92,23.35 71.92,23.35 C71.92,23.35 75.19,24.32 75.19,24.32 C75.19,24.32 76.34,27.58 76.34,27.58 C76.34,27.58 78.19,24.67 78.19,24.67 C78.19,24.67 81.64,24.67 81.64,24.67 C81.64,24.67 79.52,21.94 79.52,21.94 C79.52,21.94 80.58,18.67 80.58,18.67 C80.58,18.67 77.31,19.91 77.31,19.91c M-28.11 7.68 C-28.11,7.68 -30.94,5.65 -30.94,5.65 C-30.94,5.65 -30.76,9.09 -30.76,9.09 C-30.76,9.09 -33.5,11.12 -33.5,11.12 C-33.5,11.12 -30.23,12.09 -30.23,12.09 C-30.23,12.09 -29.17,15.35 -29.17,15.35 C-29.17,15.35 -27.23,12.44 -27.23,12.44 C-27.23,12.44 -23.79,12.44 -23.79,12.44 C-23.79,12.44 -25.91,9.71 -25.91,9.71 C-25.91,9.71 -24.85,6.44 -24.85,6.44 C-24.85,6.44 -28.11,7.68 -28.11,7.68c M-119.43 -20.22 C-119.43,-20.22 -122.26,-22.16 -122.26,-22.16 C-122.26,-22.16 -122.08,-18.72 -122.08,-18.72 C-122.08,-18.72 -124.82,-16.7 -124.82,-16.7 C-124.82,-16.7 -121.55,-15.81 -121.55,-15.81 C-121.55,-15.81 -120.49,-12.55 -120.49,-12.55 C-120.49,-12.55 -118.55,-15.37 -118.55,-15.37 C-118.55,-15.37 -115.11,-15.37 -115.11,-15.37 C-115.11,-15.37 -117.23,-18.11 -117.23,-18.11 C-117.23,-18.11 -116.17,-21.37 -116.17,-21.37 C-116.17,-21.37 -119.43,-20.22 -119.43,-20.22c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G">
+ <group android:name="_R_G_L_6_G_L_0_G_L_2_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#e8eaed" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M230.57 -95.63 C230.57,-95.63 230.57,42.37 230.57,42.37 C230.57,43.47 229.56,44.37 228.33,44.37 C228.33,44.37 -228.33,44.37 -228.33,44.37 C-229.56,44.37 -230.57,43.47 -230.57,42.37 C-230.57,42.37 -230.57,-95.63 -230.57,-95.63 C-230.57,-96.73 -229.56,-97.63 -228.33,-97.63 C-228.33,-97.63 228.33,-97.63 228.33,-97.63 C229.56,-97.63 230.57,-96.73 230.57,-95.63c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G_L_1_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c "/>
+ </group>
+ <group android:name="_R_G_L_6_G_L_0_G_L_0_G" android:translateX="46" android:translateY="145">
+ <path android:name="_R_G_L_6_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_5_G" android:scaleY="0">
+ <group android:name="_R_G_L_5_G_L_11_G" android:translateX="206" android:translateY="446" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_11_G_D_0_P_0" android:fillColor="#f1f3f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_10_G" android:translateX="148" android:translateY="441" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_10_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M48 -8 C48,-8 48,8 48,8 C48,10.21 46.21,12 44,12 C44,12 -44,12 -44,12 C-46.21,12 -48,10.21 -48,8 C-48,8 -48,-8 -48,-8 C-48,-10.21 -46.21,-12 -44,-12 C-44,-12 44,-12 44,-12 C46.21,-12 48,-10.21 48,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_9_G" android:translateX="264" android:translateY="441" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_9_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M48 -8 C48,-8 48,8 48,8 C48,10.21 46.21,12 44,12 C44,12 -44,12 -44,12 C-46.21,12 -48,10.21 -48,8 C-48,8 -48,-8 -48,-8 C-48,-10.21 -46.21,-12 -44,-12 C-44,-12 44,-12 44,-12 C46.21,-12 48,-10.21 48,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_8_G" android:translateX="206" android:translateY="380" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_8_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M176 0 C176,0 176,0 176,0 C176,14.9 163.9,27 149,27 C149,27 -149,27 -149,27 C-163.9,27 -176,14.9 -176,0 C-176,0 -176,0 -176,0 C-176,-14.9 -163.9,-27 -149,-27 C-149,-27 149,-27 149,-27 C163.9,-27 176,-14.9 176,0c "/>
+ <path android:name="_R_G_L_5_G_L_8_G_D_1_P_0" android:strokeColor="#bdc1c6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M176 0 C176,0 176,0 176,0 C176,14.9 163.9,27 149,27 C149,27 -149,27 -149,27 C-163.9,27 -176,14.9 -176,0 C-176,0 -176,0 -176,0 C-176,-14.9 -163.9,-27 -149,-27 C-149,-27 149,-27 149,-27 C163.9,-27 176,-14.9 176,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_7_G" android:translateX="120" android:translateY="268" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_7_G_D_0_P_0" android:fillColor="#4285f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M26 0 C26,0 26,0 26,0 C26,14.35 14.35,26 0,26 C0,26 0,26 0,26 C-14.35,26 -26,14.35 -26,0 C-26,0 -26,0 -26,0 C-26,-14.35 -14.35,-26 0,-26 C0,-26 0,-26 0,-26 C14.35,-26 26,-14.35 26,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_6_G" android:translateX="167" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_6_G_D_0_P_0" android:fillColor="#e94235" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_5_G" android:translateX="205" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_5_G_D_0_P_0" android:fillColor="#fabb05" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_4_G" android:translateX="243" android:translateY="286" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_4_G_D_0_P_0" android:fillColor="#4285f4" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 -8 C17,-8 17,8 17,8 C17,17.38 9.38,25 0,25 C0,25 0,25 0,25 C-9.38,25 -17,17.38 -17,8 C-17,8 -17,-8 -17,-8 C-17,-17.38 -9.38,-25 0,-25 C0,-25 0,-25 0,-25 C9.38,-25 17,-17.38 17,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_3_G" android:translateX="272" android:translateY="269" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_3_G_D_0_P_0" android:fillColor="#34a853" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8 -17 C8,-17 8,17 8,17 C8,21.42 4.42,25 0,25 C0,25 0,25 0,25 C-4.42,25 -8,21.42 -8,17 C-8,17 -8,-17 -8,-17 C-8,-21.42 -4.42,-25 0,-25 C0,-25 0,-25 0,-25 C4.42,-25 8,-21.42 8,-17c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_2_G" android:translateX="301" android:translateY="278" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_2_G_D_0_P_0" android:fillColor="#e94235" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17 0 C17,0 17,0 17,0 C17,9.38 9.38,17 0,17 C0,17 0,17 0,17 C-9.38,17 -17,9.38 -17,0 C-17,0 -17,0 -17,0 C-17,-9.38 -9.38,-17 0,-17 C0,-17 0,-17 0,-17 C9.38,-17 17,-9.38 17,0c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_1_G" android:translateX="42" android:translateY="140" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M12 -8 C12,-8 12,8 12,8 C12,10.21 10.21,12 8,12 C8,12 -8,12 -8,12 C-10.21,12 -12,10.21 -12,8 C-12,8 -12,-8 -12,-8 C-12,-10.21 -10.21,-12 -8,-12 C-8,-12 8,-12 8,-12 C10.21,-12 12,-10.21 12,-8c "/>
+ </group>
+ <group android:name="_R_G_L_5_G_L_0_G" android:translateX="92.5" android:translateY="140" android:scaleY="0">
+ <path android:name="_R_G_L_5_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M28.5 -5 C28.5,-5 28.5,5 28.5,5 C28.5,7.21 26.71,9 24.5,9 C24.5,9 -24.5,9 -24.5,9 C-26.71,9 -28.5,7.21 -28.5,5 C-28.5,5 -28.5,-5 -28.5,-5 C-28.5,-7.21 -26.71,-9 -24.5,-9 C-24.5,-9 24.5,-9 24.5,-9 C26.71,-9 28.5,-7.21 28.5,-5c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_4_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_4_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_3_G">
+ <group android:name="_R_G_L_3_G_L_1_G" android:translateX="206" android:translateY="50.5">
+ <path android:name="_R_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -50.5 C206,-50.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-50.5 -206,-50.5 C-206,-50.5 206,-50.5 206,-50.5c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_0_G" android:translateX="206" android:translateY="66.5">
+ <path android:name="_R_G_L_3_G_L_0_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_2_G" android:translateX="382.824" android:translateY="462.5" android:scaleX="-1" android:scaleY="0">
+ <group android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0" android:translateX="-60" android:translateY="0">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M28.25 0 C28.25,31.2 2.95,56.5 -28.25,56.5 C-28.25,56.5 -28.25,-56.5 -28.25,-56.5 C2.95,-56.5 28.25,-31.2 28.25,0c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G" android:translateX="414.087" android:translateY="463" android:scaleX="0.5" android:scaleY="0" android:rotation="180">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M3.87 -13.45 C3.07,-14.21 1.8,-14.18 1.04,-13.38 C0.28,-12.58 0.31,-11.31 1.11,-10.55 C1.11,-10.55 9.75,-2.32 9.75,-2.32 C9.75,-2.32 -14.75,-2.32 -14.75,-2.32 C-15.85,-2.32 -16.75,-1.43 -16.75,-0.32 C-16.75,0.78 -15.85,1.68 -14.75,1.68 C-14.75,1.68 9.94,1.68 9.94,1.68 C9.94,1.68 1.07,10.59 1.07,10.59 C0.29,11.37 0.29,12.64 1.08,13.42 C1.86,14.2 3.13,14.19 3.9,13.41 C3.9,13.41 16.17,1.09 16.17,1.09 C16.55,0.71 16.76,0.19 16.75,-0.35 C16.74,-0.89 16.52,-1.4 16.13,-1.77 C16.13,-1.77 3.87,-13.45 3.87,-13.45c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="206" android:translateY="446" android:scaleX="-1" android:scaleY="0">
+ <group android:name="_R_G_L_0_G" android:translateX="-336.003" android:translateY="-48.003">
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M-166 64 C-130.65,64 -102,35.35 -102,0 C-102,-35.34 -130.65,-64 -166,-64 C-201.34,-64 -230,-35.34 -230,0 C-230,35.35 -201.34,64 -166,64c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="192" android:translateY="63.997" android:rotation="90" android:scaleX="-1" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0" android:translateX="-166" android:translateY="0">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 64 C35.35,64 64,35.35 64,0 C64,-35.34 35.35,-64 0,-64 C-35.34,-64 -64,-35.34 -64,0 C-64,35.35 -35.34,64 0,64c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_6_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2283" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2283" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="2133" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="2133" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="283" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.88012" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="283" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.88012" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2417" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_11_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_10_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2433" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_9_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2433" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_8_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2367" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1133" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -60,0C -50.167,0 -69.833,0 -60,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="667" android:startOffset="1133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -60,0C -50.167,0 -10.833,0 -1,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="1800" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -1,0C -1,0 -1,0 -1,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0,0 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="2133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -1,0C -10.833,0 -50.167,0 -60,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2467" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1133" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 414.087,463C 409.087,463 419.087,463 414.087,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="583" android:startOffset="1133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 414.087,463C 409.087,463 389.087,463 384.087,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="417" android:startOffset="1717" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 384.087,463C 384.087,463 384.087,463 384.087,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0.667,0.667 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="333" android:startOffset="2133" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 384.087,463C 389.087,463 409.087,463 414.087,463">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="1300" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="1300" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="1300" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="1300" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="1717" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="1717" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="200" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="200" android:startOffset="2133" android:valueFrom="1" android:valueTo="0.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1300" android:valueFrom="0" android:valueTo="0.5" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2333" android:valueFrom="0.5" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1033" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="867" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="467" android:startOffset="1033" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 167.99 C35.35,167.99 64,139.34 64,104 C64,104 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,104 -64,104 C-64,139.34 -35.34,167.99 0,167.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1033" android:valueFrom="0" android:valueTo="-1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="-1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="167" android:startOffset="867" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -138.333,0 -193.667,0 -166,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="467" android:startOffset="1033" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -138.333,0 -27.667,0 0,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_1_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="867" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_1_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="4017" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml b/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml
new file mode 100644
index 0000000..0a34af6
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="50dp"/>
+ <solid android:color="@android:color/transparent"/>
+ <stroke android:width="1dp" android:color="@color/gesture_tutorial_primary_color"/>
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_home.xml b/quickstep/res/drawable/gesture_tutorial_home.xml
new file mode 100644
index 0000000..e77eb74
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_home.xml
@@ -0,0 +1,394 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="892dp" android:width="412dp" android:viewportHeight="892" android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_4_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_4_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_3_G">
+ <path android:name="_R_G_L_3_G_S" android:fillColor="#000000" android:pathData="M0,0 L412,0 L412,892 L0,892z"/>
+ </group>
+ <group android:name="_R_G_L_2_G" android:scaleY="0">
+ <group android:name="_R_G_L_2_G_L_5_G" android:translateX="206" android:translateY="872" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_5_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_2_G_L_4_G" android:translateX="206" android:translateY="776" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_4_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M180 0 C180,0 180,0 180,0 C180,13.8 168.8,25 155,25 C155,25 -155,25 -155,25 C-168.8,25 -180,13.8 -180,0 C-180,0 -180,0 -180,0 C-180,-13.8 -168.8,-25 -155,-25 C-155,-25 155,-25 155,-25 C168.8,-25 180,-13.8 180,0c "/>
+ </group>
+ <group android:name="_R_G_L_2_G_L_3_G" android:translateX="56" android:translateY="673" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_3_G_D_0_P_0" android:fillColor="#8ab4f8" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c "/>
+ </group>
+ <group android:name="_R_G_L_2_G_L_2_G" android:translateX="156" android:translateY="673" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#f28b82" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c "/>
+ </group>
+ <group android:name="_R_G_L_2_G_L_1_G" android:translateX="256" android:translateY="673" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#fdd663" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c "/>
+ </group>
+ <group android:name="_R_G_L_2_G_L_0_G" android:translateX="356" android:translateY="673" android:scaleY="0">
+ <path android:name="_R_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#81c995" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="206" android:translateY="446" android:scaleX="1" android:scaleY="1">
+ <group android:name="_R_G_L_1_G" android:translateX="-206" android:translateY="-446">
+ <group android:name="_R_G_L_1_G_L_4_G">
+ <group android:name="_R_G_L_1_G_L_4_G_L_11_G" android:translateX="206" android:translateY="472.769" android:scaleX="0.87473" android:scaleY="0.98643">
+ <path android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_10_G" android:translateX="182.5" android:translateY="831">
+ <path android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_9_G" android:translateX="186" android:translateY="801">
+ <path android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -7 C162,-7 162,7 162,7 C162,9.21 160.21,11 158,11 C158,11 -158,11 -158,11 C-160.21,11 -162,9.21 -162,7 C-162,7 -162,-7 -162,-7 C-162,-9.21 -160.21,-11 -158,-11 C-158,-11 158,-11 158,-11 C160.21,-11 162,-9.21 162,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_8_G" android:translateX="119" android:translateY="755">
+ <path android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M95 -7 C95,-7 95,7 95,7 C95,9.21 93.21,11 91,11 C91,11 -91,11 -91,11 C-93.21,11 -95,9.21 -95,7 C-95,7 -95,-7 -95,-7 C-95,-9.21 -93.21,-11 -91,-11 C-91,-11 91,-11 91,-11 C93.21,-11 95,-9.21 95,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_7_G" android:translateX="182.5" android:translateY="725">
+ <path android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_6_G" android:translateX="197.5" android:translateY="695">
+ <path android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M173.5 -7 C173.5,-7 173.5,7 173.5,7 C173.5,9.21 171.71,11 169.5,11 C169.5,11 -169.5,11 -169.5,11 C-171.71,11 -173.5,9.21 -173.5,7 C-173.5,7 -173.5,-7 -173.5,-7 C-173.5,-9.21 -171.71,-11 -169.5,-11 C-169.5,-11 169.5,-11 169.5,-11 C171.71,-11 173.5,-9.21 173.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_5_G" android:translateX="192" android:translateY="665">
+ <path android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M168 -7 C168,-7 168,7 168,7 C168,9.21 166.21,11 164,11 C164,11 -164,11 -164,11 C-166.21,11 -168,9.21 -168,7 C-168,7 -168,-7 -168,-7 C-168,-9.21 -166.21,-11 -164,-11 C-164,-11 164,-11 164,-11 C166.21,-11 168,-9.21 168,-7c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_4_G" android:translateX="105.5" android:translateY="360">
+ <path android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_3_G" android:translateX="47.5" android:translateY="360">
+ <path android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_2_G" android:translateX="142.5" android:translateY="328">
+ <path android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M118.5 -14 C118.5,-14 118.5,14 118.5,14 C118.5,16.21 116.71,18 114.5,18 C114.5,18 -114.5,18 -114.5,18 C-116.71,18 -118.5,16.21 -118.5,14 C-118.5,14 -118.5,-14 -118.5,-14 C-118.5,-16.21 -116.71,-18 -114.5,-18 C-114.5,-18 114.5,-18 114.5,-18 C116.71,-18 118.5,-16.21 118.5,-14c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_1_G" android:translateX="186" android:translateY="284">
+ <path android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -14 C162,-14 162,14 162,14 C162,16.21 160.21,18 158,18 C158,18 -158,18 -158,18 C-160.21,18 -162,16.21 -162,14 C-162,14 -162,-14 -162,-14 C-162,-16.21 -160.21,-18 -158,-18 C-158,-18 158,-18 158,-18 C160.21,-18 162,-16.21 162,-14c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_4_G_L_0_G" android:translateX="155" android:translateY="240">
+ <path android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M131 -14 C131,-14 131,14 131,14 C131,16.21 129.21,18 127,18 C127,18 -127,18 -127,18 C-129.21,18 -131,16.21 -131,14 C-131,14 -131,-14 -131,-14 C-131,-16.21 -129.21,-18 -127,-18 C-127,-18 127,-18 127,-18 C129.21,-18 131,-16.21 131,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G" android:translateX="24" android:translateY="390">
+ <group android:name="_R_G_L_1_G_L_3_G_L_7_G" android:translateX="182" android:translateY="120"/>
+ <group android:name="_R_G_L_1_G_L_3_G_L_6_G" android:translateX="182" android:translateY="120">
+ <path android:name="_R_G_L_1_G_L_3_G_L_6_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M182 -116 C182,-116 182,116 182,116 C182,118.21 180.21,120 178,120 C178,120 -178,120 -178,120 C-180.21,120 -182,118.21 -182,116 C-182,116 -182,-116 -182,-116 C-182,-118.21 -180.21,-120 -178,-120 C-178,-120 178,-120 178,-120 C180.21,-120 182,-118.21 182,-116c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_5_G" android:translateX="77.322" android:translateY="150.552">
+ <path android:name="_R_G_L_1_G_L_3_G_L_5_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ <path android:name="_R_G_L_1_G_L_3_G_L_5_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_4_G" android:translateX="38.772" android:translateY="121.73">
+ <path android:name="_R_G_L_1_G_L_3_G_L_4_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ <path android:name="_R_G_L_1_G_L_3_G_L_4_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_3_G" android:translateX="183" android:translateY="222">
+ <path android:name="_R_G_L_1_G_L_3_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ <path android:name="_R_G_L_1_G_L_3_G_L_3_G_D_1_P_0" android:strokeColor="#9aa0a6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_2_G" android:translateX="265.619" android:translateY="162.331">
+ <path android:name="_R_G_L_1_G_L_3_G_L_2_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ <path android:name="_R_G_L_1_G_L_3_G_L_2_G_D_1_P_0" android:strokeColor="#a8cbfe" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_1_G" android:translateX="319.271" android:translateY="37.945">
+ <path android:name="_R_G_L_1_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#feefc3" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.42 2.99 C14.95,-4.17 9.93,-11.31 2.21,-12.96 C-0.9,-13.62 -3.97,-13.3 -6.64,-12.2 C-6.58,-12.19 -6.53,-12.18 -6.48,-12.17 C-1.03,-11.01 2.52,-5.97 1.44,-0.92 C0.36,4.13 -4.94,7.28 -10.4,6.12 C-11.6,5.86 -12.7,5.42 -13.69,4.83 C-11.9,8.78 -8.15,11.93 -3.34,12.96 C4.38,14.61 11.88,10.14 13.42,2.99c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_3_G_L_0_G" android:translateX="179.5" android:translateY="73.351">
+ <path android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M51.08 -40.95 C51.08,-40.95 50.55,-42.54 50.55,-42.54 C50.55,-42.54 49.67,-41.13 49.67,-41.13 C49.67,-41.13 48.17,-41.21 48.17,-41.21 C48.17,-41.21 49.05,-39.8 49.05,-39.8 C49.05,-39.8 48.61,-38.22 48.61,-38.22 C48.61,-38.22 50.02,-38.74 50.02,-38.74 C50.02,-38.74 51.35,-37.69 51.35,-37.69 C51.35,-37.69 51.26,-39.45 51.26,-39.45 C51.26,-39.45 52.59,-40.42 52.59,-40.42 C52.59,-40.42 51.08,-40.95 51.08,-40.95c M8.78 30.58 C8.78,30.58 8.25,28.99 8.25,28.99 C8.25,28.99 7.37,30.4 7.37,30.4 C7.37,30.4 5.87,30.31 5.87,30.31 C5.87,30.31 6.75,31.72 6.75,31.72 C6.75,31.72 6.31,33.31 6.31,33.31 C6.31,33.31 7.72,32.78 7.72,32.78 C7.72,32.78 9.05,33.84 9.05,33.84 C9.05,33.84 8.96,32.08 8.96,32.08 C8.96,32.08 10.29,31.11 10.29,31.11 C10.29,31.11 8.78,30.58 8.78,30.58c M19.38 -61.67 C19.38,-61.67 18.94,-63.35 18.94,-63.35 C18.94,-63.35 17.97,-61.94 17.97,-61.94 C17.97,-61.94 16.47,-61.94 16.47,-61.94 C16.47,-61.94 17.35,-60.62 17.35,-60.62 C17.35,-60.62 16.91,-58.94 16.91,-58.94 C16.91,-58.94 18.41,-59.56 18.41,-59.56 C18.41,-59.56 19.65,-58.5 19.65,-58.5 C19.65,-58.5 19.56,-60.18 19.56,-60.18 C19.56,-60.18 20.88,-61.23 20.88,-61.23 C20.88,-61.23 19.38,-61.67 19.38,-61.67c M-32.98 35.08 C-32.98,35.08 -33.51,33.4 -33.51,33.4 C-33.51,33.4 -34.4,34.81 -34.4,34.81 C-34.4,34.81 -35.9,34.81 -35.9,34.81 C-35.9,34.81 -35.01,36.22 -35.01,36.22 C-35.01,36.22 -35.45,37.81 -35.45,37.81 C-35.45,37.81 -34.04,37.28 -34.04,37.28 C-34.04,37.28 -32.72,38.25 -32.72,38.25 C-32.72,38.25 -32.81,36.58 -32.81,36.58 C-32.81,36.58 -31.48,35.6 -31.48,35.6 C-31.48,35.6 -32.98,35.08 -32.98,35.08c M45.34 7.56 C45.34,7.56 44.81,5.97 44.81,5.97 C44.81,5.97 43.93,7.38 43.93,7.38 C43.93,7.38 42.34,7.3 42.34,7.3 C42.34,7.3 43.31,8.71 43.31,8.71 C43.31,8.71 42.87,10.29 42.87,10.29 C42.87,10.29 44.28,9.77 44.28,9.77 C44.28,9.77 45.52,10.82 45.52,10.82 C45.52,10.82 45.52,9.06 45.52,9.06 C45.52,9.06 46.76,8.09 46.76,8.09 C46.76,8.09 45.34,7.56 45.34,7.56c M-9.59 -41.67 C-9.59,-41.67 -10.12,-43.35 -10.12,-43.35 C-10.12,-43.35 -11,-41.94 -11,-41.94 C-11,-41.94 -12.5,-41.94 -12.5,-41.94 C-12.5,-41.94 -11.62,-40.62 -11.62,-40.62 C-11.62,-40.62 -12.06,-38.94 -12.06,-38.94 C-12.06,-38.94 -10.65,-39.56 -10.65,-39.56 C-10.65,-39.56 -9.32,-38.5 -9.32,-38.5 C-9.32,-38.5 -9.41,-40.26 -9.41,-40.26 C-9.41,-40.26 -8.09,-41.23 -8.09,-41.23 C-8.09,-41.23 -9.59,-41.67 -9.59,-41.67c M97.74 -23.97 C97.74,-23.97 97.03,-26.35 97.03,-26.35 C97.03,-26.35 95.8,-24.32 95.8,-24.32 C95.8,-24.32 93.5,-24.32 93.5,-24.32 C93.5,-24.32 94.91,-22.38 94.91,-22.38 C94.91,-22.38 94.21,-20 94.21,-20 C94.21,-20 96.33,-20.88 96.33,-20.88 C96.33,-20.88 98.09,-19.38 98.09,-19.38 C98.09,-19.38 98.09,-21.85 98.09,-21.85 C98.09,-21.85 99.86,-23.26 99.86,-23.26 C99.86,-23.26 97.74,-23.97 97.74,-23.97c M167.29 43.28 C167.29,43.28 166.67,40.9 166.67,40.9 C166.67,40.9 165.35,42.93 165.35,42.93 C165.35,42.93 163.14,42.93 163.14,42.93 C163.14,42.93 164.47,44.87 164.47,44.87 C164.47,44.87 163.76,47.25 163.76,47.25 C163.76,47.25 165.88,46.37 165.88,46.37 C165.88,46.37 167.73,47.87 167.73,47.87 C167.73,47.87 167.65,45.4 167.65,45.4 C167.65,45.4 169.5,43.98 169.5,43.98 C169.5,43.98 167.29,43.28 167.29,43.28c M-1.1 -1.79 C-1.1,-1.79 -1.72,-4.08 -1.72,-4.08 C-1.72,-4.08 -3.05,-2.14 -3.05,-2.14 C-3.05,-2.14 -5.25,-2.14 -5.25,-2.14 C-5.25,-2.14 -3.93,-0.11 -3.93,-0.11 C-3.93,-0.11 -4.64,2.18 -4.64,2.18 C-4.64,2.18 -2.52,1.38 -2.52,1.38 C-2.52,1.38 -0.66,2.8 -0.66,2.8 C-0.66,2.8 -0.75,0.41 -0.75,0.41 C-0.75,0.41 1.1,-1.08 1.1,-1.08 C1.1,-1.08 -1.1,-1.79 -1.1,-1.79c M-60.89 -5.23 C-60.89,-5.23 -61.59,-7.61 -61.59,-7.61 C-61.59,-7.61 -62.83,-5.58 -62.83,-5.58 C-62.83,-5.58 -65.13,-5.58 -65.13,-5.58 C-65.13,-5.58 -63.71,-3.64 -63.71,-3.64 C-63.71,-3.64 -64.42,-1.26 -64.42,-1.26 C-64.42,-1.26 -62.39,-2.14 -62.39,-2.14 C-62.39,-2.14 -60.53,-0.64 -60.53,-0.64 C-60.53,-0.64 -60.62,-3.11 -60.62,-3.11 C-60.62,-3.11 -58.77,-4.52 -58.77,-4.52 C-58.77,-4.52 -60.89,-5.23 -60.89,-5.23c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-51.26 -42.98 C-51.26,-42.98 -54.09,-45.01 -54.09,-45.01 C-54.09,-45.01 -53.91,-41.57 -53.91,-41.57 C-53.91,-41.57 -56.65,-39.54 -56.65,-39.54 C-56.65,-39.54 -53.38,-38.57 -53.38,-38.57 C-53.38,-38.57 -52.32,-35.3 -52.32,-35.3 C-52.32,-35.3 -50.38,-38.13 -50.38,-38.13 C-50.38,-38.13 -46.94,-38.22 -46.94,-38.22 C-46.94,-38.22 -49.05,-40.86 -49.05,-40.86 C-49.05,-40.86 -47.99,-44.21 -47.99,-44.21 C-47.99,-44.21 -51.26,-42.98 -51.26,-42.98c M-92.06 -47.92 C-92.06,-47.92 -92.59,-49.59 -92.59,-49.59 C-92.59,-49.59 -93.47,-48.18 -93.47,-48.18 C-93.47,-48.18 -95.06,-48.18 -95.06,-48.18 C-95.06,-48.18 -94.09,-46.86 -94.09,-46.86 C-94.09,-46.86 -94.53,-45.18 -94.53,-45.18 C-94.53,-45.18 -93.12,-45.8 -93.12,-45.8 C-93.12,-45.8 -91.88,-44.74 -91.88,-44.74 C-91.88,-44.74 -91.88,-46.42 -91.88,-46.42 C-91.88,-46.42 -90.65,-47.47 -90.65,-47.47 C-90.65,-47.47 -92.06,-47.92 -92.06,-47.92c M62.83 -13.34 C62.83,-13.34 62.39,-14.93 62.39,-14.93 C62.39,-14.93 61.5,-13.52 61.5,-13.52 C61.5,-13.52 59.91,-13.52 59.91,-13.52 C59.91,-13.52 60.89,-12.2 60.89,-12.2 C60.89,-12.2 60.36,-10.52 60.36,-10.52 C60.36,-10.52 61.86,-11.14 61.86,-11.14 C61.86,-11.14 63.09,-10.08 63.09,-10.08 C63.09,-10.08 63.09,-11.84 63.09,-11.84 C63.09,-11.84 64.33,-12.81 64.33,-12.81 C64.33,-12.81 62.83,-13.34 62.83,-13.34c M-155.99 -40.95 C-155.99,-40.95 -156.43,-42.54 -156.43,-42.54 C-156.43,-42.54 -157.32,-41.13 -157.32,-41.13 C-157.32,-41.13 -158.91,-41.21 -158.91,-41.21 C-158.91,-41.21 -157.93,-39.8 -157.93,-39.8 C-157.93,-39.8 -158.46,-38.22 -158.46,-38.22 C-158.46,-38.22 -156.96,-38.74 -156.96,-38.74 C-156.96,-38.74 -155.73,-37.69 -155.73,-37.69 C-155.73,-37.69 -155.73,-39.45 -155.73,-39.45 C-155.73,-39.45 -154.49,-40.42 -154.49,-40.42 C-154.49,-40.42 -155.99,-40.95 -155.99,-40.95c M141.24 26.52 C141.24,26.52 140.71,24.85 140.71,24.85 C140.71,24.85 139.83,26.26 139.83,26.26 C139.83,26.26 138.33,26.26 138.33,26.26 C138.33,26.26 139.21,27.67 139.21,27.67 C139.21,27.67 138.77,29.26 138.77,29.26 C138.77,29.26 140.18,28.73 140.18,28.73 C140.18,28.73 141.51,29.7 141.51,29.7 C141.51,29.7 141.42,28.02 141.42,28.02 C141.42,28.02 142.74,27.05 142.74,27.05 C142.74,27.05 141.24,26.52 141.24,26.52c M111.4 -51.27 C111.4,-51.27 110.95,-52.94 110.95,-52.94 C110.95,-52.94 110.07,-51.53 110.07,-51.53 C110.07,-51.53 108.48,-51.53 108.48,-51.53 C108.48,-51.53 109.45,-50.21 109.45,-50.21 C109.45,-50.21 108.92,-48.53 108.92,-48.53 C108.92,-48.53 110.42,-49.15 110.42,-49.15 C110.42,-49.15 111.66,-48.09 111.66,-48.09 C111.66,-48.09 111.66,-49.86 111.66,-49.86 C111.66,-49.86 112.9,-50.83 112.9,-50.83 C112.9,-50.83 111.4,-51.27 111.4,-51.27c M-66.59 53.33 C-66.59,53.33 -67.03,51.65 -67.03,51.65 C-67.03,51.65 -67.91,53.06 -67.91,53.06 C-67.91,53.06 -69.5,53.06 -69.5,53.06 C-69.5,53.06 -68.53,54.47 -68.53,54.47 C-68.53,54.47 -69.06,56.06 -69.06,56.06 C-69.06,56.06 -67.56,55.53 -67.56,55.53 C-67.56,55.53 -66.32,56.5 -66.32,56.5 C-66.32,56.5 -66.32,54.82 -66.32,54.82 C-66.32,54.82 -65.08,53.77 -65.08,53.77 C-65.08,53.77 -66.59,53.33 -66.59,53.33c M-50.59 59.33 C-50.59,59.33 -51.12,57.65 -51.12,57.65 C-51.12,57.65 -52,59.06 -52,59.06 C-52,59.06 -53.5,59.06 -53.5,59.06 C-53.5,59.06 -52.62,60.38 -52.62,60.38 C-52.62,60.38 -53.06,62.06 -53.06,62.06 C-53.06,62.06 -51.65,61.53 -51.65,61.53 C-51.65,61.53 -50.32,62.5 -50.32,62.5 C-50.32,62.5 -50.41,60.82 -50.41,60.82 C-50.41,60.82 -49.08,59.77 -49.08,59.77 C-49.08,59.77 -50.59,59.33 -50.59,59.33c M29.98 -16.08 C29.98,-16.08 29.27,-18.46 29.27,-18.46 C29.27,-18.46 27.95,-16.43 27.95,-16.43 C27.95,-16.43 25.74,-16.43 25.74,-16.43 C25.74,-16.43 27.06,-14.49 27.06,-14.49 C27.06,-14.49 26.36,-12.11 26.36,-12.11 C26.36,-12.11 28.48,-12.9 28.48,-12.9 C28.48,-12.9 30.33,-11.49 30.33,-11.49 C30.33,-11.49 30.24,-13.96 30.24,-13.96 C30.24,-13.96 32.1,-15.37 32.1,-15.37 C32.1,-15.37 29.98,-16.08 29.98,-16.08c M81.28 55.98 C81.28,55.98 80.58,53.6 80.58,53.6 C80.58,53.6 79.25,55.63 79.25,55.63 C79.25,55.63 77.04,55.63 77.04,55.63 C77.04,55.63 78.37,57.57 78.37,57.57 C78.37,57.57 77.66,59.95 77.66,59.95 C77.66,59.95 79.78,59.07 79.78,59.07 C79.78,59.07 81.64,60.56 81.64,60.56 C81.64,60.56 81.55,58.1 81.55,58.1 C81.55,58.1 83.4,56.68 83.4,56.68 C83.4,56.68 81.28,55.98 81.28,55.98c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-74.05 21.76 C-74.05,21.76 -74.66,19.47 -74.66,19.47 C-74.66,19.47 -75.99,21.49 -75.99,21.49 C-75.99,21.49 -78.2,21.41 -78.2,21.41 C-78.2,21.41 -76.87,23.43 -76.87,23.43 C-76.87,23.43 -77.58,25.73 -77.58,25.73 C-77.58,25.73 -75.46,24.93 -75.46,24.93 C-75.46,24.93 -73.6,26.43 -73.6,26.43 C-73.6,26.43 -73.69,23.96 -73.69,23.96 C-73.69,23.96 -71.84,22.46 -71.84,22.46 C-71.84,22.46 -74.05,21.76 -74.05,21.76c M8.98 55.68 C8.98,55.68 6.15,53.65 6.15,53.65 C6.15,53.65 6.24,57.09 6.24,57.09 C6.24,57.09 3.5,59.12 3.5,59.12 C3.5,59.12 6.86,60.09 6.86,60.09 C6.86,60.09 7.92,63.35 7.92,63.35 C7.92,63.35 9.86,60.44 9.86,60.44 C9.86,60.44 13.3,60.44 13.3,60.44 C13.3,60.44 11.18,57.71 11.18,57.71 C11.18,57.71 12.15,54.44 12.15,54.44 C12.15,54.44 8.98,55.68 8.98,55.68c M124.89 -2.41 C124.89,-2.41 122.06,-4.35 122.06,-4.35 C122.06,-4.35 122.24,-0.91 122.24,-0.91 C122.24,-0.91 119.5,1.12 119.5,1.12 C119.5,1.12 122.77,2 122.77,2 C122.77,2 123.83,5.26 123.83,5.26 C123.83,5.26 125.77,2.44 125.77,2.44 C125.77,2.44 129.21,2.44 129.21,2.44 C129.21,2.44 127.09,-0.29 127.09,-0.29 C127.09,-0.29 128.15,-3.56 128.15,-3.56 C128.15,-3.56 124.89,-2.41 124.89,-2.41c M77.31 19.91 C77.31,19.91 74.57,17.88 74.57,17.88 C74.57,17.88 74.66,21.32 74.66,21.32 C74.66,21.32 71.92,23.35 71.92,23.35 C71.92,23.35 75.19,24.32 75.19,24.32 C75.19,24.32 76.34,27.58 76.34,27.58 C76.34,27.58 78.19,24.67 78.19,24.67 C78.19,24.67 81.64,24.67 81.64,24.67 C81.64,24.67 79.52,21.94 79.52,21.94 C79.52,21.94 80.58,18.67 80.58,18.67 C80.58,18.67 77.31,19.91 77.31,19.91c M-28.11 7.68 C-28.11,7.68 -30.94,5.65 -30.94,5.65 C-30.94,5.65 -30.76,9.09 -30.76,9.09 C-30.76,9.09 -33.5,11.12 -33.5,11.12 C-33.5,11.12 -30.23,12.09 -30.23,12.09 C-30.23,12.09 -29.17,15.35 -29.17,15.35 C-29.17,15.35 -27.23,12.44 -27.23,12.44 C-27.23,12.44 -23.79,12.44 -23.79,12.44 C-23.79,12.44 -25.91,9.71 -25.91,9.71 C-25.91,9.71 -24.85,6.44 -24.85,6.44 C-24.85,6.44 -28.11,7.68 -28.11,7.68c M-119.43 -20.22 C-119.43,-20.22 -122.26,-22.16 -122.26,-22.16 C-122.26,-22.16 -122.08,-18.72 -122.08,-18.72 C-122.08,-18.72 -124.82,-16.7 -124.82,-16.7 C-124.82,-16.7 -121.55,-15.81 -121.55,-15.81 C-121.55,-15.81 -120.49,-12.55 -120.49,-12.55 C-120.49,-12.55 -118.55,-15.37 -118.55,-15.37 C-118.55,-15.37 -115.11,-15.37 -115.11,-15.37 C-115.11,-15.37 -117.23,-18.11 -117.23,-18.11 C-117.23,-18.11 -116.17,-21.37 -116.17,-21.37 C-116.17,-21.37 -119.43,-20.22 -119.43,-20.22c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_2_G">
+ <group android:name="_R_G_L_1_G_L_2_G_L_2_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#e8eaed" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_2_G_L_1_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_2_G_L_0_G" android:translateX="46" android:translateY="145">
+ <path android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_1_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_1_G_L_1_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_0_G">
+ <group android:name="_R_G_L_1_G_L_0_G_L_2_G" android:translateX="206" android:translateY="51">
+ <path android:name="_R_G_L_1_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_0_G_L_1_G" android:translateX="206" android:translateY="50.5">
+ <path android:name="_R_G_L_1_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c "/>
+ </group>
+ <group android:name="_R_G_L_1_G_L_0_G_L_0_G" android:translateX="206" android:translateY="66.5">
+ <path android:name="_R_G_L_1_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-30" android:translateY="658.997" android:pivotX="300" android:pivotY="64" android:rotation="-90" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M-166 64 C-130.65,64 -102,35.35 -102,0 C-102,-35.34 -130.65,-64 -166,-64 C-201.34,-64 -230,-35.34 -230,0 C-230,35.35 -201.34,64 -166,64c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="192" android:translateY="63.997" android:rotation="90" android:scaleX="-1" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0" android:translateX="-166" android:translateY="0">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 64 C35.35,64 64,35.35 64,0 C64,-35.34 35.35,-64 0,-64 C-35.34,-64 -64,-35.34 -64,0 C-64,35.35 -35.34,64 0,64c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_2_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="50" android:startOffset="1917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,776C 206,776 206,776 206,776">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="700" android:startOffset="1967" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,776C 206,776 206,797 206,797">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1967" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="700" android:startOffset="1917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 56,673C 56,673 56,706 56,706">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="700" android:startOffset="1917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 156,673C 156,673 156,706 156,706">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="700" android:startOffset="1917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 256,673C 256,673 256,706 256,706">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="700" android:startOffset="1917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 356,673C 356,673 356,706 356,706">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1917" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_1_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1533" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,446C 206,446 206,446 206,446">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.477,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="317" android:startOffset="1533" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,446C 206,446 206,354.603 206,354.603">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.477,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="300" android:startOffset="1850" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,354.603C 206,354.603 206,639 206,639">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.531,0.542 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_1_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="1533" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="1533" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="617" android:startOffset="1533" android:valueFrom="1" android:valueTo="0.16" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="617" android:startOffset="1533" android:valueFrom="1" android:valueTo="0.16" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="600" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1550" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="217" android:startOffset="1317" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="383" android:startOffset="1533" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M-0.01 363.74 C35.34,363.74 63.99,335.09 63.99,299.75 C63.99,299.75 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64.01,299.75 -64.01,299.75 C-64.01,335.09 -35.35,363.74 -0.01,363.74c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1550" android:valueFrom="0" android:valueTo="-1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2050" android:valueFrom="-1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="217" android:startOffset="1317" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -105.667,0 -226.333,0 -166,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="383" android:startOffset="1533" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -105.667,0 135.667,0 196,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.508,0 0.487,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="600" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2050" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1317" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2050" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="4017" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_overview.xml b/quickstep/res/drawable/gesture_tutorial_overview.xml
new file mode 100644
index 0000000..c4ca72f
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_overview.xml
@@ -0,0 +1,823 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="892dp" android:width="412dp" android:viewportHeight="892" android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_7_G" android:translateX="206" android:translateY="446">
+ <path android:name="_R_G_L_7_G_D_0_P_0" android:fillColor="#666666" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c "/>
+ </group>
+ <group android:name="_R_G_L_6_G">
+ <path android:name="_R_G_L_6_G_S" android:fillColor="#000000" android:pathData="M0,0 L412,0 L412,892 L0,892z"/>
+ </group>
+ <group android:name="_R_G_L_5_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_5_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_N_7_T_0" android:translateX="206" android:translateY="446" android:scaleX="1" android:scaleY="1">
+ <group android:name="_R_G_L_4_G" android:translateX="-206" android:translateY="-446">
+ <group android:name="_R_G_L_4_G_L_4_G">
+ <group android:name="_R_G_L_4_G_L_4_G_L_11_G" android:translateX="206" android:translateY="467">
+ <path android:name="_R_G_L_4_G_L_4_G_L_11_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -407 C206,-407 206,407 206,407 C206,416.93 197.93,425 188,425 C188,425 -188,425 -188,425 C-197.93,425 -206,416.93 -206,407 C-206,407 -206,-407 -206,-407 C-206,-416.93 -197.93,-425 -188,-425 C-188,-425 188,-425 188,-425 C197.93,-425 206,-416.93 206,-407c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_10_G" android:translateX="182.5" android:translateY="831">
+ <path android:name="_R_G_L_4_G_L_4_G_L_10_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_9_G" android:translateX="186" android:translateY="801">
+ <path android:name="_R_G_L_4_G_L_4_G_L_9_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -7 C162,-7 162,7 162,7 C162,9.21 160.21,11 158,11 C158,11 -158,11 -158,11 C-160.21,11 -162,9.21 -162,7 C-162,7 -162,-7 -162,-7 C-162,-9.21 -160.21,-11 -158,-11 C-158,-11 158,-11 158,-11 C160.21,-11 162,-9.21 162,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_8_G" android:translateX="119" android:translateY="755">
+ <path android:name="_R_G_L_4_G_L_4_G_L_8_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M95 -7 C95,-7 95,7 95,7 C95,9.21 93.21,11 91,11 C91,11 -91,11 -91,11 C-93.21,11 -95,9.21 -95,7 C-95,7 -95,-7 -95,-7 C-95,-9.21 -93.21,-11 -91,-11 C-91,-11 91,-11 91,-11 C93.21,-11 95,-9.21 95,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_7_G" android:translateX="182.5" android:translateY="725">
+ <path android:name="_R_G_L_4_G_L_4_G_L_7_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_6_G" android:translateX="197.5" android:translateY="695">
+ <path android:name="_R_G_L_4_G_L_4_G_L_6_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M173.5 -7 C173.5,-7 173.5,7 173.5,7 C173.5,9.21 171.71,11 169.5,11 C169.5,11 -169.5,11 -169.5,11 C-171.71,11 -173.5,9.21 -173.5,7 C-173.5,7 -173.5,-7 -173.5,-7 C-173.5,-9.21 -171.71,-11 -169.5,-11 C-169.5,-11 169.5,-11 169.5,-11 C171.71,-11 173.5,-9.21 173.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_5_G" android:translateX="192" android:translateY="665">
+ <path android:name="_R_G_L_4_G_L_4_G_L_5_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M168 -7 C168,-7 168,7 168,7 C168,9.21 166.21,11 164,11 C164,11 -164,11 -164,11 C-166.21,11 -168,9.21 -168,7 C-168,7 -168,-7 -168,-7 C-168,-9.21 -166.21,-11 -164,-11 C-164,-11 164,-11 164,-11 C166.21,-11 168,-9.21 168,-7c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_4_G" android:translateX="105.5" android:translateY="360">
+ <path android:name="_R_G_L_4_G_L_4_G_L_4_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_3_G" android:translateX="47.5" android:translateY="360">
+ <path android:name="_R_G_L_4_G_L_4_G_L_3_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_2_G" android:translateX="142.5" android:translateY="328">
+ <path android:name="_R_G_L_4_G_L_4_G_L_2_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M118.5 -14 C118.5,-14 118.5,14 118.5,14 C118.5,16.21 116.71,18 114.5,18 C114.5,18 -114.5,18 -114.5,18 C-116.71,18 -118.5,16.21 -118.5,14 C-118.5,14 -118.5,-14 -118.5,-14 C-118.5,-16.21 -116.71,-18 -114.5,-18 C-114.5,-18 114.5,-18 114.5,-18 C116.71,-18 118.5,-16.21 118.5,-14c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_1_G" android:translateX="186" android:translateY="284">
+ <path android:name="_R_G_L_4_G_L_4_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -14 C162,-14 162,14 162,14 C162,16.21 160.21,18 158,18 C158,18 -158,18 -158,18 C-160.21,18 -162,16.21 -162,14 C-162,14 -162,-14 -162,-14 C-162,-16.21 -160.21,-18 -158,-18 C-158,-18 158,-18 158,-18 C160.21,-18 162,-16.21 162,-14c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_4_G_L_0_G" android:translateX="155" android:translateY="240">
+ <path android:name="_R_G_L_4_G_L_4_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M131 -14 C131,-14 131,14 131,14 C131,16.21 129.21,18 127,18 C127,18 -127,18 -127,18 C-129.21,18 -131,16.21 -131,14 C-131,14 -131,-14 -131,-14 C-131,-16.21 -129.21,-18 -127,-18 C-127,-18 127,-18 127,-18 C129.21,-18 131,-16.21 131,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G" android:translateX="24" android:translateY="390">
+ <group android:name="_R_G_L_4_G_L_3_G_L_7_G" android:translateX="182" android:translateY="120"/>
+ <group android:name="_R_G_L_4_G_L_3_G_L_6_G" android:translateX="182" android:translateY="120">
+ <path android:name="_R_G_L_4_G_L_3_G_L_6_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M182 -116 C182,-116 182,116 182,116 C182,118.21 180.21,120 178,120 C178,120 -178,120 -178,120 C-180.21,120 -182,118.21 -182,116 C-182,116 -182,-116 -182,-116 C-182,-118.21 -180.21,-120 -178,-120 C-178,-120 178,-120 178,-120 C180.21,-120 182,-118.21 182,-116c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_5_G" android:translateX="77.322" android:translateY="150.552">
+ <path android:name="_R_G_L_4_G_L_3_G_L_5_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ <path android:name="_R_G_L_4_G_L_3_G_L_5_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_4_G" android:translateX="38.772" android:translateY="121.73">
+ <path android:name="_R_G_L_4_G_L_3_G_L_4_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ <path android:name="_R_G_L_4_G_L_3_G_L_4_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_3_G" android:translateX="183" android:translateY="222">
+ <path android:name="_R_G_L_4_G_L_3_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ <path android:name="_R_G_L_4_G_L_3_G_L_3_G_D_1_P_0" android:strokeColor="#9aa0a6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_2_G" android:translateX="265.619" android:translateY="162.331">
+ <path android:name="_R_G_L_4_G_L_3_G_L_2_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ <path android:name="_R_G_L_4_G_L_3_G_L_2_G_D_1_P_0" android:strokeColor="#a8cbfe" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_1_G" android:translateX="319.271" android:translateY="37.945">
+ <path android:name="_R_G_L_4_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#feefc3" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.42 2.99 C14.95,-4.17 9.93,-11.31 2.21,-12.96 C-0.9,-13.62 -3.97,-13.3 -6.64,-12.2 C-6.58,-12.19 -6.53,-12.18 -6.48,-12.17 C-1.03,-11.01 2.52,-5.97 1.44,-0.92 C0.36,4.13 -4.94,7.28 -10.4,6.12 C-11.6,5.86 -12.7,5.42 -13.69,4.83 C-11.9,8.78 -8.15,11.93 -3.34,12.96 C4.38,14.61 11.88,10.14 13.42,2.99c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_3_G_L_0_G" android:translateX="179.5" android:translateY="73.351">
+ <path android:name="_R_G_L_4_G_L_3_G_L_0_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M51.08 -40.95 C51.08,-40.95 50.55,-42.54 50.55,-42.54 C50.55,-42.54 49.67,-41.13 49.67,-41.13 C49.67,-41.13 48.17,-41.21 48.17,-41.21 C48.17,-41.21 49.05,-39.8 49.05,-39.8 C49.05,-39.8 48.61,-38.22 48.61,-38.22 C48.61,-38.22 50.02,-38.74 50.02,-38.74 C50.02,-38.74 51.35,-37.69 51.35,-37.69 C51.35,-37.69 51.26,-39.45 51.26,-39.45 C51.26,-39.45 52.59,-40.42 52.59,-40.42 C52.59,-40.42 51.08,-40.95 51.08,-40.95c M8.78 30.58 C8.78,30.58 8.25,28.99 8.25,28.99 C8.25,28.99 7.37,30.4 7.37,30.4 C7.37,30.4 5.87,30.31 5.87,30.31 C5.87,30.31 6.75,31.72 6.75,31.72 C6.75,31.72 6.31,33.31 6.31,33.31 C6.31,33.31 7.72,32.78 7.72,32.78 C7.72,32.78 9.05,33.84 9.05,33.84 C9.05,33.84 8.96,32.08 8.96,32.08 C8.96,32.08 10.29,31.11 10.29,31.11 C10.29,31.11 8.78,30.58 8.78,30.58c M19.38 -61.67 C19.38,-61.67 18.94,-63.35 18.94,-63.35 C18.94,-63.35 17.97,-61.94 17.97,-61.94 C17.97,-61.94 16.47,-61.94 16.47,-61.94 C16.47,-61.94 17.35,-60.62 17.35,-60.62 C17.35,-60.62 16.91,-58.94 16.91,-58.94 C16.91,-58.94 18.41,-59.56 18.41,-59.56 C18.41,-59.56 19.65,-58.5 19.65,-58.5 C19.65,-58.5 19.56,-60.18 19.56,-60.18 C19.56,-60.18 20.88,-61.23 20.88,-61.23 C20.88,-61.23 19.38,-61.67 19.38,-61.67c M-32.98 35.08 C-32.98,35.08 -33.51,33.4 -33.51,33.4 C-33.51,33.4 -34.4,34.81 -34.4,34.81 C-34.4,34.81 -35.9,34.81 -35.9,34.81 C-35.9,34.81 -35.01,36.22 -35.01,36.22 C-35.01,36.22 -35.45,37.81 -35.45,37.81 C-35.45,37.81 -34.04,37.28 -34.04,37.28 C-34.04,37.28 -32.72,38.25 -32.72,38.25 C-32.72,38.25 -32.81,36.58 -32.81,36.58 C-32.81,36.58 -31.48,35.6 -31.48,35.6 C-31.48,35.6 -32.98,35.08 -32.98,35.08c M45.34 7.56 C45.34,7.56 44.81,5.97 44.81,5.97 C44.81,5.97 43.93,7.38 43.93,7.38 C43.93,7.38 42.34,7.3 42.34,7.3 C42.34,7.3 43.31,8.71 43.31,8.71 C43.31,8.71 42.87,10.29 42.87,10.29 C42.87,10.29 44.28,9.77 44.28,9.77 C44.28,9.77 45.52,10.82 45.52,10.82 C45.52,10.82 45.52,9.06 45.52,9.06 C45.52,9.06 46.76,8.09 46.76,8.09 C46.76,8.09 45.34,7.56 45.34,7.56c M-9.59 -41.67 C-9.59,-41.67 -10.12,-43.35 -10.12,-43.35 C-10.12,-43.35 -11,-41.94 -11,-41.94 C-11,-41.94 -12.5,-41.94 -12.5,-41.94 C-12.5,-41.94 -11.62,-40.62 -11.62,-40.62 C-11.62,-40.62 -12.06,-38.94 -12.06,-38.94 C-12.06,-38.94 -10.65,-39.56 -10.65,-39.56 C-10.65,-39.56 -9.32,-38.5 -9.32,-38.5 C-9.32,-38.5 -9.41,-40.26 -9.41,-40.26 C-9.41,-40.26 -8.09,-41.23 -8.09,-41.23 C-8.09,-41.23 -9.59,-41.67 -9.59,-41.67c M97.74 -23.97 C97.74,-23.97 97.03,-26.35 97.03,-26.35 C97.03,-26.35 95.8,-24.32 95.8,-24.32 C95.8,-24.32 93.5,-24.32 93.5,-24.32 C93.5,-24.32 94.91,-22.38 94.91,-22.38 C94.91,-22.38 94.21,-20 94.21,-20 C94.21,-20 96.33,-20.88 96.33,-20.88 C96.33,-20.88 98.09,-19.38 98.09,-19.38 C98.09,-19.38 98.09,-21.85 98.09,-21.85 C98.09,-21.85 99.86,-23.26 99.86,-23.26 C99.86,-23.26 97.74,-23.97 97.74,-23.97c M167.29 43.28 C167.29,43.28 166.67,40.9 166.67,40.9 C166.67,40.9 165.35,42.93 165.35,42.93 C165.35,42.93 163.14,42.93 163.14,42.93 C163.14,42.93 164.47,44.87 164.47,44.87 C164.47,44.87 163.76,47.25 163.76,47.25 C163.76,47.25 165.88,46.37 165.88,46.37 C165.88,46.37 167.73,47.87 167.73,47.87 C167.73,47.87 167.65,45.4 167.65,45.4 C167.65,45.4 169.5,43.98 169.5,43.98 C169.5,43.98 167.29,43.28 167.29,43.28c M-1.1 -1.79 C-1.1,-1.79 -1.72,-4.08 -1.72,-4.08 C-1.72,-4.08 -3.05,-2.14 -3.05,-2.14 C-3.05,-2.14 -5.25,-2.14 -5.25,-2.14 C-5.25,-2.14 -3.93,-0.11 -3.93,-0.11 C-3.93,-0.11 -4.64,2.18 -4.64,2.18 C-4.64,2.18 -2.52,1.38 -2.52,1.38 C-2.52,1.38 -0.66,2.8 -0.66,2.8 C-0.66,2.8 -0.75,0.41 -0.75,0.41 C-0.75,0.41 1.1,-1.08 1.1,-1.08 C1.1,-1.08 -1.1,-1.79 -1.1,-1.79c M-60.89 -5.23 C-60.89,-5.23 -61.59,-7.61 -61.59,-7.61 C-61.59,-7.61 -62.83,-5.58 -62.83,-5.58 C-62.83,-5.58 -65.13,-5.58 -65.13,-5.58 C-65.13,-5.58 -63.71,-3.64 -63.71,-3.64 C-63.71,-3.64 -64.42,-1.26 -64.42,-1.26 C-64.42,-1.26 -62.39,-2.14 -62.39,-2.14 C-62.39,-2.14 -60.53,-0.64 -60.53,-0.64 C-60.53,-0.64 -60.62,-3.11 -60.62,-3.11 C-60.62,-3.11 -58.77,-4.52 -58.77,-4.52 C-58.77,-4.52 -60.89,-5.23 -60.89,-5.23c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-51.26 -42.98 C-51.26,-42.98 -54.09,-45.01 -54.09,-45.01 C-54.09,-45.01 -53.91,-41.57 -53.91,-41.57 C-53.91,-41.57 -56.65,-39.54 -56.65,-39.54 C-56.65,-39.54 -53.38,-38.57 -53.38,-38.57 C-53.38,-38.57 -52.32,-35.3 -52.32,-35.3 C-52.32,-35.3 -50.38,-38.13 -50.38,-38.13 C-50.38,-38.13 -46.94,-38.22 -46.94,-38.22 C-46.94,-38.22 -49.05,-40.86 -49.05,-40.86 C-49.05,-40.86 -47.99,-44.21 -47.99,-44.21 C-47.99,-44.21 -51.26,-42.98 -51.26,-42.98c M-92.06 -47.92 C-92.06,-47.92 -92.59,-49.59 -92.59,-49.59 C-92.59,-49.59 -93.47,-48.18 -93.47,-48.18 C-93.47,-48.18 -95.06,-48.18 -95.06,-48.18 C-95.06,-48.18 -94.09,-46.86 -94.09,-46.86 C-94.09,-46.86 -94.53,-45.18 -94.53,-45.18 C-94.53,-45.18 -93.12,-45.8 -93.12,-45.8 C-93.12,-45.8 -91.88,-44.74 -91.88,-44.74 C-91.88,-44.74 -91.88,-46.42 -91.88,-46.42 C-91.88,-46.42 -90.65,-47.47 -90.65,-47.47 C-90.65,-47.47 -92.06,-47.92 -92.06,-47.92c M62.83 -13.34 C62.83,-13.34 62.39,-14.93 62.39,-14.93 C62.39,-14.93 61.5,-13.52 61.5,-13.52 C61.5,-13.52 59.91,-13.52 59.91,-13.52 C59.91,-13.52 60.89,-12.2 60.89,-12.2 C60.89,-12.2 60.36,-10.52 60.36,-10.52 C60.36,-10.52 61.86,-11.14 61.86,-11.14 C61.86,-11.14 63.09,-10.08 63.09,-10.08 C63.09,-10.08 63.09,-11.84 63.09,-11.84 C63.09,-11.84 64.33,-12.81 64.33,-12.81 C64.33,-12.81 62.83,-13.34 62.83,-13.34c M-155.99 -40.95 C-155.99,-40.95 -156.43,-42.54 -156.43,-42.54 C-156.43,-42.54 -157.32,-41.13 -157.32,-41.13 C-157.32,-41.13 -158.91,-41.21 -158.91,-41.21 C-158.91,-41.21 -157.93,-39.8 -157.93,-39.8 C-157.93,-39.8 -158.46,-38.22 -158.46,-38.22 C-158.46,-38.22 -156.96,-38.74 -156.96,-38.74 C-156.96,-38.74 -155.73,-37.69 -155.73,-37.69 C-155.73,-37.69 -155.73,-39.45 -155.73,-39.45 C-155.73,-39.45 -154.49,-40.42 -154.49,-40.42 C-154.49,-40.42 -155.99,-40.95 -155.99,-40.95c M141.24 26.52 C141.24,26.52 140.71,24.85 140.71,24.85 C140.71,24.85 139.83,26.26 139.83,26.26 C139.83,26.26 138.33,26.26 138.33,26.26 C138.33,26.26 139.21,27.67 139.21,27.67 C139.21,27.67 138.77,29.26 138.77,29.26 C138.77,29.26 140.18,28.73 140.18,28.73 C140.18,28.73 141.51,29.7 141.51,29.7 C141.51,29.7 141.42,28.02 141.42,28.02 C141.42,28.02 142.74,27.05 142.74,27.05 C142.74,27.05 141.24,26.52 141.24,26.52c M111.4 -51.27 C111.4,-51.27 110.95,-52.94 110.95,-52.94 C110.95,-52.94 110.07,-51.53 110.07,-51.53 C110.07,-51.53 108.48,-51.53 108.48,-51.53 C108.48,-51.53 109.45,-50.21 109.45,-50.21 C109.45,-50.21 108.92,-48.53 108.92,-48.53 C108.92,-48.53 110.42,-49.15 110.42,-49.15 C110.42,-49.15 111.66,-48.09 111.66,-48.09 C111.66,-48.09 111.66,-49.86 111.66,-49.86 C111.66,-49.86 112.9,-50.83 112.9,-50.83 C112.9,-50.83 111.4,-51.27 111.4,-51.27c M-66.59 53.33 C-66.59,53.33 -67.03,51.65 -67.03,51.65 C-67.03,51.65 -67.91,53.06 -67.91,53.06 C-67.91,53.06 -69.5,53.06 -69.5,53.06 C-69.5,53.06 -68.53,54.47 -68.53,54.47 C-68.53,54.47 -69.06,56.06 -69.06,56.06 C-69.06,56.06 -67.56,55.53 -67.56,55.53 C-67.56,55.53 -66.32,56.5 -66.32,56.5 C-66.32,56.5 -66.32,54.82 -66.32,54.82 C-66.32,54.82 -65.08,53.77 -65.08,53.77 C-65.08,53.77 -66.59,53.33 -66.59,53.33c M-50.59 59.33 C-50.59,59.33 -51.12,57.65 -51.12,57.65 C-51.12,57.65 -52,59.06 -52,59.06 C-52,59.06 -53.5,59.06 -53.5,59.06 C-53.5,59.06 -52.62,60.38 -52.62,60.38 C-52.62,60.38 -53.06,62.06 -53.06,62.06 C-53.06,62.06 -51.65,61.53 -51.65,61.53 C-51.65,61.53 -50.32,62.5 -50.32,62.5 C-50.32,62.5 -50.41,60.82 -50.41,60.82 C-50.41,60.82 -49.08,59.77 -49.08,59.77 C-49.08,59.77 -50.59,59.33 -50.59,59.33c M29.98 -16.08 C29.98,-16.08 29.27,-18.46 29.27,-18.46 C29.27,-18.46 27.95,-16.43 27.95,-16.43 C27.95,-16.43 25.74,-16.43 25.74,-16.43 C25.74,-16.43 27.06,-14.49 27.06,-14.49 C27.06,-14.49 26.36,-12.11 26.36,-12.11 C26.36,-12.11 28.48,-12.9 28.48,-12.9 C28.48,-12.9 30.33,-11.49 30.33,-11.49 C30.33,-11.49 30.24,-13.96 30.24,-13.96 C30.24,-13.96 32.1,-15.37 32.1,-15.37 C32.1,-15.37 29.98,-16.08 29.98,-16.08c M81.28 55.98 C81.28,55.98 80.58,53.6 80.58,53.6 C80.58,53.6 79.25,55.63 79.25,55.63 C79.25,55.63 77.04,55.63 77.04,55.63 C77.04,55.63 78.37,57.57 78.37,57.57 C78.37,57.57 77.66,59.95 77.66,59.95 C77.66,59.95 79.78,59.07 79.78,59.07 C79.78,59.07 81.64,60.56 81.64,60.56 C81.64,60.56 81.55,58.1 81.55,58.1 C81.55,58.1 83.4,56.68 83.4,56.68 C83.4,56.68 81.28,55.98 81.28,55.98c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-74.05 21.76 C-74.05,21.76 -74.66,19.47 -74.66,19.47 C-74.66,19.47 -75.99,21.49 -75.99,21.49 C-75.99,21.49 -78.2,21.41 -78.2,21.41 C-78.2,21.41 -76.87,23.43 -76.87,23.43 C-76.87,23.43 -77.58,25.73 -77.58,25.73 C-77.58,25.73 -75.46,24.93 -75.46,24.93 C-75.46,24.93 -73.6,26.43 -73.6,26.43 C-73.6,26.43 -73.69,23.96 -73.69,23.96 C-73.69,23.96 -71.84,22.46 -71.84,22.46 C-71.84,22.46 -74.05,21.76 -74.05,21.76c M8.98 55.68 C8.98,55.68 6.15,53.65 6.15,53.65 C6.15,53.65 6.24,57.09 6.24,57.09 C6.24,57.09 3.5,59.12 3.5,59.12 C3.5,59.12 6.86,60.09 6.86,60.09 C6.86,60.09 7.92,63.35 7.92,63.35 C7.92,63.35 9.86,60.44 9.86,60.44 C9.86,60.44 13.3,60.44 13.3,60.44 C13.3,60.44 11.18,57.71 11.18,57.71 C11.18,57.71 12.15,54.44 12.15,54.44 C12.15,54.44 8.98,55.68 8.98,55.68c M124.89 -2.41 C124.89,-2.41 122.06,-4.35 122.06,-4.35 C122.06,-4.35 122.24,-0.91 122.24,-0.91 C122.24,-0.91 119.5,1.12 119.5,1.12 C119.5,1.12 122.77,2 122.77,2 C122.77,2 123.83,5.26 123.83,5.26 C123.83,5.26 125.77,2.44 125.77,2.44 C125.77,2.44 129.21,2.44 129.21,2.44 C129.21,2.44 127.09,-0.29 127.09,-0.29 C127.09,-0.29 128.15,-3.56 128.15,-3.56 C128.15,-3.56 124.89,-2.41 124.89,-2.41c M77.31 19.91 C77.31,19.91 74.57,17.88 74.57,17.88 C74.57,17.88 74.66,21.32 74.66,21.32 C74.66,21.32 71.92,23.35 71.92,23.35 C71.92,23.35 75.19,24.32 75.19,24.32 C75.19,24.32 76.34,27.58 76.34,27.58 C76.34,27.58 78.19,24.67 78.19,24.67 C78.19,24.67 81.64,24.67 81.64,24.67 C81.64,24.67 79.52,21.94 79.52,21.94 C79.52,21.94 80.58,18.67 80.58,18.67 C80.58,18.67 77.31,19.91 77.31,19.91c M-28.11 7.68 C-28.11,7.68 -30.94,5.65 -30.94,5.65 C-30.94,5.65 -30.76,9.09 -30.76,9.09 C-30.76,9.09 -33.5,11.12 -33.5,11.12 C-33.5,11.12 -30.23,12.09 -30.23,12.09 C-30.23,12.09 -29.17,15.35 -29.17,15.35 C-29.17,15.35 -27.23,12.44 -27.23,12.44 C-27.23,12.44 -23.79,12.44 -23.79,12.44 C-23.79,12.44 -25.91,9.71 -25.91,9.71 C-25.91,9.71 -24.85,6.44 -24.85,6.44 C-24.85,6.44 -28.11,7.68 -28.11,7.68c M-119.43 -20.22 C-119.43,-20.22 -122.26,-22.16 -122.26,-22.16 C-122.26,-22.16 -122.08,-18.72 -122.08,-18.72 C-122.08,-18.72 -124.82,-16.7 -124.82,-16.7 C-124.82,-16.7 -121.55,-15.81 -121.55,-15.81 C-121.55,-15.81 -120.49,-12.55 -120.49,-12.55 C-120.49,-12.55 -118.55,-15.37 -118.55,-15.37 C-118.55,-15.37 -115.11,-15.37 -115.11,-15.37 C-115.11,-15.37 -117.23,-18.11 -117.23,-18.11 C-117.23,-18.11 -116.17,-21.37 -116.17,-21.37 C-116.17,-21.37 -119.43,-20.22 -119.43,-20.22c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_4_G_L_2_G">
+ <group android:name="_R_G_L_4_G_L_2_G_L_2_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_4_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#e8eaed" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_2_G_L_1_G" android:translateX="206" android:translateY="145">
+ <path android:name="_R_G_L_4_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_2_G_L_0_G" android:translateX="46" android:translateY="145">
+ <path android:name="_R_G_L_4_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_4_G_L_1_G" android:translateX="206" android:translateY="877">
+ <path android:name="_R_G_L_4_G_L_1_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_0_G">
+ <group android:name="_R_G_L_4_G_L_0_G_L_2_G" android:translateX="206" android:translateY="50.5">
+ <path android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -29.67 C206,-29.67 206,50.33 206,50.33 C206,50.33 -206,50.33 -206,50.33 C-206,50.33 -206,-29.67 -206,-29.67 C-206,-29.67 206,-29.67 206,-29.67c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_0_G_L_1_G" android:translateX="206" android:translateY="50.5">
+ <path android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c "/>
+ </group>
+ <group android:name="_R_G_L_4_G_L_0_G_L_0_G" android:translateX="206" android:translateY="66.5">
+ <path android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_3_G_N_3_T_0" android:translateX="206" android:translateY="395" android:scaleX="0.6" android:scaleY="0">
+ <group android:name="_R_G_L_3_G" android:translateX="-206" android:translateY="-446">
+ <group android:name="_R_G_L_3_G_L_4_G" android:scaleY="0">
+ <group android:name="_R_G_L_3_G_L_4_G_L_11_G" android:translateX="206" android:translateY="467" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_11_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -407 C206,-407 206,407 206,407 C206,416.93 197.93,425 188,425 C188,425 -188,425 -188,425 C-197.93,425 -206,416.93 -206,407 C-206,407 -206,-407 -206,-407 C-206,-416.93 -197.93,-425 -188,-425 C-188,-425 188,-425 188,-425 C197.93,-425 206,-416.93 206,-407c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_10_G" android:translateX="182.5" android:translateY="831" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_10_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_9_G" android:translateX="186" android:translateY="801" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_9_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -7 C162,-7 162,7 162,7 C162,9.21 160.21,11 158,11 C158,11 -158,11 -158,11 C-160.21,11 -162,9.21 -162,7 C-162,7 -162,-7 -162,-7 C-162,-9.21 -160.21,-11 -158,-11 C-158,-11 158,-11 158,-11 C160.21,-11 162,-9.21 162,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_8_G" android:translateX="119" android:translateY="755" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_8_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M95 -7 C95,-7 95,7 95,7 C95,9.21 93.21,11 91,11 C91,11 -91,11 -91,11 C-93.21,11 -95,9.21 -95,7 C-95,7 -95,-7 -95,-7 C-95,-9.21 -93.21,-11 -91,-11 C-91,-11 91,-11 91,-11 C93.21,-11 95,-9.21 95,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_7_G" android:translateX="182.5" android:translateY="725" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_7_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M158.5 -7 C158.5,-7 158.5,7 158.5,7 C158.5,9.21 156.71,11 154.5,11 C154.5,11 -154.5,11 -154.5,11 C-156.71,11 -158.5,9.21 -158.5,7 C-158.5,7 -158.5,-7 -158.5,-7 C-158.5,-9.21 -156.71,-11 -154.5,-11 C-154.5,-11 154.5,-11 154.5,-11 C156.71,-11 158.5,-9.21 158.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_6_G" android:translateX="197.5" android:translateY="695" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_6_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M173.5 -7 C173.5,-7 173.5,7 173.5,7 C173.5,9.21 171.71,11 169.5,11 C169.5,11 -169.5,11 -169.5,11 C-171.71,11 -173.5,9.21 -173.5,7 C-173.5,7 -173.5,-7 -173.5,-7 C-173.5,-9.21 -171.71,-11 -169.5,-11 C-169.5,-11 169.5,-11 169.5,-11 C171.71,-11 173.5,-9.21 173.5,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_5_G" android:translateX="192" android:translateY="665" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_5_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M168 -7 C168,-7 168,7 168,7 C168,9.21 166.21,11 164,11 C164,11 -164,11 -164,11 C-166.21,11 -168,9.21 -168,7 C-168,7 -168,-7 -168,-7 C-168,-9.21 -166.21,-11 -164,-11 C-164,-11 164,-11 164,-11 C166.21,-11 168,-9.21 168,-7c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_4_G" android:translateX="105.5" android:translateY="360" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_4_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_3_G" android:translateX="47.5" android:translateY="360" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_3_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_2_G" android:translateX="142.5" android:translateY="328" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_2_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M118.5 -14 C118.5,-14 118.5,14 118.5,14 C118.5,16.21 116.71,18 114.5,18 C114.5,18 -114.5,18 -114.5,18 C-116.71,18 -118.5,16.21 -118.5,14 C-118.5,14 -118.5,-14 -118.5,-14 C-118.5,-16.21 -116.71,-18 -114.5,-18 C-114.5,-18 114.5,-18 114.5,-18 C116.71,-18 118.5,-16.21 118.5,-14c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_1_G" android:translateX="186" android:translateY="284" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_1_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M162 -14 C162,-14 162,14 162,14 C162,16.21 160.21,18 158,18 C158,18 -158,18 -158,18 C-160.21,18 -162,16.21 -162,14 C-162,14 -162,-14 -162,-14 C-162,-16.21 -160.21,-18 -158,-18 C-158,-18 158,-18 158,-18 C160.21,-18 162,-16.21 162,-14c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_4_G_L_0_G" android:translateX="155" android:translateY="240" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_4_G_L_0_G_D_0_P_0" android:fillColor="#bdc1c6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M131 -14 C131,-14 131,14 131,14 C131,16.21 129.21,18 127,18 C127,18 -127,18 -127,18 C-129.21,18 -131,16.21 -131,14 C-131,14 -131,-14 -131,-14 C-131,-16.21 -129.21,-18 -127,-18 C-127,-18 127,-18 127,-18 C129.21,-18 131,-16.21 131,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G" android:translateX="24" android:translateY="390" android:scaleY="0">
+ <group android:name="_R_G_L_3_G_L_3_G_L_7_G" android:translateX="182" android:translateY="120" android:scaleY="0"/>
+ <group android:name="_R_G_L_3_G_L_3_G_L_6_G" android:translateX="182" android:translateY="120" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_6_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M182 -116 C182,-116 182,116 182,116 C182,118.21 180.21,120 178,120 C178,120 -178,120 -178,120 C-180.21,120 -182,118.21 -182,116 C-182,116 -182,-116 -182,-116 C-182,-118.21 -180.21,-120 -178,-120 C-178,-120 178,-120 178,-120 C180.21,-120 182,-118.21 182,-116c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_5_G" android:translateX="77.322" android:translateY="150.552" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_5_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ <path android:name="_R_G_L_3_G_L_3_G_L_5_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 20.61 C0,20.61 -10.39,8.69 -10.39,8.69 M0 -6.11 C0,-6.11 -6.78,-15.61 -6.78,-15.61 M0 33.64 C0,33.64 8.26,17.67 8.26,17.67 M0 7.58 C0,7.58 8.26,-7.73 8.26,-7.73 M0 71.19 C0,71.19 0,-18.04 0,-18.04 M-30.22 37.18 C-30.22,37.18 0,-71.19 0,-71.19 C0,-71.19 30.22,37.18 30.22,37.18 C30.22,37.18 -30.22,37.18 -30.22,37.18c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_4_G" android:translateX="38.772" android:translateY="121.73" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_4_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ <path android:name="_R_G_L_3_G_L_3_G_L_4_G_D_1_P_0" android:strokeColor="#9adcb2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M0 28.82 C0,28.82 -14.52,12.18 -14.52,12.18 M0 -8.58 C0,-8.58 -9.51,-21.75 -9.51,-21.75 M0 47.01 C0,47.01 11.57,24.7 11.57,24.7 M0 10.64 C0,10.64 11.57,-10.78 11.57,-10.78 M0 99.42 C0,99.42 0,-25.21 0,-25.21 M-31.92 51.94 C-31.92,51.94 0,-99.42 0,-99.42 C0,-99.42 31.92,51.94 31.92,51.94 C31.92,51.94 -31.92,51.94 -31.92,51.94c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_3_G" android:translateX="183" android:translateY="222" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ <path android:name="_R_G_L_3_G_L_3_G_L_3_G_D_1_P_0" android:strokeColor="#9aa0a6" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="4" android:strokeAlpha="1" android:pathData=" M170 0 C170,0 -170,0 -170,0 "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_2_G" android:translateX="265.619" android:translateY="162.331" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_2_G_D_0_P_0" android:fillColor="#5f6368" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ <path android:name="_R_G_L_3_G_L_3_G_L_2_G_D_1_P_0" android:strokeColor="#a8cbfe" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-34.05 50.06 C-34.05,50.06 -34.05,-49.25 -34.05,-49.25 M-34.05 -49.55 C-34.05,-49.55 17.54,50.06 17.54,50.06 C17.54,50.06 84.62,50.06 84.62,50.06 C84.62,50.06 32.65,-50.06 32.65,-50.06 C32.65,-50.06 -34.05,-50.06 -34.05,-50.06 C-34.05,-50.06 -84.62,50.06 -84.62,50.06 C-84.62,50.06 17.54,50.06 17.54,50.06 "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_1_G" android:translateX="319.271" android:translateY="37.945" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#feefc3" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.42 2.99 C14.95,-4.17 9.93,-11.31 2.21,-12.96 C-0.9,-13.62 -3.97,-13.3 -6.64,-12.2 C-6.58,-12.19 -6.53,-12.18 -6.48,-12.17 C-1.03,-11.01 2.52,-5.97 1.44,-0.92 C0.36,4.13 -4.94,7.28 -10.4,6.12 C-11.6,5.86 -12.7,5.42 -13.69,4.83 C-11.9,8.78 -8.15,11.93 -3.34,12.96 C4.38,14.61 11.88,10.14 13.42,2.99c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_3_G_L_0_G" android:translateX="179.5" android:translateY="73.351" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_3_G_L_0_G_D_0_P_0" android:fillColor="#dadce0" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M51.08 -40.95 C51.08,-40.95 50.55,-42.54 50.55,-42.54 C50.55,-42.54 49.67,-41.13 49.67,-41.13 C49.67,-41.13 48.17,-41.21 48.17,-41.21 C48.17,-41.21 49.05,-39.8 49.05,-39.8 C49.05,-39.8 48.61,-38.22 48.61,-38.22 C48.61,-38.22 50.02,-38.74 50.02,-38.74 C50.02,-38.74 51.35,-37.69 51.35,-37.69 C51.35,-37.69 51.26,-39.45 51.26,-39.45 C51.26,-39.45 52.59,-40.42 52.59,-40.42 C52.59,-40.42 51.08,-40.95 51.08,-40.95c M8.78 30.58 C8.78,30.58 8.25,28.99 8.25,28.99 C8.25,28.99 7.37,30.4 7.37,30.4 C7.37,30.4 5.87,30.31 5.87,30.31 C5.87,30.31 6.75,31.72 6.75,31.72 C6.75,31.72 6.31,33.31 6.31,33.31 C6.31,33.31 7.72,32.78 7.72,32.78 C7.72,32.78 9.05,33.84 9.05,33.84 C9.05,33.84 8.96,32.08 8.96,32.08 C8.96,32.08 10.29,31.11 10.29,31.11 C10.29,31.11 8.78,30.58 8.78,30.58c M19.38 -61.67 C19.38,-61.67 18.94,-63.35 18.94,-63.35 C18.94,-63.35 17.97,-61.94 17.97,-61.94 C17.97,-61.94 16.47,-61.94 16.47,-61.94 C16.47,-61.94 17.35,-60.62 17.35,-60.62 C17.35,-60.62 16.91,-58.94 16.91,-58.94 C16.91,-58.94 18.41,-59.56 18.41,-59.56 C18.41,-59.56 19.65,-58.5 19.65,-58.5 C19.65,-58.5 19.56,-60.18 19.56,-60.18 C19.56,-60.18 20.88,-61.23 20.88,-61.23 C20.88,-61.23 19.38,-61.67 19.38,-61.67c M-32.98 35.08 C-32.98,35.08 -33.51,33.4 -33.51,33.4 C-33.51,33.4 -34.4,34.81 -34.4,34.81 C-34.4,34.81 -35.9,34.81 -35.9,34.81 C-35.9,34.81 -35.01,36.22 -35.01,36.22 C-35.01,36.22 -35.45,37.81 -35.45,37.81 C-35.45,37.81 -34.04,37.28 -34.04,37.28 C-34.04,37.28 -32.72,38.25 -32.72,38.25 C-32.72,38.25 -32.81,36.58 -32.81,36.58 C-32.81,36.58 -31.48,35.6 -31.48,35.6 C-31.48,35.6 -32.98,35.08 -32.98,35.08c M45.34 7.56 C45.34,7.56 44.81,5.97 44.81,5.97 C44.81,5.97 43.93,7.38 43.93,7.38 C43.93,7.38 42.34,7.3 42.34,7.3 C42.34,7.3 43.31,8.71 43.31,8.71 C43.31,8.71 42.87,10.29 42.87,10.29 C42.87,10.29 44.28,9.77 44.28,9.77 C44.28,9.77 45.52,10.82 45.52,10.82 C45.52,10.82 45.52,9.06 45.52,9.06 C45.52,9.06 46.76,8.09 46.76,8.09 C46.76,8.09 45.34,7.56 45.34,7.56c M-9.59 -41.67 C-9.59,-41.67 -10.12,-43.35 -10.12,-43.35 C-10.12,-43.35 -11,-41.94 -11,-41.94 C-11,-41.94 -12.5,-41.94 -12.5,-41.94 C-12.5,-41.94 -11.62,-40.62 -11.62,-40.62 C-11.62,-40.62 -12.06,-38.94 -12.06,-38.94 C-12.06,-38.94 -10.65,-39.56 -10.65,-39.56 C-10.65,-39.56 -9.32,-38.5 -9.32,-38.5 C-9.32,-38.5 -9.41,-40.26 -9.41,-40.26 C-9.41,-40.26 -8.09,-41.23 -8.09,-41.23 C-8.09,-41.23 -9.59,-41.67 -9.59,-41.67c M97.74 -23.97 C97.74,-23.97 97.03,-26.35 97.03,-26.35 C97.03,-26.35 95.8,-24.32 95.8,-24.32 C95.8,-24.32 93.5,-24.32 93.5,-24.32 C93.5,-24.32 94.91,-22.38 94.91,-22.38 C94.91,-22.38 94.21,-20 94.21,-20 C94.21,-20 96.33,-20.88 96.33,-20.88 C96.33,-20.88 98.09,-19.38 98.09,-19.38 C98.09,-19.38 98.09,-21.85 98.09,-21.85 C98.09,-21.85 99.86,-23.26 99.86,-23.26 C99.86,-23.26 97.74,-23.97 97.74,-23.97c M167.29 43.28 C167.29,43.28 166.67,40.9 166.67,40.9 C166.67,40.9 165.35,42.93 165.35,42.93 C165.35,42.93 163.14,42.93 163.14,42.93 C163.14,42.93 164.47,44.87 164.47,44.87 C164.47,44.87 163.76,47.25 163.76,47.25 C163.76,47.25 165.88,46.37 165.88,46.37 C165.88,46.37 167.73,47.87 167.73,47.87 C167.73,47.87 167.65,45.4 167.65,45.4 C167.65,45.4 169.5,43.98 169.5,43.98 C169.5,43.98 167.29,43.28 167.29,43.28c M-1.1 -1.79 C-1.1,-1.79 -1.72,-4.08 -1.72,-4.08 C-1.72,-4.08 -3.05,-2.14 -3.05,-2.14 C-3.05,-2.14 -5.25,-2.14 -5.25,-2.14 C-5.25,-2.14 -3.93,-0.11 -3.93,-0.11 C-3.93,-0.11 -4.64,2.18 -4.64,2.18 C-4.64,2.18 -2.52,1.38 -2.52,1.38 C-2.52,1.38 -0.66,2.8 -0.66,2.8 C-0.66,2.8 -0.75,0.41 -0.75,0.41 C-0.75,0.41 1.1,-1.08 1.1,-1.08 C1.1,-1.08 -1.1,-1.79 -1.1,-1.79c M-60.89 -5.23 C-60.89,-5.23 -61.59,-7.61 -61.59,-7.61 C-61.59,-7.61 -62.83,-5.58 -62.83,-5.58 C-62.83,-5.58 -65.13,-5.58 -65.13,-5.58 C-65.13,-5.58 -63.71,-3.64 -63.71,-3.64 C-63.71,-3.64 -64.42,-1.26 -64.42,-1.26 C-64.42,-1.26 -62.39,-2.14 -62.39,-2.14 C-62.39,-2.14 -60.53,-0.64 -60.53,-0.64 C-60.53,-0.64 -60.62,-3.11 -60.62,-3.11 C-60.62,-3.11 -58.77,-4.52 -58.77,-4.52 C-58.77,-4.52 -60.89,-5.23 -60.89,-5.23c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-51.26 -42.98 C-51.26,-42.98 -54.09,-45.01 -54.09,-45.01 C-54.09,-45.01 -53.91,-41.57 -53.91,-41.57 C-53.91,-41.57 -56.65,-39.54 -56.65,-39.54 C-56.65,-39.54 -53.38,-38.57 -53.38,-38.57 C-53.38,-38.57 -52.32,-35.3 -52.32,-35.3 C-52.32,-35.3 -50.38,-38.13 -50.38,-38.13 C-50.38,-38.13 -46.94,-38.22 -46.94,-38.22 C-46.94,-38.22 -49.05,-40.86 -49.05,-40.86 C-49.05,-40.86 -47.99,-44.21 -47.99,-44.21 C-47.99,-44.21 -51.26,-42.98 -51.26,-42.98c M-92.06 -47.92 C-92.06,-47.92 -92.59,-49.59 -92.59,-49.59 C-92.59,-49.59 -93.47,-48.18 -93.47,-48.18 C-93.47,-48.18 -95.06,-48.18 -95.06,-48.18 C-95.06,-48.18 -94.09,-46.86 -94.09,-46.86 C-94.09,-46.86 -94.53,-45.18 -94.53,-45.18 C-94.53,-45.18 -93.12,-45.8 -93.12,-45.8 C-93.12,-45.8 -91.88,-44.74 -91.88,-44.74 C-91.88,-44.74 -91.88,-46.42 -91.88,-46.42 C-91.88,-46.42 -90.65,-47.47 -90.65,-47.47 C-90.65,-47.47 -92.06,-47.92 -92.06,-47.92c M62.83 -13.34 C62.83,-13.34 62.39,-14.93 62.39,-14.93 C62.39,-14.93 61.5,-13.52 61.5,-13.52 C61.5,-13.52 59.91,-13.52 59.91,-13.52 C59.91,-13.52 60.89,-12.2 60.89,-12.2 C60.89,-12.2 60.36,-10.52 60.36,-10.52 C60.36,-10.52 61.86,-11.14 61.86,-11.14 C61.86,-11.14 63.09,-10.08 63.09,-10.08 C63.09,-10.08 63.09,-11.84 63.09,-11.84 C63.09,-11.84 64.33,-12.81 64.33,-12.81 C64.33,-12.81 62.83,-13.34 62.83,-13.34c M-155.99 -40.95 C-155.99,-40.95 -156.43,-42.54 -156.43,-42.54 C-156.43,-42.54 -157.32,-41.13 -157.32,-41.13 C-157.32,-41.13 -158.91,-41.21 -158.91,-41.21 C-158.91,-41.21 -157.93,-39.8 -157.93,-39.8 C-157.93,-39.8 -158.46,-38.22 -158.46,-38.22 C-158.46,-38.22 -156.96,-38.74 -156.96,-38.74 C-156.96,-38.74 -155.73,-37.69 -155.73,-37.69 C-155.73,-37.69 -155.73,-39.45 -155.73,-39.45 C-155.73,-39.45 -154.49,-40.42 -154.49,-40.42 C-154.49,-40.42 -155.99,-40.95 -155.99,-40.95c M141.24 26.52 C141.24,26.52 140.71,24.85 140.71,24.85 C140.71,24.85 139.83,26.26 139.83,26.26 C139.83,26.26 138.33,26.26 138.33,26.26 C138.33,26.26 139.21,27.67 139.21,27.67 C139.21,27.67 138.77,29.26 138.77,29.26 C138.77,29.26 140.18,28.73 140.18,28.73 C140.18,28.73 141.51,29.7 141.51,29.7 C141.51,29.7 141.42,28.02 141.42,28.02 C141.42,28.02 142.74,27.05 142.74,27.05 C142.74,27.05 141.24,26.52 141.24,26.52c M111.4 -51.27 C111.4,-51.27 110.95,-52.94 110.95,-52.94 C110.95,-52.94 110.07,-51.53 110.07,-51.53 C110.07,-51.53 108.48,-51.53 108.48,-51.53 C108.48,-51.53 109.45,-50.21 109.45,-50.21 C109.45,-50.21 108.92,-48.53 108.92,-48.53 C108.92,-48.53 110.42,-49.15 110.42,-49.15 C110.42,-49.15 111.66,-48.09 111.66,-48.09 C111.66,-48.09 111.66,-49.86 111.66,-49.86 C111.66,-49.86 112.9,-50.83 112.9,-50.83 C112.9,-50.83 111.4,-51.27 111.4,-51.27c M-66.59 53.33 C-66.59,53.33 -67.03,51.65 -67.03,51.65 C-67.03,51.65 -67.91,53.06 -67.91,53.06 C-67.91,53.06 -69.5,53.06 -69.5,53.06 C-69.5,53.06 -68.53,54.47 -68.53,54.47 C-68.53,54.47 -69.06,56.06 -69.06,56.06 C-69.06,56.06 -67.56,55.53 -67.56,55.53 C-67.56,55.53 -66.32,56.5 -66.32,56.5 C-66.32,56.5 -66.32,54.82 -66.32,54.82 C-66.32,54.82 -65.08,53.77 -65.08,53.77 C-65.08,53.77 -66.59,53.33 -66.59,53.33c M-50.59 59.33 C-50.59,59.33 -51.12,57.65 -51.12,57.65 C-51.12,57.65 -52,59.06 -52,59.06 C-52,59.06 -53.5,59.06 -53.5,59.06 C-53.5,59.06 -52.62,60.38 -52.62,60.38 C-52.62,60.38 -53.06,62.06 -53.06,62.06 C-53.06,62.06 -51.65,61.53 -51.65,61.53 C-51.65,61.53 -50.32,62.5 -50.32,62.5 C-50.32,62.5 -50.41,60.82 -50.41,60.82 C-50.41,60.82 -49.08,59.77 -49.08,59.77 C-49.08,59.77 -50.59,59.33 -50.59,59.33c M29.98 -16.08 C29.98,-16.08 29.27,-18.46 29.27,-18.46 C29.27,-18.46 27.95,-16.43 27.95,-16.43 C27.95,-16.43 25.74,-16.43 25.74,-16.43 C25.74,-16.43 27.06,-14.49 27.06,-14.49 C27.06,-14.49 26.36,-12.11 26.36,-12.11 C26.36,-12.11 28.48,-12.9 28.48,-12.9 C28.48,-12.9 30.33,-11.49 30.33,-11.49 C30.33,-11.49 30.24,-13.96 30.24,-13.96 C30.24,-13.96 32.1,-15.37 32.1,-15.37 C32.1,-15.37 29.98,-16.08 29.98,-16.08c M81.28 55.98 C81.28,55.98 80.58,53.6 80.58,53.6 C80.58,53.6 79.25,55.63 79.25,55.63 C79.25,55.63 77.04,55.63 77.04,55.63 C77.04,55.63 78.37,57.57 78.37,57.57 C78.37,57.57 77.66,59.95 77.66,59.95 C77.66,59.95 79.78,59.07 79.78,59.07 C79.78,59.07 81.64,60.56 81.64,60.56 C81.64,60.56 81.55,58.1 81.55,58.1 C81.55,58.1 83.4,56.68 83.4,56.68 C83.4,56.68 81.28,55.98 81.28,55.98c M-165.26 -10.97 C-165.26,-10.97 -165.97,-13.35 -165.97,-13.35 C-165.97,-13.35 -167.29,-11.32 -167.29,-11.32 C-167.29,-11.32 -169.5,-11.32 -169.5,-11.32 C-169.5,-11.32 -168.18,-9.38 -168.18,-9.38 C-168.18,-9.38 -168.88,-7 -168.88,-7 C-168.88,-7 -166.76,-7.79 -166.76,-7.79 C-166.76,-7.79 -164.91,-6.38 -164.91,-6.38 C-164.91,-6.38 -165,-8.85 -165,-8.85 C-165,-8.85 -163.14,-10.26 -163.14,-10.26 C-163.14,-10.26 -165.26,-10.97 -165.26,-10.97c M-74.05 21.76 C-74.05,21.76 -74.66,19.47 -74.66,19.47 C-74.66,19.47 -75.99,21.49 -75.99,21.49 C-75.99,21.49 -78.2,21.41 -78.2,21.41 C-78.2,21.41 -76.87,23.43 -76.87,23.43 C-76.87,23.43 -77.58,25.73 -77.58,25.73 C-77.58,25.73 -75.46,24.93 -75.46,24.93 C-75.46,24.93 -73.6,26.43 -73.6,26.43 C-73.6,26.43 -73.69,23.96 -73.69,23.96 C-73.69,23.96 -71.84,22.46 -71.84,22.46 C-71.84,22.46 -74.05,21.76 -74.05,21.76c M8.98 55.68 C8.98,55.68 6.15,53.65 6.15,53.65 C6.15,53.65 6.24,57.09 6.24,57.09 C6.24,57.09 3.5,59.12 3.5,59.12 C3.5,59.12 6.86,60.09 6.86,60.09 C6.86,60.09 7.92,63.35 7.92,63.35 C7.92,63.35 9.86,60.44 9.86,60.44 C9.86,60.44 13.3,60.44 13.3,60.44 C13.3,60.44 11.18,57.71 11.18,57.71 C11.18,57.71 12.15,54.44 12.15,54.44 C12.15,54.44 8.98,55.68 8.98,55.68c M124.89 -2.41 C124.89,-2.41 122.06,-4.35 122.06,-4.35 C122.06,-4.35 122.24,-0.91 122.24,-0.91 C122.24,-0.91 119.5,1.12 119.5,1.12 C119.5,1.12 122.77,2 122.77,2 C122.77,2 123.83,5.26 123.83,5.26 C123.83,5.26 125.77,2.44 125.77,2.44 C125.77,2.44 129.21,2.44 129.21,2.44 C129.21,2.44 127.09,-0.29 127.09,-0.29 C127.09,-0.29 128.15,-3.56 128.15,-3.56 C128.15,-3.56 124.89,-2.41 124.89,-2.41c M77.31 19.91 C77.31,19.91 74.57,17.88 74.57,17.88 C74.57,17.88 74.66,21.32 74.66,21.32 C74.66,21.32 71.92,23.35 71.92,23.35 C71.92,23.35 75.19,24.32 75.19,24.32 C75.19,24.32 76.34,27.58 76.34,27.58 C76.34,27.58 78.19,24.67 78.19,24.67 C78.19,24.67 81.64,24.67 81.64,24.67 C81.64,24.67 79.52,21.94 79.52,21.94 C79.52,21.94 80.58,18.67 80.58,18.67 C80.58,18.67 77.31,19.91 77.31,19.91c M-28.11 7.68 C-28.11,7.68 -30.94,5.65 -30.94,5.65 C-30.94,5.65 -30.76,9.09 -30.76,9.09 C-30.76,9.09 -33.5,11.12 -33.5,11.12 C-33.5,11.12 -30.23,12.09 -30.23,12.09 C-30.23,12.09 -29.17,15.35 -29.17,15.35 C-29.17,15.35 -27.23,12.44 -27.23,12.44 C-27.23,12.44 -23.79,12.44 -23.79,12.44 C-23.79,12.44 -25.91,9.71 -25.91,9.71 C-25.91,9.71 -24.85,6.44 -24.85,6.44 C-24.85,6.44 -28.11,7.68 -28.11,7.68c M-119.43 -20.22 C-119.43,-20.22 -122.26,-22.16 -122.26,-22.16 C-122.26,-22.16 -122.08,-18.72 -122.08,-18.72 C-122.08,-18.72 -124.82,-16.7 -124.82,-16.7 C-124.82,-16.7 -121.55,-15.81 -121.55,-15.81 C-121.55,-15.81 -120.49,-12.55 -120.49,-12.55 C-120.49,-12.55 -118.55,-15.37 -118.55,-15.37 C-118.55,-15.37 -115.11,-15.37 -115.11,-15.37 C-115.11,-15.37 -117.23,-18.11 -117.23,-18.11 C-117.23,-18.11 -116.17,-21.37 -116.17,-21.37 C-116.17,-21.37 -119.43,-20.22 -119.43,-20.22c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_3_G_L_2_G" android:scaleY="0">
+ <group android:name="_R_G_L_3_G_L_2_G_L_2_G" android:translateX="206" android:translateY="145" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_2_G_L_2_G_D_0_P_0" android:fillColor="#e8eaed" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_2_G_L_1_G" android:translateX="206" android:translateY="145" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_2_G_L_1_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_2_G_L_0_G" android:translateX="46" android:translateY="145" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_2_G_L_0_G_D_0_P_0" android:fillColor="#80868b" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_3_G_L_1_G" android:translateX="206" android:translateY="877" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_1_G_D_0_P_0" android:fillColor="#373737" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40 0 C40,0 40,0 40,0 C40,1.1 39.1,2 38,2 C38,2 -38,2 -38,2 C-39.1,2 -40,1.1 -40,0 C-40,0 -40,0 -40,0 C-40,-1.1 -39.1,-2 -38,-2 C-38,-2 38,-2 38,-2 C39.1,-2 40,-1.1 40,0c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_0_G" android:scaleY="0">
+ <group android:name="_R_G_L_3_G_L_0_G_L_2_G" android:translateX="206" android:translateY="50.5" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -29.67 C206,-29.67 206,50.33 206,50.33 C206,50.33 -206,50.33 -206,50.33 C-206,50.33 -206,-29.67 -206,-29.67 C-206,-29.67 206,-29.67 206,-29.67c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_0_G_L_1_G" android:translateX="206" android:translateY="50.5" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#202124" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c "/>
+ </group>
+ <group android:name="_R_G_L_3_G_L_0_G_L_0_G" android:translateX="206" android:translateY="66.5" android:scaleY="0">
+ <path android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_2_G_N_3_T_0" android:translateX="206" android:translateY="395" android:scaleX="0.6" android:scaleY="0">
+ <group android:name="_R_G_L_2_G" android:translateY="-508.163" android:scaleX="0.68838" android:scaleY="0.68838">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#9aa0a6" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 25 C13.81,25 25,13.81 25,0 C25,-13.81 13.81,-25 0,-25 C-13.81,-25 -25,-13.81 -25,0 C-25,13.81 -13.81,25 0,25c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_3_T_0" android:translateX="206" android:translateY="395" android:scaleX="0.6" android:scaleY="0">
+ <group android:name="_R_G_L_1_G" android:translateX="-556.176" android:translateY="-7.307" android:scaleX="1.39" android:scaleY="1.39">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#3c4043" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M136.82 -315.36 C136.82,-315.36 -137.18,-315.36 -137.18,-315.36 C-137.18,-315.36 -137.18,326.29 -137.18,326.29 C-137.18,326.29 136.82,326.29 136.82,326.29 C136.82,326.29 136.82,-315.36 136.82,-315.36c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-30" android:translateY="658.997" android:pivotX="300" android:pivotY="64" android:rotation="-90" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M-166 64 C-130.65,64 -102,35.35 -102,0 C-102,-35.34 -130.65,-64 -166,-64 C-201.34,-64 -230,-35.34 -230,0 C-230,35.35 -201.34,64 -166,64c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="192" android:translateY="63.997" android:rotation="90" android:scaleX="-1" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="0.3" android:fillType="nonZero" android:pathData=" M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="295.995" android:translateY="63.997" android:scaleY="0">
+ <group android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0" android:translateX="-166" android:translateY="0">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#baf29d" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 64 C35.35,64 64,35.35 64,0 C64,-35.34 35.35,-64 0,-64 C-35.34,-64 -64,-35.34 -64,0 C-64,35.35 -35.34,64 0,64c "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_4_G_N_7_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="1500" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,446C 206,446 206,446 206,446">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="950" android:startOffset="1500" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,446C 206,446 206,395 206,395">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_7_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="1500" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="1500" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="950" android:startOffset="1500" android:valueFrom="1" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="950" android:startOffset="1500" android:valueFrom="1" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_7_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_7_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_11_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_10_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_9_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_8_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="3400" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,386.5 206,395">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="350" android:startOffset="3400" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,437.5 206,446">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3400" android:valueFrom="0" android:valueTo="0.6" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="3883" android:startOffset="0" android:valueFrom="0.68838" android:valueTo="0.68838" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="3883" android:startOffset="0" android:valueFrom="0.68838" android:valueTo="0.68838" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="167" android:startOffset="3883" android:valueFrom="0.68838" android:valueTo="1.37677" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="167" android:startOffset="3883" android:valueFrom="0.68838" android:valueTo="1.37677" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="3400" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,386.5 206,395">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="350" android:startOffset="3400" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,437.5 206,446">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3883" android:valueFrom="0" android:valueTo="0.6" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="2667" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -556.176,-7.307C -556.176,-7.307 -556.176,-7.307 -556.176,-7.307">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="250" android:startOffset="2667" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="417" android:startOffset="2917" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="3400" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,386.5 206,395">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="350" android:startOffset="3400" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 206,395C 206,403.5 206,437.5 206,446">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="3400" android:startOffset="0" android:valueFrom="0.6" android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="350" android:startOffset="3400" android:valueFrom="0.6" android:valueTo="0.72718" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="217" android:startOffset="3750" android:valueFrom="0.72718" android:valueTo="0.72" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="2667" android:valueFrom="0" android:valueTo="0.6" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1233" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="1233" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="1050" android:startOffset="1400" android:valueFrom="M0 1.99 C35.34,1.99 64,-26.66 63.99,-62.01 C63.99,-62.01 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64,-62 -64,-62 C-64,-26.66 -35.35,1.99 0,1.99c " android:valueTo="M-0.01 229.99 C35.33,229.99 63.99,201.34 63.99,166 C63.99,166 64.01,-61.87 64.01,-61.87 C64.01,-97.21 35.35,-125.87 0.01,-125.87 C-35.34,-125.87 -63.99,-97.21 -63.99,-61.87 C-63.99,-61.87 -64.01,166 -64.01,166 C-64.01,201.34 -35.36,229.99 -0.01,229.99c " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1400" android:valueFrom="0" android:valueTo="-1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3483" android:valueFrom="-1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateXY" android:duration="167" android:startOffset="1233" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -128,0 -204,0 -166,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateXY" android:duration="1050" android:startOffset="1400" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M -166,0C -128,0 24,0 62,0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1233" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3483" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="1233" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="3483" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="5133" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/quickstep/res/layout/gesture_tutorial_dialog.xml b/quickstep/res/layout/gesture_tutorial_dialog.xml
new file mode 100644
index 0000000..59bf7b9
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_dialog.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/bg_sandbox_feedback"
+ android:paddingTop="24dp"
+ android:paddingBottom="24dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <TextView
+ android:id="@+id/gesture_tutorial_dialog_title"
+ style="@style/TextAppearance.GestureTutorial.Dialog.Title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/skip_tutorial_dialog_title"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"/>
+
+ <TextView
+ android:id="@+id/gesture_tutorial_dialog_subtitle"
+ style="@style/TextAppearance.GestureTutorial.Dialog.Subtitle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/skip_tutorial_dialog_subtitle"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_dialog_title"/>
+
+ <!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
+ of elevation and shadow) which is replaced by ripple effect in android:foreground -->
+ <Button
+ android:id="@+id/gesture_tutorial_dialog_cancel_button"
+ style="@style/TextAppearance.GestureTutorial.CancelButtonLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="46dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:background="@drawable/gesture_tutorial_cancel_button_background"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ android:stateListAnimator="@null"
+ android:text="@string/gesture_tutorial_action_button_label_cancel"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_dialog_subtitle"/>
+
+ <Button
+ android:id="@+id/gesture_tutorial_dialog_confirm_button"
+ style="@style/TextAppearance.GestureTutorial.ButtonLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="46dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ android:stateListAnimator="@null"
+ android:text="@string/gesture_tutorial_action_button_label_skip"
+
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_dialog_subtitle"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index 16b2c56..700dd1f 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -15,6 +15,7 @@
-->
<com.android.quickstep.interaction.RootSandboxLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
@@ -53,112 +54,93 @@
android:layout_height="match_parent"
android:background="@drawable/gesture_tutorial_ripple"/>
- <VideoView
+ <ImageView
android:id="@+id/gesture_tutorial_feedback_video"
- android:layout_width="0dp"
- android:layout_height="0dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
- android:layout_alignParentEnd="true"/>
-
- <ImageButton
- android:id="@+id/gesture_tutorial_fragment_close_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_marginStart="4dp"
- android:layout_marginTop="30dp"
- android:accessibilityTraversalAfter="@id/gesture_tutorial_fragment_titles_container"
- android:background="@android:color/transparent"
- android:contentDescription="@string/gesture_tutorial_close_button_content_description"
- android:padding="18dp"
- android:src="@drawable/gesture_tutorial_close_button"
- android:tint="?android:attr/textColorPrimary"
+ android:layout_alignParentEnd="true"
+ android:scaleType="fitXY"
android:visibility="gone"/>
- <LinearLayout
- android:id="@+id/gesture_tutorial_fragment_titles_container"
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/gesture_tutorial_fragment_feedback_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
- android:layout_marginTop="70dp"
- android:focusable="true"
- android:gravity="center_horizontal"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/gesture_tutorial_fragment_title_view"
- style="@style/TextAppearance.GestureTutorial.Title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/gesture_tutorial_title_margin_start_end"
- android:layout_marginEnd="@dimen/gesture_tutorial_title_margin_start_end"/>
-
- <TextView
- android:id="@+id/gesture_tutorial_fragment_subtitle_view"
- style="@style/TextAppearance.GestureTutorial.Subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/gesture_tutorial_subtitle_margin_start_end"
- android:layout_marginTop="10dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_subtitle_margin_start_end"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/gesture_tutorial_fragment_feedback_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="@dimen/gesture_tutorial_feedback_margin_start_end"
android:layout_marginEnd="@dimen/gesture_tutorial_feedback_margin_start_end"
android:layout_marginTop="24dp"
android:padding="24dp"
- android:gravity="center_vertical"
android:background="@drawable/bg_sandbox_feedback">
+ <ImageButton
+ android:id="@+id/gesture_tutorial_fragment_close_button"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:src="@drawable/close_icon"
+ android:background="@drawable/bg_sandbox_close_button"
+ android:contentDescription="@string/gesture_tutorial_close_button_content_description"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"/>
+
<TextView
android:id="@+id/gesture_tutorial_fragment_feedback_title"
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginBottom="10dp"/>
+ android:layout_marginTop="16dp"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_close_button"/>
<TextView
android:id="@+id/gesture_tutorial_fragment_feedback_subtitle"
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="24dp"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_title"/>
+
+ <TextView
+ android:id="@+id/gesture_tutorial_fragment_feedback_tutorial_step"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtext"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/gesture_tutorial_fragment_action_button"
+ app:layout_constraintTop_toTopOf="@id/gesture_tutorial_fragment_action_button"
+ app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_fragment_action_button"/>
+
+ <!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
+ of elevation and shadow) which is replaced by ripple effect in android:foreground -->
+ <Button
+ android:id="@+id/gesture_tutorial_fragment_action_button"
+ style="@style/TextAppearance.GestureTutorial.ButtonLabel"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </LinearLayout>
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ android:stateListAnimator="@null"
+ android:visibility="invisible"
- <!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
- of elevation and shadow) which is replaced by ripple effect in android:foreground -->
- <Button
- android:id="@+id/gesture_tutorial_fragment_action_button"
- style="@style/TextAppearance.GestureTutorial.ButtonLabel"
- android:layout_width="142dp"
- android:layout_height="49dp"
- android:layout_alignParentEnd="true"
- android:layout_alignParentBottom="true"
- android:layout_marginEnd="@dimen/gesture_tutorial_button_margin_start_end"
- android:layout_marginBottom="48dp"
- android:background="@drawable/gesture_tutorial_action_button_background"
- android:foreground="?android:attr/selectableItemBackgroundBorderless"
- android:stateListAnimator="@null"/>
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle"/>
- <Button
- android:id="@+id/gesture_tutorial_fragment_action_text_button"
- style="@style/TextAppearance.GestureTutorial.TextButtonLabel"
- android:layout_width="142dp"
- android:layout_height="49dp"
- android:layout_alignParentStart="true"
- android:layout_alignParentBottom="true"
- android:layout_marginStart="@dimen/gesture_tutorial_button_margin_start_end"
- android:layout_marginBottom="48dp"
- android:background="@null"
- android:foreground="?android:attr/selectableItemBackgroundBorderless"
- android:stateListAnimator="@null"/>
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
</com.android.quickstep.interaction.RootSandboxLayout>
\ No newline at end of file
diff --git a/quickstep/res/raw/tips_nav_back_left.mp4 b/quickstep/res/raw/tips_nav_back_left.mp4
deleted file mode 100644
index f40b3b7..0000000
--- a/quickstep/res/raw/tips_nav_back_left.mp4
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/raw/tips_nav_back_right.mp4 b/quickstep/res/raw/tips_nav_back_right.mp4
deleted file mode 100644
index 93841c7..0000000
--- a/quickstep/res/raw/tips_nav_back_right.mp4
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/raw/tips_nav_home.mp4 b/quickstep/res/raw/tips_nav_home.mp4
deleted file mode 100644
index ce33df2..0000000
--- a/quickstep/res/raw/tips_nav_home.mp4
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/raw/tips_nav_overview.mp4 b/quickstep/res/raw/tips_nav_overview.mp4
deleted file mode 100644
index 17f4b80..0000000
--- a/quickstep/res/raw/tips_nav_overview.mp4
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index eeb9e99..a0f1638 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -126,7 +126,7 @@
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
<string name="overview_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
- <!-- Feedback shown during interactive parts of Overview gesture tutorial when the Home gesture is detected. [CHAR LIMIT=100] -->
+ <!-- Feedback shown during interactive parts of Overview gesture tutorial when the Home gesture is detected. The window refers to the current app's window during the gesture. [CHAR LIMIT=100] -->
<string name="overview_gesture_feedback_home_detected">Try holding the window for longer before releasing.</string>
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
<string name="overview_gesture_feedback_wrong_swipe_direction">Make sure you swipe straight up, then pause.</string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 387d4ec..82a91a7 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -57,6 +57,14 @@
<item name="android:lineHeight">42sp</item>
</style>
+ <style name="TextAppearance.GestureTutorial.Dialog.Title"
+ parent="TextAppearance.GestureTutorial.Feedback.Title">
+ <item name="android:gravity">center_horizontal</item>
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:lineHeight">32sp</item>
+ <item name="android:textSize">24sp</item>
+ </style>
+
<style name="TextAppearance.GestureTutorial.Feedback.Subtitle"
parent="TextAppearance.GestureTutorial">
<item name="android:gravity">start</item>
@@ -67,6 +75,21 @@
<item name="android:lineHeight">24sp</item>
</style>
+ <style name="TextAppearance.GestureTutorial.Dialog.Subtitle"
+ parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
+ <item name="android:gravity">center_horizontal</item>
+ <item name="android:fontFamily">google-sans-text</item>
+ <item name="android:letterSpacing">0.025</item>
+ <item name="android:lineHeight">20sp</item>
+ <item name="android:textSize">14sp</item>
+ </style>
+
+ <style name="TextAppearance.GestureTutorial.Feedback.Subtext"
+ parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
+ <item name="android:textSize">16sp</item>
+ <item name="android:textColor">#909090</item>
+ </style>
+
<style name="TextAppearance.GestureTutorial.ButtonLabel"
parent="TextAppearance.GestureTutorial.CallToAction">
<item name="android:gravity">center</item>
@@ -76,6 +99,11 @@
<item name="android:textAllCaps">false</item>
</style>
+ <style name="TextAppearance.GestureTutorial.CancelButtonLabel"
+ parent="TextAppearance.GestureTutorial.ButtonLabel">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
<style name="TextAppearance.GestureTutorial.TextButtonLabel"
parent="TextAppearance.GestureTutorial.ButtonLabel">
<item name="android:textColor">@color/gesture_tutorial_primary_color</item>
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index e771962..2b1b57c 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -17,17 +17,26 @@
package com.android.quickstep;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
+import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
@@ -35,11 +44,11 @@
import com.android.launcher3.util.DisplayController;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class OrientationTouchTransformerTest {
@@ -284,11 +293,26 @@
}
private DisplayController.Info createDisplayInfo(ScreenSize screenSize, int rotation) {
+ Context context = RuntimeEnvironment.application;
+ Display display = spy(context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY));
+
Point p = new Point(screenSize.mWidth, screenSize.mHeight);
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
- p = new Point(screenSize.mHeight, screenSize.mWidth);
+ p.set(screenSize.mHeight, screenSize.mWidth);
}
- return new DisplayController.Info(0, rotation, 0, p, p, p, null);
+
+ doReturn(rotation).when(display).getRotation();
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(p.x, p.y);
+ return null;
+ }).when(display).getRealSize(any(Point.class));
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(p.x, p.y);
+ ((Point) i.getArgument(1)).set(p.x, p.y);
+ return null;
+ }).when(display).getCurrentSizeRange(any(Point.class), any(Point.class));
+ return new DisplayController.Info(context, display);
}
private float generateTouchRegionHeight(ScreenSize screenSize, int rotation) {
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index 88079ae..fd93d98 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -147,7 +147,7 @@
LauncherActivityInterface.INSTANCE);
tvs.setDp(mDeviceProfile);
- int launcherRotation = DisplayController.getDefaultDisplay(mContext).getInfo().rotation;
+ int launcherRotation = DisplayController.INSTANCE.get(mContext).getInfo().rotation;
if (mAppRotation < 0) {
mAppRotation = launcherRotation;
}
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 0524b21..caf52e3 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -19,17 +19,20 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_SIZE;
+import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.content.IntentSender;
+import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.IBinder;
import android.view.View;
import androidx.annotation.Nullable;
@@ -37,6 +40,8 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.model.WellbeingModel;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
@@ -50,6 +55,7 @@
import com.android.launcher3.uioverrides.RecentsViewStateController;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SysUINavigationMode;
@@ -67,6 +73,7 @@
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import java.util.HashMap;
import java.util.List;
import java.util.stream.Stream;
@@ -418,18 +425,38 @@
}
@Override
- public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
+ public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
ActivityOptionsWrapper activityOptions =
mAppTransitionManager.hasControlRemoteAppTransitionPermission()
? mAppTransitionManager.getActivityLaunchOptions(this, v)
- : super.getActivityLaunchOptions(v);
+ : super.getActivityLaunchOptions(v, item);
if (mLastTouchUpTime > 0) {
ActivityOptionsCompat.setLauncherSourceInfo(
activityOptions.options, mLastTouchUpTime);
}
+ addLaunchCookie(item, activityOptions.options);
return activityOptions;
}
+ /**
+ * Adds a new launch cookie for the activity launch of the given {@param info} if supported.
+ */
+ public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
+ if (info == null) {
+ return;
+ }
+ switch (info.itemType) {
+ case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+ case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+ case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ // Fall through and continue if it's an app or shortcut
+ break;
+ default:
+ return;
+ }
+ opts.setLaunchCookie(ObjectWrapper.wrap(new Integer(info.id)));
+ }
+
public void setHintUserWillBeActive() {
addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 009ca27..827eb7d 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -693,7 +693,7 @@
matrix.postTranslate(windowTransX0, windowTransY0);
}
- floatingView.update(floatingIconBounds, mIconAlpha.value, percent, 0f,
+ floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f,
mWindowRadius.value * scale, true /* isOpening */);
builder.withMatrix(matrix)
.withWindowCrop(crop)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 9097c8b..0652d48 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -113,7 +113,7 @@
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
float splitPlaceholderAlpha = state.areElementsVisible(mLauncher, SPLIT_PLACHOLDER_VIEW) ?
- 0.7f : 0;
+ 0.85f : 0;
propertySetter.setFloat(mRecentsView.getSplitPlaceholder(), ALPHA_FLOAT,
splitPlaceholderAlpha, LINEAR);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 74a253e..694998c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -267,7 +267,7 @@
}
private float dpiFromPx(float pixels) {
- return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics());
+ return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics().densityDpi);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index dbb8272..53f1fd0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -66,11 +66,13 @@
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
+import android.os.IBinder;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.widget.Toast;
@@ -139,6 +141,8 @@
private final Handler mHandler = new Handler();
// Callbacks to be made once the recents animation starts
private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>();
+ private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll;
+
protected RecentsAnimationController mRecentsAnimationController;
protected RecentsAnimationTargets mRecentsAnimationTargets;
protected T mActivity;
@@ -1043,7 +1047,8 @@
interpolator, target, velocityPxPerMs));
}
- protected abstract HomeAnimationFactory createHomeAnimationFactory(long duration);
+ protected abstract HomeAnimationFactory createHomeAnimationFactory(
+ ArrayList<IBinder> launchCookies, long duration);
private final TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() {
@Override
@@ -1084,7 +1089,8 @@
final RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets != null
? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
: null;
- HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(duration);
+ HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(
+ runningTaskTarget.taskInfo.launchCookies, duration);
mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome()
&& runningTaskTarget != null
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
@@ -1252,7 +1258,7 @@
HomeAnimationFactory homeAnimationFactory) {
RectFSpringAnim anim =
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
- anim.addOnUpdateListener((r, p) -> {
+ anim.addOnUpdateListener((v, r, p) -> {
updateSysUiFlags(Math.max(p, mCurrentShift.value));
});
anim.addAnimatorListener(new AnimationSuccessListener() {
@@ -1368,6 +1374,7 @@
private void invalidateHandlerWithLauncher() {
endLauncherTransitionController();
+ mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
mRecentsView.onGestureAnimationEnd();
resetLauncherListeners();
}
@@ -1395,7 +1402,9 @@
mActivityInterface.onTransitionCancelled(wasVisible);
// Leave the pending invisible flag, as it may be used by wallpaper open animation.
- mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ if (mActivity != null) {
+ mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ }
}
protected void switchToScreenshot() {
@@ -1503,9 +1512,8 @@
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
mSwipePipToHomeAnimator.getComponentName(),
mSwipePipToHomeAnimator.getDestinationBounds());
- mRecentsAnimationController.setFinishTaskBounds(
+ mRecentsAnimationController.setFinishTaskTransaction(
mSwipePipToHomeAnimator.getTaskId(),
- mSwipePipToHomeAnimator.getDestinationBounds(),
mSwipePipToHomeAnimator.getFinishTransaction());
mIsSwipingPipToHome = false;
}
@@ -1560,17 +1568,19 @@
mRecentsAnimationTargets.addReleaseCheck(applier));
});
- mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
- if (moveWindowWithRecentsScroll()) {
- updateFinalShift();
- }
- });
+ mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
runOnRecentsAnimationStart(() ->
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
mRecentsAnimationTargets));
mRecentsViewScrollLinked = true;
}
+ private void onRecentsViewScroll() {
+ if (moveWindowWithRecentsScroll()) {
+ updateFinalShift();
+ }
+ }
+
protected void startNewTask(Consumer<Boolean> resultCallback) {
// Launch the task user scrolled to (mRecentsView.getNextPage()).
if (!mCanceled) {
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index ec1cc4a..9846ee7 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -38,6 +38,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -48,6 +49,7 @@
import android.view.SurfaceControl.Transaction;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
@@ -56,6 +58,7 @@
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.util.TransformParams.BuilderProxy;
@@ -66,6 +69,7 @@
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.UUID;
import java.util.function.Consumer;
@@ -124,7 +128,8 @@
}
@Override
- protected HomeAnimationFactory createHomeAnimationFactory(long duration) {
+ protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
+ long duration) {
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
Intent intent = new Intent(mGestureState.getHomeIntent());
@@ -298,7 +303,8 @@
}
@Override
- public void update(RectF currentRect, float progress, float radius) {
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) {
if (mSurfaceControl != null) {
currentRect.roundOut(mTempRect);
Transaction t = new Transaction();
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 311ac83..dd35d68 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -15,28 +15,51 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.Utilities.dpToPx;
+import static com.android.launcher3.Utilities.mapToRange;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
+import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.RectF;
+import android.os.IBinder;
import android.os.UserHandle;
import android.view.View;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.Workspace;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.util.DynamicResource;
+import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.FloatingIconView;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.plugins.ResourceProvider;
import com.android.systemui.shared.system.InputConsumerController;
+import java.util.ArrayList;
+
/**
* Temporary class to allow easier refactoring
*/
@@ -52,38 +75,47 @@
@Override
- protected HomeAnimationFactory createHomeAnimationFactory(long duration) {
+ protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
+ long duration) {
HomeAnimationFactory homeAnimFactory;
if (mActivity != null) {
- final TaskView runningTaskView = mRecentsView.getRunningTaskView();
- final View workspaceView;
- if (runningTaskView != null
- && !mIsSwipingPipToHome
- && runningTaskView.getTask().key.getComponent() != null) {
- workspaceView = mActivity.getWorkspace().getFirstMatchForAppClose(
- runningTaskView.getTask().key.getComponent().getPackageName(),
- UserHandle.of(runningTaskView.getTask().key.userId));
- } else {
- workspaceView = null;
- }
- final RectF iconLocation = new RectF();
+ final View workspaceView = findWorkspaceView(launchCookies,
+ mRecentsView.getRunningTaskView());
boolean canUseWorkspaceView =
workspaceView != null && workspaceView.isAttachedToWindow();
- FloatingIconView floatingIconView = canUseWorkspaceView
- ? FloatingIconView.getFloatingIconView(mActivity, workspaceView,
- true /* hideOriginal */, iconLocation, false /* isOpening */)
- : null;
mActivity.getRootView().setForceHideBackArrow(true);
mActivity.setHintUserWillBeActive();
if (canUseWorkspaceView) {
+ final ResourceProvider rp = DynamicResource.provider(mActivity);
+ final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+ float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s));
+ final float launcherAlphaMax =
+ rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress);
+
+ RectF iconLocation = new RectF();
+ FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
+ true /* hideOriginal */, iconLocation, false /* isOpening */);
+
// We want the window alpha to be 0 once this threshold is met, so that the
// FolderIconView can be seen morphing into the icon shape.
float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
homeAnimFactory = new LauncherHomeAnimationFactory() {
+
+ // There is a delay in loading the icon, so we need to keep the window
+ // opaque until it is ready.
+ private boolean mIsFloatingIconReady = false;
+
+ private @Nullable ValueAnimator mBounceBackAnimator;
+
@Override
public RectF getWindowTargetRect() {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ // We want the target rect to be at this offset position, so that all
+ // launcher content can spring back upwards.
+ floatingIconView.setPositionOffsetY(transY);
+ }
return iconLocation;
}
@@ -92,17 +124,92 @@
anim.addAnimatorListener(floatingIconView);
floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
floatingIconView.setFastFinishRunnable(anim::end);
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ mBounceBackAnimator = bounceBackToRestingPosition();
+ // Use a spring to put drag layer translation back to 0.
+ anim.addAnimatorListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ floatingIconView.setPositionOffsetY(0);
+ mBounceBackAnimator.start();
+ }
+ });
+
+ Workspace workspace = mActivity.getWorkspace();
+ workspace.setPivotToScaleWithSelf(mActivity.getHotseat());
+ }
+ }
+
+ private ValueAnimator bounceBackToRestingPosition() {
+ DragLayer dl = mActivity.getDragLayer();
+ Workspace workspace = mActivity.getWorkspace();
+ Hotseat hotseat = mActivity.getHotseat();
+
+ final float startValue = transY;
+ final float endValue = 0;
+ // Ensures the velocity is always aligned with the direction.
+ float pixelPerSecond = Math.abs(dpPerSecond)
+ * Math.signum(endValue - transY);
+
+ ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
+ .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
+ .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
+ .setMinimumVisibleChange(1f)
+ .setStartValue(startValue)
+ .setEndValue(endValue)
+ .setStartVelocity(pixelPerSecond)
+ .build(dl, VIEW_TRANSLATE_Y);
+ springTransY.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ dl.setTranslationY(0f);
+ dl.setAlpha(1f);
+ SCALE_PROPERTY.set(workspace, 1f);
+ SCALE_PROPERTY.set(hotseat, 1f);
+ }
+ });
+ return springTransY;
}
@Override
- public void update(RectF currentRect, float progress, float radius) {
- floatingIconView.update(currentRect, 1f, progress, windowAlphaThreshold,
- radius, false);
+ public boolean keepWindowOpaque() {
+ if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
+ mIsFloatingIconReady = true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ int fgAlpha = 255;
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ DragLayer dl = mActivity.getDragLayer();
+ float translationY = config.getWorkspaceTransY();
+ dl.setTranslationY(translationY);
+
+ float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR);
+ dl.setAlpha(Math.min(alpha, 1f));
+
+ float scale = Math.min(1f, config.getWorkspaceScale());
+ SCALE_PROPERTY.set(mActivity.getWorkspace(), scale);
+ SCALE_PROPERTY.set(mActivity.getHotseat(), scale);
+ SCALE_PROPERTY.set(mActivity.getAppsView(), scale);
+
+ progress = config.getInterpolatedProgress();
+ fgAlpha = config.getFgAlpha();
+ }
+ floatingIconView.update(1f, fgAlpha, currentRect, progress,
+ windowAlphaThreshold, radius, false);
}
@Override
public void onCancel() {
floatingIconView.fastFinish();
+ if (mBounceBackAnimator != null) {
+ mBounceBackAnimator.cancel();
+ }
}
};
} else {
@@ -121,6 +228,37 @@
return homeAnimFactory;
}
+ /**
+ * Returns the associated view on the workspace matching one of the launch cookies, or the app
+ * associated with the running task.
+ */
+ @Nullable
+ private View findWorkspaceView(ArrayList<IBinder> launchCookies, TaskView runningTaskView) {
+ if (mIsSwipingPipToHome) {
+ // Disable if swiping to PIP
+ return null;
+ }
+ if (runningTaskView == null || runningTaskView.getTask() == null
+ || runningTaskView.getTask().key.getComponent() == null) {
+ // Disable if it's an invalid task
+ return null;
+ }
+
+ // Find the associated item info for the launch cookie (if available)
+ int launchCookieItemId = -1;
+ for (IBinder cookie : launchCookies) {
+ Integer itemId = ObjectWrapper.unwrap(cookie);
+ if (itemId != null) {
+ launchCookieItemId = itemId;
+ break;
+ }
+ }
+
+ return mActivity.getWorkspace().getFirstMatchForAppClose(launchCookieItemId,
+ runningTaskView.getTask().key.getComponent().getPackageName(),
+ UserHandle.of(runningTaskView.getTask().key.userId));
+ }
+
@Override
protected void finishRecentsControllerToHome(Runnable callback) {
mRecentsAnimationController.finish(
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 7c453e7..ec224ed 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -37,6 +37,8 @@
import android.os.Looper;
import android.view.View;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -48,6 +50,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -177,9 +180,9 @@
}
@Override
- public ActivityOptionsWrapper getActivityLaunchOptions(final View v) {
+ public ActivityOptionsWrapper getActivityLaunchOptions(final View v, @Nullable ItemInfo item) {
if (!(v instanceof TaskView)) {
- return super.getActivityLaunchOptions(v);
+ return super.getActivityLaunchOptions(v, item);
}
final TaskView taskView = (TaskView) v;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 82e8a93..4560735 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -19,7 +19,6 @@
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import android.graphics.Rect;
import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.NonNull;
@@ -145,18 +144,16 @@
}
/**
- * Sets the final bounds on a Task. This is used by Launcher to notify the system that
- * animating Activity to PiP has completed and the associated task surface should be updated
- * accordingly. This should be called before `finish`
+ * Sets the final surface transaction on a Task. This is used by Launcher to notify the system
+ * that animating Activity to PiP has completed and the associated task surface should be
+ * updated accordingly. This should be called before `finish`
* @param taskId for which the leash should be updated
- * @param destinationBounds bounds of the final PiP window
* @param finishTransaction leash operations for the final transform.
*/
- public void setFinishTaskBounds(int taskId, Rect destinationBounds,
+ public void setFinishTaskTransaction(int taskId,
PictureInPictureSurfaceTransaction finishTransaction) {
UI_HELPER_EXECUTOR.execute(
- () -> mController.setFinishTaskBounds(taskId, destinationBounds,
- finishTransaction));
+ () -> mController.setFinishTaskTransaction(taskId, finishTransaction));
}
/**
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 23e35f6..6cf12a3 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -17,8 +17,8 @@
import static android.content.Intent.ACTION_USER_UNLOCKED;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
@@ -62,7 +62,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.DisplayHolder;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.SettingsCache;
@@ -91,7 +90,7 @@
private final Context mContext;
private final SysUINavigationMode mSysUiNavMode;
- private final DisplayHolder mDisplayHolder;
+ private final DisplayController mDisplayController;
private final int mDisplayId;
private final RotationTouchHelper mRotationTouchHelper;
@@ -128,17 +127,13 @@
private boolean mIsUserSetupComplete;
public RecentsAnimationDeviceState(Context context) {
- this(context, DisplayController.getDefaultDisplay(context));
- }
-
- public RecentsAnimationDeviceState(Context context, DisplayHolder displayHolder) {
mContext = context;
- mDisplayHolder = displayHolder;
+ mDisplayController = DisplayController.INSTANCE.get(context);
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
- mDisplayId = mDisplayHolder.getInfo().id;
+ mDisplayId = mDisplayController.getInfo().id;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
- runOnDestroy(() -> mDisplayHolder.removeChangeListener(this));
- mRotationTouchHelper = new RotationTouchHelper(context, mDisplayHolder);
+ runOnDestroy(() -> mDisplayController.removeChangeListener(this));
+ mRotationTouchHelper = new RotationTouchHelper(context, mDisplayController);
runOnDestroy(mRotationTouchHelper::destroy);
// Register for user unlocked if necessary
@@ -244,9 +239,9 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- mDisplayHolder.removeChangeListener(this);
- mDisplayHolder.addChangeListener(this);
- onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
+ mDisplayController.removeChangeListener(this);
+ mDisplayController.addChangeListener(this);
+ onDisplayInfoChanged(mDisplayController.getInfo(), CHANGE_ALL);
if (newMode == NO_BUTTON) {
mExclusionListener.register();
@@ -254,7 +249,7 @@
mExclusionListener.unregister();
}
- mNavBarPosition = new NavBarPosition(newMode, mDisplayHolder.getInfo());
+ mNavBarPosition = new NavBarPosition(newMode, mDisplayController.getInfo());
mMode = newMode;
}
@@ -556,11 +551,11 @@
}
if (mIsOneHandedModeEnabled || mIsSwipeToNotificationEnabled) {
- final Info displayInfo = mDisplayHolder.getInfo();
+ final Info displayInfo = mDisplayController.getInfo();
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
&& displayInfo.rotation != Surface.ROTATION_90
&& displayInfo.rotation != Surface.ROTATION_270
- && displayInfo.metrics.densityDpi < DisplayMetrics.DENSITY_600);
+ && displayInfo.densityDpi < DisplayMetrics.DENSITY_600);
}
return false;
}
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2cf3212..d4ad176 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -17,8 +17,8 @@
import static android.view.Surface.ROTATION_0;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
@@ -28,7 +28,7 @@
import android.view.OrientationEventListener;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.DisplayController.DisplayHolder;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.quickstep.util.RecentsOrientedState;
@@ -44,7 +44,7 @@
DisplayInfoChangeListener {
private final OrientationTouchTransformer mOrientationTouchTransformer;
- private final DisplayHolder mDisplayHolder;
+ private final DisplayController mDisplayController;
private final SysUINavigationMode mSysUiNavMode;
private final int mDisplayId;
private int mDisplayRotation;
@@ -121,12 +121,12 @@
private final Context mContext;
- public RotationTouchHelper(Context context, DisplayHolder displayHolder) {
+ public RotationTouchHelper(Context context, DisplayController displayController) {
mContext = context;
- mDisplayHolder = displayHolder;
+ mDisplayController = displayController;
Resources resources = mContext.getResources();
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
- mDisplayId = mDisplayHolder.getInfo().id;
+ mDisplayId = mDisplayController.getInfo().id;
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
() -> QuickStepContract.getWindowCornerRadius(resources));
@@ -201,7 +201,7 @@
return;
}
- mOrientationTouchTransformer.createOrAddTouchRegion(mDisplayHolder.getInfo());
+ mOrientationTouchTransformer.createOrAddTouchRegion(mDisplayController.getInfo());
}
/**
@@ -223,11 +223,11 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- mDisplayHolder.removeChangeListener(this);
- mDisplayHolder.addChangeListener(this);
- onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
+ mDisplayController.removeChangeListener(this);
+ mDisplayController.addChangeListener(this);
+ onDisplayInfoChanged(mDisplayController.getInfo(), CHANGE_ALL);
- mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayHolder.getInfo(),
+ mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayController.getInfo(),
mContext.getResources());
if (!mMode.hasGestures && newMode.hasGestures) {
setupOrientationSwipeHandler();
@@ -276,8 +276,8 @@
* Sets the gestural height.
*/
void setGesturalHeight(int newGesturalHeight) {
- mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDisplayHolder.getInfo(),
- mContext.getResources());
+ mOrientationTouchTransformer.setGesturalHeight(
+ newGesturalHeight, mDisplayController.getInfo(), mContext.getResources());
}
/**
@@ -293,7 +293,7 @@
}
private void enableMultipleRegions(boolean enable) {
- mOrientationTouchTransformer.enableMultipleRegions(enable, mDisplayHolder.getInfo());
+ mOrientationTouchTransformer.enableMultipleRegions(enable, mDisplayController.getInfo());
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
// Clear any previous state from sensor manager
@@ -356,7 +356,7 @@
* notifies system UI of the primary rotation the user is interacting with
*/
private void toggleSecondaryNavBarsForRotation() {
- mOrientationTouchTransformer.setSingleActiveRegion(mDisplayHolder.getInfo());
+ mOrientationTouchTransformer.setSingleActiveRegion(mDisplayController.getInfo());
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index a8c09dc..0f34a72 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
import android.animation.Animator;
import android.content.Context;
@@ -26,6 +27,7 @@
import android.graphics.RectF;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.DeviceProfile;
@@ -35,7 +37,9 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.RectFSpringAnim2;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.util.TransformParams.BuilderProxy;
@@ -149,7 +153,10 @@
public void setAnimation(RectFSpringAnim anim) { }
- public void update(RectF currentRect, float progress, float radius) { }
+ public boolean keepWindowOpaque() { return false; }
+
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) { }
public void onCancel() { }
@@ -199,7 +206,14 @@
homeToWindowPositionMap.invert(windowToHomePositionMap);
windowToHomePositionMap.mapRect(startRect);
- RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext);
+ RectFSpringAnim anim;
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ anim = new RectFSpringAnim2(startRect, targetRect, mContext,
+ mTaskViewSimulator.getCurrentCornerRadius(),
+ cropRectF.width() / 2f);
+ } else {
+ anim = new RectFSpringAnim(startRect, targetRect, mContext);
+ }
homeAnimationFactory.setAnimation(anim);
SpringAnimationRunner runner = new SpringAnimationRunner(
@@ -259,18 +273,26 @@
}
@Override
- public void onUpdate(RectF currentRect, float progress) {
+ public void onUpdate(@Nullable AppCloseConfig config, RectF currentRect, float progress) {
mHomeAnim.setPlayFraction(progress);
mHomeToWindowPositionMap.mapRect(mWindowCurrentRect, currentRect);
mMatrix.setRectToRect(mCropRectF, mWindowCurrentRect, ScaleToFit.FILL);
float cornerRadius = Utilities.mapRange(progress, mStartRadius, mEndRadius);
+ float alpha = getWindowAlpha(progress);
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ alpha = config.getWindowAlpha();
+ cornerRadius = config.getCornerRadius();
+ }
+ if (mAnimationFactory.keepWindowOpaque()) {
+ alpha = 1f;
+ }
mTransformParams
- .setTargetAlpha(getWindowAlpha(progress))
+ .setTargetAlpha(alpha)
.setCornerRadius(cornerRadius);
-
mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
- mAnimationFactory.update(currentRect, progress, mMatrix.mapRadius(cornerRadius));
+ mAnimationFactory.update(config, currentRect, progress,
+ mMatrix.mapRadius(cornerRadius));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 1db5872..a59ba51 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -209,7 +209,7 @@
// RecentsView never updates the display rotation until swipe-up so the value may
// be stale. Use the display value instead.
- int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
+ int displayRotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
tsv.getOrientationState().update(displayRotation, displayRotation);
tsv.setPreview(targets.apps[targets.apps.length - 1]);
@@ -437,7 +437,7 @@
// RecentsView never updates the display rotation until swipe-up so the value may
// be stale. Use the display value instead.
- int displayRotation = DisplayController.getDefaultDisplay(recentsView.getContext())
+ int displayRotation = DisplayController.INSTANCE.get(recentsView.getContext())
.getInfo().rotation;
tvs.getOrientationState().update(displayRotation, displayRotation);
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index e9d2eb4..18c0b7a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -149,6 +149,8 @@
@BinderThread
public void onInitialize(Bundle bundle) {
+ Log.d(TAG + " b/182478748", "TouchInteractionService.onInitialize: user="
+ + getUserId());
ISystemUiProxy proxy = ISystemUiProxy.Stub.asInterface(
bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
IPip pip = IPip.Stub.asInterface(bundle.getBinder(KEY_EXTRA_SHELL_PIP));
@@ -310,6 +312,8 @@
}
private void disposeEventHandlers() {
+ Log.d(TAG + " b/182478748", "TouchInteractionService.disposeEventHandlers: user="
+ + getUserId());
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
@@ -321,6 +325,8 @@
}
private void initInputMonitor() {
+ Log.d(TAG + " b/182478748", "TouchInteractionService.initInputMonitor: user="
+ + getUserId());
disposeEventHandlers();
if (TestProtocol.sDebugTracing) {
@@ -329,9 +335,11 @@
}
if (mDeviceState.isButtonNavMode()) {
+ Log.d(TAG + " b/182478748", "isButtonNav: user=" + getUserId());
return;
}
+ Log.d(TAG + " b/182478748", "create swipe-up input monitor: user=" + getUserId());
mInputMonitorCompat = new InputMonitorCompat("swipe-up", mDeviceState.getDisplayId());
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
@@ -448,6 +456,7 @@
@Override
public void onDestroy() {
+ Log.d(TAG, "Touch service destroyed: user=" + getUserId());
sIsInitialized = false;
if (mDeviceState.isUserUnlocked()) {
mInputConsumer.unregisterInputConsumer();
@@ -469,7 +478,7 @@
@Override
public IBinder onBind(Intent intent) {
- Log.d(TAG, "Touch service connected");
+ Log.d(TAG, "Touch service connected: user=" + getUserId());
return mMyBinder;
}
@@ -506,7 +515,8 @@
}
mRotationTouchHelper.setOrientationTransformIfNeeded(event);
- if (mRotationTouchHelper.isInSwipeUpTouchRegion(event)) {
+ if (!mDeviceState.isOneHandedModeActive()
+ && mRotationTouchHelper.isInSwipeUpTouchRegion(event)) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_SWIPE_TO_HOME,
"TouchInteractionService.onInputEvent:isInSwipeUpTouchRegion");
@@ -535,8 +545,7 @@
InputConsumer.NO_OP, mInputMonitorCompat,
mDeviceState,
event);
- } else if (mDeviceState.canTriggerOneHandedAction(event)
- && !mDeviceState.isOneHandedModeActive()) {
+ } else if (mDeviceState.canTriggerOneHandedAction(event)) {
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
InputConsumer.NO_OP, mInputMonitorCompat);
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index a4a7bd3..9d9ef94 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -43,7 +43,7 @@
SysUINavigationMode.Mode sysUINavigationMode = SysUINavigationMode.getMode(mActivity);
if (sysUINavigationMode == SysUINavigationMode.Mode.NO_BUTTON) {
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
- DisplayController.getDefaultDisplay(mActivity).getInfo());
+ DisplayController.INSTANCE.get(mActivity).getInfo());
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
true /* disableHorizontalSwipe */, navBarPosition,
null /* onInterceptTouch */, this);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 85ecab1..9c64794 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -116,7 +116,7 @@
R.dimen.device_locked_y_offset);
// Do not use DeviceProfile as the user data might be locked
- mDisplaySize = DisplayController.getDefaultDisplay(context).getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().realSize;
// Init states
mStateCallback = new MultiStateCallback(STATE_NAMES);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
index cd69cf1..d82d43d 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
@@ -44,12 +44,10 @@
*/
public class OneHandedModeInputConsumer extends DelegateInputConsumer {
- private static final String TAG = "OneHandedModeInputConsumer";
private static final int ANGLE_MAX = 150;
private static final int ANGLE_MIN = 30;
private final Context mContext;
- private final DisplayController.DisplayHolder mDisplayHolder;
private final Point mDisplaySize;
private final RecentsAnimationDeviceState mDeviceState;
@@ -68,12 +66,11 @@
InputConsumer delegate, InputMonitorCompat inputMonitor) {
super(delegate, inputMonitor);
mContext = context;
- mDisplayHolder = DisplayController.getDefaultDisplay(mContext);
mDeviceState = deviceState;
mDragDistThreshold = context.getResources().getDimensionPixelSize(
R.dimen.gestures_onehanded_drag_threshold);
mSquaredSlop = Utilities.squaredTouchSlop(context);
- mDisplaySize = mDisplayHolder.getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(mContext).getInfo().realSize;
mNavBarSize = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE,
mContext.getResources());
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 7c293c3..957f776 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -32,33 +32,6 @@
}
@Override
- Integer getTitleStringId() {
- switch (mTutorialType) {
- case ASSISTANT:
- return R.string.assistant_gesture_tutorial_playground_title;
- case ASSISTANT_COMPLETE:
- return R.string.gesture_tutorial_confirm_title;
- }
- return null;
- }
-
- @Override
- Integer getSubtitleStringId() {
- if (mTutorialType == TutorialType.ASSISTANT) {
- return R.string.assistant_gesture_tutorial_playground_subtitle;
- }
- return null;
- }
-
- @Override
- Integer getActionButtonStringId() {
- if (mTutorialType == ASSISTANT_COMPLETE) {
- return R.string.gesture_tutorial_action_button_label_done;
- }
- return null;
- }
-
- @Override
public void onBackGestureAttempted(BackGestureResult result) {
switch (mTutorialType) {
case ASSISTANT:
@@ -96,14 +69,8 @@
break;
case ASSISTANT_COMPLETED:
hideFeedback(true);
- showRippleEffect(
- () -> {
- if (mTutorialFragment.isTutorialComplete()) {
- mTutorialFragment.changeController(ASSISTANT_COMPLETE);
- } else {
- mTutorialFragment.continueTutorial();
- }
- });
+ showRippleEffect(null);
+ showFeedback(R.string.assistant_gesture_tutorial_playground_subtitle);
break;
case ASSISTANT_NOT_STARTED_BAD_ANGLE:
showFeedback(R.string.assistant_gesture_feedback_swipe_not_diagonal);
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 300ca7d..c396eec 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -36,58 +36,24 @@
super(fragment, tutorialType);
}
- @Override
- Integer getTitleStringId() {
- switch (mTutorialType) {
- case RIGHT_EDGE_BACK_NAVIGATION:
- case LEFT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_intro_title;
- case BACK_NAVIGATION_COMPLETE:
- return R.string.gesture_tutorial_confirm_title;
- }
- return null;
- }
-
- @Override
- Integer getSubtitleStringId() {
- switch (mTutorialType) {
- case RIGHT_EDGE_BACK_NAVIGATION:
- case LEFT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_intro_subtitle;
- case BACK_NAVIGATION_COMPLETE:
- return R.string.back_gesture_tutorial_confirm_subtitle;
- }
- return null;
- }
-
- @Override
- Integer getActionButtonStringId() {
- if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
- return R.string.gesture_tutorial_action_button_label_done;
- }
- return null;
- }
-
- @Override
- Integer getActionTextButtonStringId() {
- if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
- return R.string.gesture_tutorial_action_button_label_settings;
- }
- return null;
- }
-
- @Override
- void onActionTextButtonClicked(View button) {
- mTutorialFragment.startSystemNavigationSetting();
- }
-
@Nullable
- @Override
public View getMockLauncherView() {
return null;
}
@Override
+ public Integer getIntroductionTitle() {
+ return mTutorialType == LEFT_EDGE_BACK_NAVIGATION
+ ? R.string.back_gesture_intro_title : null;
+ }
+
+ @Override
+ public Integer getIntroductionSubtitle() {
+ return mTutorialType == LEFT_EDGE_BACK_NAVIGATION
+ ? R.string.back_gesture_intro_subtitle : null;
+ }
+
+ @Override
public void onBackGestureAttempted(BackGestureResult result) {
switch (mTutorialType) {
case RIGHT_EDGE_BACK_NAVIGATION:
@@ -112,8 +78,7 @@
mFakeTaskView.setBackground(AppCompatResources.getDrawable(mContext,
R.drawable.sandbox_fake_google_search));
showRippleEffect(null);
- showFeedback(R.string.back_gesture_feedback_complete,
- mTutorialFragment::continueTutorial);
+ showFeedback(R.string.back_gesture_feedback_complete, true);
break;
case BACK_CANCELLED_FROM_RIGHT:
showFeedback(R.string.back_gesture_feedback_cancelled_right_edge);
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index b3eb1c0..71d00f0 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -29,8 +29,8 @@
@Override
Integer getFeedbackVideoResId() {
return mTutorialType == TutorialType.RIGHT_EDGE_BACK_NAVIGATION
- ? R.raw.tips_nav_back_right
- : R.raw.tips_nav_back_left;
+ ? R.drawable.gesture_tutorial_back_right
+ : R.drawable.gesture_tutorial_back_left;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index ebb4bfc..c3b342b 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -41,8 +41,12 @@
private static final String KEY_TUTORIAL_STEPS = "tutorial_steps";
private Deque<TutorialType> mTutorialSteps;
+ private TutorialType mCurrentTutorialStep;
private TutorialFragment mFragment;
+ private int mCurrentStep;
+ private int mNumSteps;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -51,7 +55,10 @@
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
mTutorialSteps = getTutorialSteps(args);
- mFragment = TutorialFragment.newInstance(mTutorialSteps.pop());
+ mCurrentStep = 1;
+ mNumSteps = mTutorialSteps.size();
+ mCurrentTutorialStep = mTutorialSteps.pop();
+ mFragment = TutorialFragment.newInstance(mCurrentTutorialStep);
getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit();
@@ -89,6 +96,21 @@
return mTutorialSteps.isEmpty();
}
+ public int getCurrentStep() {
+ return mCurrentStep;
+ }
+
+ public int getNumSteps() {
+ return mNumSteps;
+ }
+
+ /**
+ * Closes the tutorial and this activity.
+ */
+ public void closeTutorial() {
+ mFragment.closeTutorial();
+ }
+
/**
* Replaces the current TutorialFragment, continuing to the next tutorial step if there is one.
*
@@ -99,17 +121,20 @@
mFragment.closeTutorial();
return;
}
- mFragment = TutorialFragment.newInstance(mTutorialSteps.pop());
+ mCurrentTutorialStep = mTutorialSteps.pop();
+ mFragment = TutorialFragment.newInstance(mCurrentTutorialStep);
getSupportFragmentManager().beginTransaction()
.replace(R.id.gesture_tutorial_fragment_container, mFragment)
.runOnCommit(() -> mFragment.onAttachedToWindow())
.commit();
+ mCurrentStep++;
}
private String[] getTutorialStepNames() {
- String[] tutorialStepNames = new String[mTutorialSteps.size()];
+ String[] tutorialStepNames = new String[mTutorialSteps.size() + 1];
- int i = 0;
+ int i = 1;
+ tutorialStepNames[0] = mCurrentTutorialStep.name();
for (TutorialType tutorialStep : mTutorialSteps) {
tutorialStepNames[i++] = tutorialStep.name();
}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index d0f21c2..2e580af 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.quickstep.interaction.TutorialController.TutorialType.HOME_NAVIGATION_COMPLETE;
-
import android.annotation.TargetApi;
import android.graphics.PointF;
import android.os.Build;
@@ -34,30 +32,13 @@
}
@Override
- Integer getTitleStringId() {
- switch (mTutorialType) {
- case HOME_NAVIGATION:
- return R.string.home_gesture_intro_title;
- case HOME_NAVIGATION_COMPLETE:
- return R.string.gesture_tutorial_confirm_title;
- }
- return null;
+ public Integer getIntroductionTitle() {
+ return R.string.home_gesture_intro_title;
}
@Override
- Integer getSubtitleStringId() {
- if (mTutorialType == TutorialType.HOME_NAVIGATION) {
- return R.string.home_gesture_intro_subtitle;
- }
- return null;
- }
-
- @Override
- Integer getActionButtonStringId() {
- if (mTutorialType == HOME_NAVIGATION_COMPLETE) {
- return R.string.gesture_tutorial_action_button_label_done;
- }
- return null;
+ public Integer getIntroductionSubtitle() {
+ return R.string.home_gesture_intro_subtitle;
}
@Override
@@ -92,8 +73,9 @@
switch (result) {
case HOME_GESTURE_COMPLETED: {
animateFakeTaskViewHome(finalVelocity, null);
+ showActionButton();
showFeedback(R.string.home_gesture_feedback_complete,
- mTutorialFragment::continueTutorial);
+ true);
break;
}
case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 31e0351..ebddc69 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -25,7 +25,7 @@
@Nullable
@Override
Integer getFeedbackVideoResId() {
- return R.raw.tips_nav_home;
+ return R.drawable.gesture_tutorial_home;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 66e6a0d..3c59ed3 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -43,30 +43,13 @@
}
@Override
- Integer getTitleStringId() {
- switch (mTutorialType) {
- case OVERVIEW_NAVIGATION:
- return R.string.overview_gesture_intro_title;
- case OVERVIEW_NAVIGATION_COMPLETE:
- return R.string.gesture_tutorial_confirm_title;
- }
- return null;
+ public Integer getIntroductionTitle() {
+ return R.string.overview_gesture_intro_title;
}
@Override
- Integer getSubtitleStringId() {
- if (mTutorialType == TutorialType.OVERVIEW_NAVIGATION) {
- return R.string.overview_gesture_intro_subtitle;
- }
- return null;
- }
-
- @Override
- Integer getActionButtonStringId() {
- if (mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
- return R.string.gesture_tutorial_action_button_label_done;
- }
- return null;
+ public Integer getIntroductionSubtitle() {
+ return R.string.overview_gesture_intro_subtitle;
}
@Nullable
@@ -124,8 +107,7 @@
animset.start();
mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
onMotionPaused(true /*arbitrary value*/);
- showFeedback(R.string.overview_gesture_feedback_complete,
- mTutorialFragment::continueTutorial);
+ showFeedback(R.string.overview_gesture_feedback_complete, true);
break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED:
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index c6213e3..86344ab 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -25,7 +25,7 @@
@Nullable
@Override
Integer getFeedbackVideoResId() {
- return R.raw.tips_nav_overview;
+ return R.drawable.gesture_tutorial_overview;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
index 3a6d434..4e4b81a 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
@@ -17,8 +17,6 @@
import android.graphics.PointF;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.R;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
@@ -30,24 +28,6 @@
super(fragment, tutorialType);
}
- @Nullable
- @Override
- Integer getTitleStringId() {
- return R.string.sandbox_mode_title;
- }
-
- @Nullable
- @Override
- Integer getSubtitleStringId() {
- return R.string.sandbox_mode_subtitle;
- }
-
- @Nullable
- @Override
- Integer getActionButtonStringId() {
- return null;
- }
-
@Override
public void onBackGestureAttempted(BackGestureResult result) {
switch (result) {
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 8fc453d..1aa64fa 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -52,6 +52,7 @@
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeUpAnimationLogic;
import com.android.quickstep.SwipeUpAnimationLogic.RunningWindowAnim;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.TransformParams;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -306,11 +307,12 @@
}
@Override
- public void update(RectF rect, float progress, float radius) {
+ public void update(@Nullable AppCloseConfig config, RectF rect, float progress,
+ float radius) {
mFakeIconView.setVisibility(View.VISIBLE);
mFakeIconView.update(rect, progress,
1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */,
- radius,
+ radius, 255,
false, /* isOpening */
mFakeIconView, mDp,
false /* isVerticalBarLayout */);
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index cbab4f9..6f82f85 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -16,19 +16,25 @@
package com.android.quickstep.interaction;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Animatable2;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
+import android.util.Log;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
-import android.widget.VideoView;
import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
import com.android.launcher3.InvariantDeviceProfile;
@@ -41,6 +47,11 @@
abstract class TutorialController implements BackGestureAttemptCallback,
NavBarGestureAttemptCallback {
+ private static final String TAG = "TutorialController";
+
+ private static final String PIXEL_TIPS_APP_PACKAGE_NAME = "com.google.android.apps.tips";
+ private static final CharSequence DEFAULT_PIXEL_TIPS_APP_NAME = "Pixel Tips";
+
private static final int FEEDBACK_VISIBLE_MS = 2500;
private static final int FEEDBACK_ANIMATION_MS = 250;
private static final int RIPPLE_VISIBLE_MS = 300;
@@ -50,20 +61,19 @@
final Context mContext;
final ImageButton mCloseButton;
- final TextView mTitleTextView;
- final TextView mSubtitleTextView;
final ViewGroup mFeedbackView;
- final VideoView mFeedbackVideoView;
+ final ImageView mFeedbackVideoView;
final ImageView mFakeLauncherView;
final ClipIconView mFakeIconView;
final View mFakeTaskView;
final View mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
- final Button mActionTextButton;
final Button mActionButton;
+ final TextView mTutorialStepView;
private final Runnable mHideFeedbackRunnable;
Runnable mHideFeedbackEndAction;
+ private final AlertDialog mSkipTutorialDialog;
TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
mTutorialFragment = tutorialFragment;
@@ -72,9 +82,7 @@
RootSandboxLayout rootView = tutorialFragment.getRootView();
mCloseButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
- mCloseButton.setOnClickListener(button -> mTutorialFragment.closeTutorial());
- mTitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_title_view);
- mSubtitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_subtitle_view);
+ mCloseButton.setOnClickListener(button -> showSkipTutorialDialog());
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
mFeedbackVideoView = rootView.findViewById(R.id.gesture_tutorial_feedback_video);
mFakeLauncherView = rootView.findViewById(R.id.gesture_tutorial_fake_launcher_view);
@@ -84,9 +92,10 @@
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
- mActionTextButton =
- rootView.findViewById(R.id.gesture_tutorial_fragment_action_text_button);
mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
+ mTutorialStepView =
+ rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
+ mSkipTutorialDialog = createSkipTutorialDialog();
mHideFeedbackRunnable =
() -> mFeedbackView.animate()
@@ -95,30 +104,16 @@
.withEndAction(this::hideFeedbackEndAction).start();
}
+ private void showSkipTutorialDialog() {
+ if (mSkipTutorialDialog != null) {
+ mSkipTutorialDialog.show();
+ }
+ }
+
void setTutorialType(TutorialType tutorialType) {
mTutorialType = tutorialType;
}
- @Nullable
- Integer getTitleStringId() {
- return null;
- }
-
- @Nullable
- Integer getSubtitleStringId() {
- return null;
- }
-
- @Nullable
- Integer getActionButtonStringId() {
- return null;
- }
-
- @Nullable
- Integer getActionTextButtonStringId() {
- return null;
- }
-
@DrawableRes
protected int getMockLauncherResId() {
return R.drawable.default_sandbox_mock_launcher;
@@ -155,13 +150,39 @@
mFakeTaskView.animate().alpha(0).setListener(AnimationSuccessListener.forRunnable(r));
}
+ @StringRes
+ public Integer getIntroductionTitle() {
+ return null;
+ }
+
+ @StringRes
+ public Integer getIntroductionSubtitle() {
+ return null;
+ }
+
/**
* Show feedback reflecting a failed gesture attempt.
*
* @param subtitleResId Resource of the text to display.
**/
void showFeedback(int subtitleResId) {
- showFeedback(subtitleResId, null);
+ showFeedback(subtitleResId, false);
+ }
+
+ /**
+ * Show feedback reflecting a failed gesture attempt.
+ *
+ * @param showActionButton Whether the tutorial feedback's action button should be shown.
+ **/
+ void showFeedback(int subtitleResId, boolean showActionButton) {
+ showFeedback(subtitleResId, showActionButton ? () -> {} : null, showActionButton);
+ }
+
+ /**
+ * Show feedback reflecting a failed gesture attempt.
+ **/
+ void showFeedback(int subtitleResId, @Nullable Runnable successEndAction) {
+ showFeedback(subtitleResId, successEndAction, false);
}
/**
@@ -170,32 +191,73 @@
* @param successEndAction Non-null iff the gesture was successful; this is run after the
* feedback is shown (i.e. to go to the next step)
**/
- void showFeedback(int subtitleResId, @Nullable Runnable successEndAction) {
+ void showFeedback(
+ int subtitleResId, @Nullable Runnable successEndAction, boolean showActionButton) {
+ showFeedback(
+ successEndAction == null
+ ? R.string.gesture_tutorial_try_again
+ : R.string.gesture_tutorial_nice,
+ subtitleResId,
+ successEndAction,
+ showActionButton);
+ }
+ void showFeedback(
+ int titleResId,
+ int subtitleResId,
+ @Nullable Runnable successEndAction,
+ boolean showActionButton) {
if (mHideFeedbackEndAction != null) {
return;
}
- int visibleDuration = FEEDBACK_VISIBLE_MS;
- if (mTutorialFragment.getFeedbackVideoResId() != null) {
+ TextView title = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_title);
+ title.setText(titleResId);
+ TextView subtitle =
+ mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
+ subtitle.setText(subtitleResId);
+ if (showActionButton) {
+ showActionButton();
+ }
+ mHideFeedbackEndAction = successEndAction;
+
+ AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
+ if (tutorialAnimation != null) {
if (successEndAction == null) {
- if (mFeedbackVideoView.isPlaying()) {
- mFeedbackVideoView.seekTo(1);
- } else {
- mFeedbackVideoView.start();
+ if (tutorialAnimation.isRunning()) {
+ tutorialAnimation.reset();
}
+ tutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+
+ @Override
+ public void onAnimationStart(Drawable drawable) {
+ super.onAnimationStart(drawable);
+
+ mFeedbackView.setTranslationY(
+ -mFeedbackView.getHeight() - mFeedbackView.getTop());
+ mFeedbackView.setVisibility(View.VISIBLE);
+ mFeedbackView.animate()
+ .setDuration(FEEDBACK_ANIMATION_MS)
+ .translationY(0)
+ .start();
+ }
+
+ @Override
+ public void onAnimationEnd(Drawable drawable) {
+ super.onAnimationEnd(drawable);
+
+ mFeedbackView.removeCallbacks(mHideFeedbackRunnable);
+ mFeedbackView.post(mHideFeedbackRunnable);
+
+ tutorialAnimation.unregisterAnimationCallback(this);
+ }
+ });
+
+ tutorialAnimation.start();
mFeedbackVideoView.setVisibility(View.VISIBLE);
- visibleDuration = mTutorialFragment.getFeedbackVideoDuration();
+ return;
} else {
mTutorialFragment.releaseFeedbackVideoView();
}
}
- TextView title = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_title);
- title.setText(successEndAction == null
- ? R.string.gesture_tutorial_try_again
- : R.string.gesture_tutorial_nice);
- TextView subtitle =
- mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
- subtitle.setText(subtitleResId);
- mHideFeedbackEndAction = successEndAction;
mFeedbackView.setTranslationY(-mFeedbackView.getHeight() - mFeedbackView.getTop());
mFeedbackView.setVisibility(View.VISIBLE);
mFeedbackView.animate()
@@ -203,7 +265,9 @@
.translationY(0)
.start();
mFeedbackView.removeCallbacks(mHideFeedbackRunnable);
- mFeedbackView.postDelayed(mHideFeedbackRunnable, visibleDuration);
+ if (!showActionButton) {
+ mFeedbackView.postDelayed(mHideFeedbackRunnable, FEEDBACK_VISIBLE_MS);
+ }
}
void hideFeedback(boolean releaseFeedbackVideo) {
@@ -239,16 +303,14 @@
}
void onActionButtonClicked(View button) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.continueTutorial();
}
- void onActionTextButtonClicked(View button) {}
-
@CallSuper
void transitToController() {
hideFeedback(false);
- updateTitles();
- updateActionButtons();
+ hideActionButton();
+ updateSubtext();
updateDrawables();
if (mFakeLauncherView != null) {
@@ -256,39 +318,33 @@
}
}
- private void updateTitles() {
- updateTitleView(mTitleTextView, getTitleStringId(),
- R.style.TextAppearance_GestureTutorial_Title);
- updateTitleView(mSubtitleTextView, getSubtitleStringId(),
- R.style.TextAppearance_GestureTutorial_Subtitle);
+ void hideActionButton() {
+ // Invisible to maintain the layout.
+ mActionButton.setVisibility(View.INVISIBLE);
+ mActionButton.setOnClickListener(null);
}
- private void updateTitleView(TextView textView, @Nullable Integer stringId, int styleId) {
- if (stringId == null) {
- textView.setVisibility(View.GONE);
- return;
+ void showActionButton() {
+ int stringResId = -1;
+
+ if (mContext instanceof GestureSandboxActivity) {
+ GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
+
+ stringResId = sandboxActivity.isTutorialComplete()
+ ? R.string.gesture_tutorial_action_button_label_done
+ : R.string.gesture_tutorial_action_button_label_next;
}
- textView.setVisibility(View.VISIBLE);
- textView.setText(stringId);
- textView.setTextAppearance(styleId);
+ mActionButton.setText(stringResId == -1 ? null : mContext.getString(stringResId));
+ mActionButton.setVisibility(View.VISIBLE);
+ mActionButton.setOnClickListener(this::onActionButtonClicked);
}
- private void updateActionButtons() {
- updateButton(mActionButton, getActionButtonStringId(), this::onActionButtonClicked);
- updateButton(
- mActionTextButton, getActionTextButtonStringId(), this::onActionTextButtonClicked);
- }
-
- private void updateButton(Button button, @Nullable Integer stringId, OnClickListener listener) {
- if (stringId == null) {
- button.setVisibility(View.INVISIBLE);
- return;
- }
-
- button.setVisibility(View.VISIBLE);
- button.setText(stringId);
- button.setOnClickListener(listener);
+ private void updateSubtext() {
+ mTutorialStepView.setText(mContext.getString(
+ R.string.gesture_tutorial_step,
+ mTutorialFragment.getCurrentStep(),
+ mTutorialFragment.getNumSteps()));
}
private void updateDrawables() {
@@ -309,11 +365,67 @@
}
}
- private boolean isComplete() {
- return mTutorialType == TutorialType.BACK_NAVIGATION_COMPLETE
- || mTutorialType == TutorialType.HOME_NAVIGATION_COMPLETE
- || mTutorialType == TutorialType.OVERVIEW_NAVIGATION_COMPLETE
- || mTutorialType == TutorialType.ASSISTANT_COMPLETE;
+ private AlertDialog createSkipTutorialDialog() {
+ if (mContext instanceof GestureSandboxActivity) {
+ GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
+ View contentView = View.inflate(
+ sandboxActivity, R.layout.gesture_tutorial_dialog, null);
+ AlertDialog tutorialDialog = new AlertDialog
+ .Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
+ .setView(contentView)
+ .create();
+
+ PackageManager packageManager = mContext.getPackageManager();
+ CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
+
+ try {
+ tipsAppName = packageManager.getApplicationLabel(
+ packageManager.getApplicationInfo(
+ PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG,
+ "Could not find app label for package name: "
+ + PIXEL_TIPS_APP_PACKAGE_NAME
+ + ". Defaulting to 'Pixel Tips.'",
+ e);
+ }
+
+ TextView subtitleTextView = (TextView) contentView.findViewById(
+ R.id.gesture_tutorial_dialog_subtitle);
+ if (subtitleTextView != null) {
+ subtitleTextView.setText(
+ mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
+ } else {
+ Log.w(TAG, "No subtitle view in the skip tutorial dialog to update.");
+ }
+
+ Button cancelButton = (Button) contentView.findViewById(
+ R.id.gesture_tutorial_dialog_cancel_button);
+ if (cancelButton != null) {
+ cancelButton.setOnClickListener(
+ v -> tutorialDialog.dismiss());
+ } else {
+ Log.w(TAG, "No cancel button in the skip tutorial dialog to update.");
+ }
+
+ Button confirmButton = contentView.findViewById(
+ R.id.gesture_tutorial_dialog_confirm_button);
+ if (confirmButton != null) {
+ confirmButton.setOnClickListener(v -> {
+ sandboxActivity.closeTutorial();
+ tutorialDialog.dismiss();
+ });
+ } else {
+ Log.w(TAG, "No confirm button in the skip tutorial dialog to update.");
+ }
+
+ tutorialDialog.getWindow().setBackgroundDrawable(
+ new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
+
+ return tutorialDialog;
+ }
+
+ return null;
}
/** Denotes the type of the tutorial. */
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 6e30ad0..b6663b8 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -16,9 +16,12 @@
package com.android.quickstep.interaction;
import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Insets;
-import android.net.Uri;
+import android.graphics.drawable.Animatable2;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -27,7 +30,7 @@
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowInsets;
-import android.widget.VideoView;
+import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -35,7 +38,6 @@
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.quickstep.interaction.TutorialController.TutorialType;
abstract class TutorialFragment extends Fragment implements OnTouchListener {
@@ -48,8 +50,10 @@
RootSandboxLayout mRootView;
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarGestureHandler mNavBarGestureHandler;
- private VideoView mFeedbackVideoView;
- private int mFeedbackVideoDuration;
+ private ImageView mFeedbackVideoView;
+
+ @Nullable private AnimatedVectorDrawable mTutorialAnimation = null;
+ private boolean mIntroductionShown = false;
public static TutorialFragment newInstance(TutorialType tutorialType) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
@@ -92,6 +96,11 @@
return null;
}
+ @Nullable
+ AnimatedVectorDrawable getTutorialAnimation() {
+ return mTutorialAnimation;
+ }
+
abstract TutorialController createController(TutorialType type);
abstract Class<? extends TutorialController> getControllerClass();
@@ -130,12 +139,6 @@
}
@Override
- public void onStart() {
- super.onStart();
- initializeFeedbackVideoView();
- }
-
- @Override
public void onStop() {
super.onStop();
releaseFeedbackVideoView();
@@ -143,20 +146,18 @@
void initializeFeedbackVideoView() {
if (!updateFeedbackVideo()) {
- mFeedbackVideoView.setVisibility(View.INVISIBLE);
return;
- } else {
- mFeedbackVideoView.setVisibility(View.VISIBLE);
}
- int heightPixels = getResources().getDisplayMetrics().heightPixels;
- int heightPixelsWithMargin = heightPixels + Utilities.dpToPx(80);
- int widthPixels = getResources().getDisplayMetrics().widthPixels - Utilities.dpToPx(12);
- mFeedbackVideoView.setScaleY((float) heightPixelsWithMargin / heightPixels);
- mFeedbackVideoView.setScaleX((float) heightPixelsWithMargin / widthPixels);
- mFeedbackVideoView.start();
- mFeedbackVideoView.setOnPreparedListener(
- mp -> mFeedbackVideoDuration = mFeedbackVideoView.getDuration());
- mFeedbackVideoView.setOnCompletionListener(mp -> releaseFeedbackVideoView());
+
+ if (!mIntroductionShown && mTutorialController != null) {
+ Integer introTileStringResId = mTutorialController.getIntroductionTitle();
+ Integer introSubtitleResId = mTutorialController.getIntroductionSubtitle();
+ if (introTileStringResId != null && introSubtitleResId != null) {
+ mTutorialController.showFeedback(introTileStringResId,
+ introSubtitleResId, null, false);
+ mIntroductionShown = true;
+ }
+ }
}
boolean updateFeedbackVideo() {
@@ -164,19 +165,37 @@
if (feedbackVideoResId == null || getContext() == null) {
return false;
}
- Uri uri = Uri.parse("android.resource://" + getContext().getPackageName() + "/"
- + feedbackVideoResId);
- mFeedbackVideoView.setVideoURI(uri);
+ mTutorialAnimation = (AnimatedVectorDrawable) getContext().getDrawable(feedbackVideoResId);
+
+ if (mTutorialAnimation != null) {
+ mTutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+
+ @Override
+ public void onAnimationStart(Drawable drawable) {
+ super.onAnimationStart(drawable);
+
+ mFeedbackVideoView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Drawable drawable) {
+ super.onAnimationEnd(drawable);
+
+ releaseFeedbackVideoView();
+ }
+ });
+ }
+ mFeedbackVideoView.setImageDrawable(mTutorialAnimation);
+
return true;
}
void releaseFeedbackVideoView() {
- mFeedbackVideoView.stopPlayback();
- mFeedbackVideoView.setVisibility(View.INVISIBLE);
- }
+ if (mTutorialAnimation != null && mTutorialAnimation.isRunning()) {
+ mTutorialAnimation.stop();
+ }
- int getFeedbackVideoDuration() {
- return mFeedbackVideoDuration;
+ mFeedbackVideoView.setVisibility(View.GONE);
}
@Override
@@ -217,6 +236,7 @@
mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);
mNavBarGestureHandler.registerNavBarGestureAttemptCallback(mTutorialController);
mTutorialType = tutorialType;
+ initializeFeedbackVideoView();
}
@Override
@@ -230,11 +250,7 @@
}
void continueTutorial() {
- if (!(getContext() instanceof GestureSandboxActivity)) {
- closeTutorial();
- return;
- }
- GestureSandboxActivity gestureSandboxActivity = (GestureSandboxActivity) getContext();
+ GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
if (gestureSandboxActivity == null) {
closeTutorial();
@@ -255,12 +271,22 @@
startActivity(new Intent("com.android.settings.GESTURE_NAVIGATION_SETTINGS"));
}
- boolean isTutorialComplete() {
- if (!(getContext() instanceof GestureSandboxActivity)) {
- return true;
- }
- GestureSandboxActivity gestureSandboxActivity = (GestureSandboxActivity) getContext();
+ int getCurrentStep() {
+ GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
- return gestureSandboxActivity == null || gestureSandboxActivity.isTutorialComplete();
+ return gestureSandboxActivity == null ? -1 : gestureSandboxActivity.getCurrentStep();
+ }
+
+ int getNumSteps() {
+ GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
+
+ return gestureSandboxActivity == null ? -1 : gestureSandboxActivity.getNumSteps();
+ }
+
+ @Nullable
+ private GestureSandboxActivity getGestureSandboxActivity() {
+ Context context = getContext();
+
+ return context instanceof GestureSandboxActivity ? (GestureSandboxActivity) context : null;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/AppCloseConfig.java b/quickstep/src/com/android/quickstep/util/AppCloseConfig.java
new file mode 100644
index 0000000..bec3379
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/AppCloseConfig.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+
+/*
+ * Adds getter methods to {@link MultiValueUpdateListener} specific to app close animation,
+ * so that the entire animation can be defined in one place.
+ */
+public abstract class AppCloseConfig extends MultiValueUpdateListener {
+
+ /**
+ * Returns the translation y of the workspace contents.
+ */
+ public abstract float getWorkspaceTransY();
+
+ /*
+ * Returns the scale of the workspace contents.
+ */
+ public abstract float getWorkspaceScale();
+
+ /*
+ * Returns the alpha of the window.
+ */
+ public abstract @FloatRange(from = 0, to = 1) float getWindowAlpha();
+
+ /*
+ * Returns the alpha of the foreground layer of an adaptive icon.
+ */
+ public abstract @IntRange(from = 0, to = 255) int getFgAlpha();
+
+ /*
+ * Returns the corner radius of the window and icon.
+ */
+ public abstract float getCornerRadius();
+
+ /*
+ * Returns the interpolated progress of the animation.
+ */
+ public abstract float getInterpolatedProgress();
+
+}
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index e5d2c53..02ec68a 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -20,6 +20,7 @@
import android.graphics.PointF;
import android.graphics.RectF;
+import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;
@@ -241,7 +242,7 @@
mCurrentCenterX + currentWidth / 2, mCurrentY + currentHeight);
}
for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
- onUpdateListener.onUpdate(mCurrentRect, mCurrentScaleProgress);
+ onUpdateListener.onUpdate(null, mCurrentRect, mCurrentScaleProgress);
}
}
}
@@ -266,7 +267,7 @@
}
public interface OnUpdateListener {
- void onUpdate(RectF currentRect, float progress);
+ void onUpdate(@Nullable AppCloseConfig values, RectF currentRect, float progress);
default void onCancel() { }
}
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
new file mode 100644
index 0000000..95d56aa
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static com.android.launcher3.Utilities.dpToPx;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.PathParser;
+import android.util.Property;
+import android.view.animation.Interpolator;
+
+import androidx.core.view.animation.PathInterpolatorCompat;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.DynamicResource;
+import com.android.systemui.plugins.ResourceProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Applies spring forces to animate from a starting rect to a target rect,
+ * while providing update callbacks to the caller.
+ */
+public class RectFSpringAnim2 extends RectFSpringAnim {
+
+ private static final FloatPropertyCompat<RectFSpringAnim2> RECT_CENTER_X =
+ new FloatPropertyCompat<RectFSpringAnim2>("rectCenterXSpring") {
+ @Override
+ public float getValue(RectFSpringAnim2 anim) {
+ return anim.mCurrentCenterX;
+ }
+
+ @Override
+ public void setValue(RectFSpringAnim2 anim, float currentCenterX) {
+ anim.mCurrentCenterX = currentCenterX;
+ anim.onUpdate();
+ }
+ };
+
+ private static final FloatPropertyCompat<RectFSpringAnim2> RECT_Y =
+ new FloatPropertyCompat<RectFSpringAnim2>("rectYSpring") {
+ @Override
+ public float getValue(RectFSpringAnim2 anim) {
+ return anim.mCurrentY;
+ }
+
+ @Override
+ public void setValue(RectFSpringAnim2 anim, float y) {
+ anim.mCurrentY = y;
+ anim.onUpdate();
+ }
+ };
+
+ private static final Property<RectFSpringAnim2, Float> PROGRESS =
+ new Property<RectFSpringAnim2, Float>(Float.class, "rectFProgress") {
+ @Override
+ public Float get(RectFSpringAnim2 rectFSpringAnim) {
+ return rectFSpringAnim.mProgress;
+ }
+
+ @Override
+ public void set(RectFSpringAnim2 rectFSpringAnim, Float progress) {
+ rectFSpringAnim.mProgress = progress;
+ rectFSpringAnim.onUpdate();
+ }
+ };
+
+ private final RectF mStartRect;
+ private final RectF mTargetRect;
+ private final RectF mCurrentRect = new RectF();
+ private final List<OnUpdateListener> mOnUpdateListeners = new ArrayList<>();
+ private final List<Animator.AnimatorListener> mAnimatorListeners = new ArrayList<>();
+
+ private float mCurrentCenterX;
+ private float mCurrentY;
+
+ private float mTargetX;
+ private float mTargetY;
+
+ // If true, tracking the bottom of the rects, else tracking the top.
+ private final boolean mTrackingBottomY;
+ private float mProgress;
+ private SpringAnimation mRectXAnim;
+ private SpringAnimation mRectYAnim;
+ private ValueAnimator mRectScaleAnim;
+ private boolean mAnimsStarted;
+ private boolean mRectXAnimEnded;
+ private boolean mRectYAnimEnded;
+ private boolean mRectScaleAnimEnded;
+
+ private final float mXDamping;
+ private final float mXStiffness;
+
+ private final float mYDamping;
+ private float mYStiffness;
+
+ private long mDuration;
+
+ private final Interpolator mCloseInterpolator;
+
+ private AppCloseConfig mValues;
+ final float mStartRadius;
+ final float mEndRadius;
+
+ final float mHomeTransYEnd;
+ final float mScaleStart;
+
+ public RectFSpringAnim2(RectF startRect, RectF targetRect, Context context, float startRadius,
+ float endRadius) {
+ super(startRect, targetRect, context);
+ mStartRect = startRect;
+ mTargetRect = targetRect;
+
+ mTrackingBottomY = startRect.bottom < targetRect.bottom;
+ mCurrentY = mTrackingBottomY ? mStartRect.bottom : mStartRect.top;
+ mCurrentCenterX = mStartRect.centerX();
+
+ mTargetY = mTrackingBottomY ? mTargetRect.bottom : mTargetRect.top;
+ mTargetX = mTargetRect.centerX();
+
+ ResourceProvider rp = DynamicResource.provider(context);
+ mXDamping = rp.getFloat(R.dimen.swipe_up_rect_2_x_damping_ratio);
+ mXStiffness = rp.getFloat(R.dimen.swipe_up_rect_2_x_stiffness);
+
+ mYDamping = rp.getFloat(R.dimen.swipe_up_rect_2_y_damping_ratio);
+ mYStiffness = rp.getFloat(R.dimen.swipe_up_rect_2_y_stiffness);
+ mDuration = Math.round(rp.getFloat(R.dimen.swipe_up_duration));
+
+ mHomeTransYEnd = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+ mScaleStart = rp.getFloat(R.dimen.swipe_up_scale_start);
+
+
+ if (!mTrackingBottomY) {
+ mYStiffness *= rp.getFloat(R.dimen.swipe_up_rect_2_y_stiffness_low_swipe_multiplier);
+ mDuration *= rp.getFloat(R.dimen.swipe_up_low_swipe_duration_multiplier);
+ }
+
+ mCloseInterpolator = getAppCloseInterpolator(context);
+
+ // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
+ // rounding at the end of the animation.
+ mStartRadius = startRadius;
+ mEndRadius = endRadius;
+
+ setCanRelease(true);
+ }
+
+ public void onTargetPositionChanged() {
+ if (mRectXAnim != null && mTargetX != mTargetRect.centerX()) {
+ mTargetX = mTargetRect.centerX();
+ mRectXAnim.animateToFinalPosition(mTargetX);
+ }
+
+ if (mRectYAnim != null) {
+ if (mTrackingBottomY && mTargetY != mTargetRect.bottom) {
+ mTargetY = mTargetRect.bottom;
+ mRectYAnim.animateToFinalPosition(mTargetY);
+ } else if (!mTrackingBottomY && mTargetY != mTargetRect.top) {
+ mTargetY = mTargetRect.top;
+ mRectYAnim.animateToFinalPosition(mTargetY);
+ }
+ }
+ }
+
+ public void addOnUpdateListener(OnUpdateListener onUpdateListener) {
+ mOnUpdateListeners.add(onUpdateListener);
+ }
+
+ public void addAnimatorListener(Animator.AnimatorListener animatorListener) {
+ mAnimatorListeners.add(animatorListener);
+ }
+
+ /**
+ * Starts the fling/spring animation.
+ * @param context The activity context.
+ * @param velocityPxPerMs Velocity of swipe in px/ms.
+ */
+ public void start(Context context, PointF velocityPxPerMs) {
+ DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context);
+
+ mRectXAnim = new SpringAnimation(this, RECT_CENTER_X)
+ .setStartValue(mCurrentCenterX)
+ .setMinValue(Math.min(0, mCurrentCenterX))
+ .setMaxValue(Math.max(dp.widthPx, mCurrentCenterX))
+ .setStartVelocity(velocityPxPerMs.x * 1000)
+ .setSpring(new SpringForce(mTargetX)
+ .setStiffness(mXStiffness)
+ .setDampingRatio(mXDamping));
+ mRectXAnim.addEndListener(((animation, canceled, centerX, velocityX) -> {
+ mRectXAnimEnded = true;
+ maybeOnEnd();
+ }));
+
+ mRectYAnim = new SpringAnimation(this, RECT_Y)
+ .setStartValue(mCurrentY)
+ .setMinValue(Math.min(0, mCurrentY))
+ .setMaxValue(Math.max(dp.heightPx, mCurrentY))
+ .setStartVelocity(velocityPxPerMs.y * 1000)
+ .setSpring(new SpringForce(mTargetY)
+ .setStiffness(mYStiffness)
+ .setDampingRatio(mYDamping));
+ mRectYAnim.addEndListener(((animation, canceled, centerY, velocityY) -> {
+ mRectYAnimEnded = true;
+ maybeOnEnd();
+ }));
+
+ mRectScaleAnim = ObjectAnimator.ofFloat(this, PROGRESS, 0, 1f)
+ .setDuration(mDuration);
+ mRectScaleAnim.setInterpolator(mCloseInterpolator);
+ mRectScaleAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRectScaleAnimEnded = true;
+ maybeOnEnd();
+ }
+ });
+
+ mValues = buildConfig();
+ mRectScaleAnim.addUpdateListener(mValues);
+
+ setCanRelease(false);
+ mAnimsStarted = true;
+
+ mRectXAnim.start();
+ mRectYAnim.start();
+ mRectScaleAnim.start();
+ for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
+ animatorListener.onAnimationStart(null);
+ }
+ }
+
+ private AppCloseConfig buildConfig() {
+ return new AppCloseConfig() {
+ FloatProp mHomeTransY = new FloatProp(0, mHomeTransYEnd, 0, mDuration, LINEAR);
+ FloatProp mHomeScale = new FloatProp(mScaleStart, 1f, 0, mDuration, LINEAR);
+ FloatProp mWindowFadeOut = new FloatProp(1f, 0f, 0, 116, LINEAR);
+ // There should be a slight overlap b/w window fading out and fg fading in.
+ // (fg startDelay < window fade out duration)
+ FloatProp mFgFadeIn = new FloatProp(0, 255f, 100, mDuration - 100, LINEAR);
+ FloatProp mRadius = new FloatProp(mStartRadius, mEndRadius, 0, mDuration, LINEAR);
+ FloatProp mThreePointInterpolation = new FloatProp(0, 1, 0, mDuration, LINEAR);
+
+ @Override
+ public float getWorkspaceTransY() {
+ return mHomeTransY.value;
+ }
+
+ @Override
+ public float getWorkspaceScale() {
+ return mHomeScale.value;
+ }
+
+ @Override
+ public float getWindowAlpha() {
+ return mWindowFadeOut.value;
+ }
+
+ @Override
+ public int getFgAlpha() {
+ return (int) mFgFadeIn.value;
+ }
+
+ @Override
+ public float getCornerRadius() {
+ return mRadius.value;
+ }
+
+ @Override
+ public float getInterpolatedProgress() {
+ return mThreePointInterpolation.value;
+ }
+
+ @Override
+ public void onUpdate(float percent) {}
+ };
+ }
+
+ public void end() {
+ if (mAnimsStarted) {
+ if (mRectXAnim.canSkipToEnd()) {
+ mRectXAnim.skipToEnd();
+ }
+ if (mRectYAnim.canSkipToEnd()) {
+ mRectYAnim.skipToEnd();
+ }
+ mRectScaleAnim.end();
+ }
+ mRectXAnimEnded = true;
+ mRectYAnimEnded = true;
+ mRectScaleAnimEnded = true;
+ maybeOnEnd();
+ }
+
+ private boolean isEnded() {
+ return mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded;
+ }
+
+ private void onUpdate() {
+ if (isEnded()) {
+ // Prevent further updates from being called. This can happen between callbacks for
+ // ending the x/y/scale animations.
+ return;
+ }
+
+ if (!mOnUpdateListeners.isEmpty()) {
+ float rectProgress = mProgress;
+ float currentWidth = Utilities.mapRange(rectProgress, mStartRect.width(),
+ mTargetRect.width());
+ float currentHeight = Utilities.mapRange(rectProgress, mStartRect.height(),
+ mTargetRect.height());
+ if (mTrackingBottomY) {
+ mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY - currentHeight,
+ mCurrentCenterX + currentWidth / 2, mCurrentY);
+ } else {
+ mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY,
+ mCurrentCenterX + currentWidth / 2, mCurrentY + currentHeight);
+ }
+
+ float currentPlayTime = mRectScaleAnimEnded ? mRectScaleAnim.getDuration()
+ : mRectScaleAnim.getCurrentPlayTime();
+ float linearProgress = Math.min(1f, currentPlayTime / mRectScaleAnim.getDuration());
+ for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
+ onUpdateListener.onUpdate(mValues, mCurrentRect, linearProgress);
+ }
+ }
+ }
+
+ private void maybeOnEnd() {
+ if (mAnimsStarted && isEnded()) {
+ mAnimsStarted = false;
+ setCanRelease(true);
+ for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
+ animatorListener.onAnimationEnd(null);
+ }
+ }
+ }
+
+ public void cancel() {
+ if (mAnimsStarted) {
+ for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
+ onUpdateListener.onCancel();
+ }
+ }
+ end();
+ }
+
+ private Interpolator getAppCloseInterpolator(Context context) {
+ ResourceProvider rp = DynamicResource.provider(context);
+ String path = String.format("M 0,0 C %f, %f, %f, %f, %f, %f C %f, %f, %f, %f, 1, 1",
+ rp.getFloat(R.dimen.c1_a),
+ rp.getFloat(R.dimen.c1_b),
+ rp.getFloat(R.dimen.c1_c),
+ rp.getFloat(R.dimen.c1_d),
+ rp.getFloat(R.dimen.mp_x),
+ rp.getFloat(R.dimen.mp_y),
+ rp.getFloat(R.dimen.c2_a),
+ rp.getFloat(R.dimen.c2_b),
+ rp.getFloat(R.dimen.c2_c),
+ rp.getFloat(R.dimen.c2_d));
+ return PathInterpolatorCompat.create(PathParser.createPathFromPathData(path));
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
index 176478f..88cc650 100644
--- a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
@@ -77,7 +77,7 @@
WindowBounds bounds = new WindowBounds(wm.getBounds(),
new Rect(insets.left, insets.top, insets.right, insets.bottom));
- int rotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
+ int rotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
int halfDividerSize = context.getResources()
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 9576eac..01d51f8 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -16,15 +16,20 @@
package com.android.quickstep.util;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import android.animation.AnimatorSet;
import android.app.ActivityOptions;
+import android.content.res.Resources;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.util.Pair;
+import android.view.Gravity;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
@@ -32,7 +37,10 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.R;
import com.android.launcher3.WrappedAnimationRunnerImpl;
import com.android.launcher3.WrappedLauncherAnimationRunner;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
@@ -114,6 +122,26 @@
resetState();
}
+ /**
+ * @return {@link InsettableFrameLayout.LayoutParams} to correctly position the
+ * split placeholder view
+ */
+ public InsettableFrameLayout.LayoutParams getLayoutParamsForActivePosition(Resources resources,
+ DeviceProfile deviceProfile) {
+ InsettableFrameLayout.LayoutParams params =
+ new InsettableFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ boolean topLeftPosition = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+ if (deviceProfile.isLandscape) {
+ params.width = (int) resources.getDimension(R.dimen.split_placeholder_size);
+ params.gravity = topLeftPosition ? Gravity.START : Gravity.END;
+ } else {
+ params.height = (int) resources.getDimension(R.dimen.split_placeholder_size);
+ params.gravity = Gravity.TOP;
+ }
+
+ return params;
+ }
+
@Nullable
public SplitPositionOption getActiveSplitPositionOption() {
return mInitialPosition;
@@ -133,8 +161,8 @@
}
@Override
- public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t,
- Runnable finishCallback) {
+ public void startAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction t, Runnable finishCallback) {
TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskView, mTaskView,
info, t, finishCallback);
// After successful launch, call resetState
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 1df459e..de6c4f5 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
@@ -220,6 +221,9 @@
* @param totalRows Total number of rows.
*/
private void addStaggeredAnimationForView(View v, int row, int totalRows) {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ return;
+ }
// Invert the rows, because we stagger starting from the bottom of the screen.
int invertedRow = totalRows - row;
// Add 1 to the inverted row so that the bottom most row has a start delay.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a6c934b..790c655 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -42,6 +42,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
+import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
@@ -88,11 +89,13 @@
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ListView;
+import android.widget.OverScroller;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -116,14 +119,15 @@
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.TranslateEdgeEffect;
import com.android.launcher3.util.ViewPool;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
@@ -141,6 +145,7 @@
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitScreenBounds;
+import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
@@ -157,6 +162,7 @@
import com.android.wm.shell.pip.IPipAnimationListener;
import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
/**
@@ -296,6 +302,9 @@
}
};
+ // OverScroll constants
+ private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
+
protected final RecentsOrientedState mOrientationState;
protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy;
protected RecentsAnimationController mRecentsAnimationController;
@@ -314,6 +323,8 @@
protected final Rect mTempRect = new Rect();
protected final RectF mTempRectF = new RectF();
private final PointF mTempPointF = new PointF();
+ private final float[] mTempFloat = new float[1];
+ private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>();
private float mFullscreenScale;
private static final int DISMISS_TASK_DURATION = 300;
@@ -360,6 +371,9 @@
IntSet mTopIdSet = new IntSet();
+ private int mOverScrollShift = 0;
+
+
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
*/
@@ -584,6 +598,72 @@
}
@Override
+ protected void initEdgeEffect() {
+ mEdgeGlowLeft = new TranslateEdgeEffect(getContext());
+ mEdgeGlowRight = new TranslateEdgeEffect(getContext());
+ }
+
+ @Override
+ protected void drawEdgeEffect(Canvas canvas) {
+ // Do not draw edge effect
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ // Draw overscroll
+ if (mAllowOverScroll && (!mEdgeGlowRight.isFinished() || !mEdgeGlowLeft.isFinished())) {
+ final int restoreCount = canvas.save();
+ final int width = getWidth();
+ final int height = getHeight();
+ int primarySize = mOrientationHandler.getPrimaryValue(width, height);
+ int secondarySize = mOrientationHandler.getSecondaryValue(width, height);
+
+ float effectiveShift = 0;
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.setSize(secondarySize, primarySize);
+ if (((TranslateEdgeEffect) mEdgeGlowLeft).getTranslationShift(mTempFloat)) {
+ effectiveShift = mTempFloat[0];
+ postInvalidateOnAnimation();
+ }
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.setSize(secondarySize, primarySize);
+ if (((TranslateEdgeEffect) mEdgeGlowRight).getTranslationShift(mTempFloat)) {
+ effectiveShift -= mTempFloat[0];
+ postInvalidateOnAnimation();
+ }
+ }
+
+ int scroll = OverScroll.dampedScroll(effectiveShift * primarySize, primarySize);
+ mOrientationHandler.set(canvas, CANVAS_TRANSLATE, scroll);
+
+ if (mOverScrollShift != scroll) {
+ mOverScrollShift = scroll;
+ dispatchScrollChanged();
+ }
+
+ super.dispatchDraw(canvas);
+ canvas.restoreToCount(restoreCount);
+ } else {
+ if (mOverScrollShift != 0) {
+ mOverScrollShift = 0;
+ dispatchScrollChanged();
+ }
+ super.dispatchDraw(canvas);
+ }
+ if (LIVE_TILE.get() && mEnableDrawingLiveTile && mLiveTileParams.getTargetSet() != null) {
+ redrawLiveTile();
+ }
+ }
+
+ /**
+ * Returns the view shift due to overscroll
+ */
+ public int getOverScrollShift() {
+ return mOverScrollShift;
+ }
+
+ @Override
public Task onTaskThumbnailChanged(int taskId, ThumbnailData thumbnailData) {
if (mHandleTaskStackChanges) {
TaskView taskView = getTaskView(taskId);
@@ -936,8 +1016,30 @@
}
@Override
- protected boolean snapToPageInFreeScroll() {
- return !showAsGrid();
+ protected void onNotSnappingToPageInFreeScroll() {
+ int finalPos = mScroller.getFinalX();
+ if (!showAsGrid() && finalPos > mMinScroll && finalPos < mMaxScroll) {
+ int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
+ int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
+
+ // If scrolling ends in the half of the added space that is closer to
+ // the end, settle to the end. Otherwise snap to the nearest page.
+ // If flinging past one of the ends, don't change the velocity as it
+ // will get stopped at the end anyway.
+ int pageSnapped = finalPos < (firstPageScroll + mMinScroll) / 2
+ ? mMinScroll
+ : finalPos > (lastPageScroll + mMaxScroll) / 2
+ ? mMaxScroll
+ : getScrollForPage(mNextPage);
+
+ mScroller.setFinalX(pageSnapped);
+ // Ensure the scroll/snap doesn't happen too fast;
+ int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
+ - mScroller.getDuration();
+ if (extraScrollDuration > 0) {
+ mScroller.extendDuration(extraScrollDuration);
+ }
+ }
}
@Override
@@ -1267,12 +1369,6 @@
// Update the high res thumbnail loader state
mModel.getThumbnailCache().getHighResLoadingState().setFlingingFast(isFlingingFast);
-
- mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
- if (LIVE_TILE.get() && mEnableDrawingLiveTile
- && mLiveTileParams.getTargetSet() != null) {
- redrawLiveTile();
- }
return scrolling;
}
@@ -1569,7 +1665,6 @@
updateOrientationHandler();
}
- setOnScrollChangeListener(null);
setEnableFreeScroll(true);
setEnableDrawingLiveTile(true);
if (!LIVE_TILE.get()) {
@@ -2659,9 +2754,14 @@
public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
mSplitHiddenTaskView = taskView;
- mSplitPlaceholderView.getSplitController().setInitialTaskSelect(taskView,
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
+ splitController.setInitialTaskSelect(taskView,
splitPositionOption);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
+ mSplitPlaceholderView.setLayoutParams(
+ splitController.getLayoutParamsForActivePosition(getResources(),
+ mActivity.getDeviceProfile()));
+ mSplitPlaceholderView.setIcon(taskView.getIconView());
}
public PendingAnimation createSplitSelectInitAnimation() {
@@ -3203,13 +3303,6 @@
return mClearAllButton;
}
- @Override
- protected boolean onOverscroll(int amount) {
- // overscroll should only be accepted on -1 direction (for clear all button)
- if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false;
- return super.onOverscroll(amount);
- }
-
/**
* @return How many pixels the running task is offset on the currently laid out dominant axis.
*/
@@ -3224,14 +3317,8 @@
if (pageIndex == -1) {
return 0;
}
- // Unbound the scroll (due to overscroll) if the adjacent tasks are offset away from it.
- // This allows the page to move freely, given there's no visual indication why it shouldn't.
- int boundedScroll = mOrientationHandler.getPrimaryScroll(this);
- int unboundedScroll = getUnboundedScroll();
- float unboundedProgress = mAdjacentPageOffset;
- int scroll = Math.round(unboundedScroll * unboundedProgress
- + boundedScroll * (1 - unboundedProgress));
- return getScrollForPage(pageIndex) - scroll;
+ return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this)
+ + getOverScrollShift();
}
/**
@@ -3417,6 +3504,33 @@
void onEmptyMessageUpdated(boolean isEmpty);
}
+ /**
+ * Adds a listener for scroll changes
+ */
+ public void addOnScrollChangedListener(OnScrollChangedListener listener) {
+ mScrollListeners.add(listener);
+ }
+
+ /**
+ * Removes a previously added scroll change listener
+ */
+ public void removeOnScrollChangedListener(OnScrollChangedListener listener) {
+ mScrollListeners.remove(listener);
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ dispatchScrollChanged();
+ }
+
+ private void dispatchScrollChanged() {
+ mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
+ for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
+ mScrollListeners.get(i).onScrollChanged();
+ }
+ }
+
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
IPipAnimationListener.Stub {
private T mActivity;
diff --git a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
index fb9be81..bb8bc11 100644
--- a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
@@ -19,11 +19,12 @@
import android.content.Context;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.view.View;
+import android.view.Gravity;
+import android.widget.FrameLayout;
import com.android.quickstep.util.SplitSelectStateController;
-public class SplitPlaceholderView extends View {
+public class SplitPlaceholderView extends FrameLayout {
public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT =
new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") {
@@ -40,6 +41,7 @@
};
private SplitSelectStateController mSplitController;
+ private IconView mIcon;
public SplitPlaceholderView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -52,4 +54,15 @@
public SplitSelectStateController getSplitController() {
return mSplitController;
}
+
+ public void setIcon(IconView icon) {
+ if (mIcon == null) {
+ mIcon = new IconView(getContext());
+ addView(mIcon);
+ }
+ mIcon.setDrawable(icon.getDrawable());
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(icon.getLayoutParams());
+ params.gravity = Gravity.CENTER;
+ mIcon.setLayoutParams(params);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 658d71d..f55cdac 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -121,7 +121,7 @@
};
}
- private void setPosition(float x, float y) {
+ private void setPosition(float x, float y, int overscrollShift) {
PagedOrientationHandler pagedOrientationHandler = mTaskView.getPagedOrientationHandler();
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
float adjustedY = y + taskTopMargin;
@@ -136,8 +136,9 @@
setPivotY(0);
}
setRotation(pagedOrientationHandler.getDegreesRotated());
- setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail()));
- setY(pagedOrientationHandler.getTaskMenuY(adjustedY, mTaskView.getThumbnail()));
+ setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail(), overscrollShift));
+ setY(pagedOrientationHandler.getTaskMenuY(
+ adjustedY, mTaskView.getThumbnail(), overscrollShift));
}
public void onRotationChanged() {
@@ -169,14 +170,15 @@
return false;
}
post(this::animateOpen);
- mActivity.getRootView().getViewTreeObserver().addOnScrollChangedListener(this);
+ ((RecentsView) mActivity.getOverviewPanel()).addOnScrollChangedListener(this);
return true;
}
@Override
public void onScrollChanged() {
RecentsView rv = mTaskView.getRecentsView();
- setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY());
+ setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY(),
+ rv.getOverScrollShift());
}
/** @return true if successfully able to populate task view menu, false otherwise */
@@ -236,7 +238,7 @@
.mOrientationState.isRecentsActivityRotationAllowed();
mOptionLayout.setOrientation(orientationHandler
.getTaskMenuLayoutOrientation(canActivityRotate, mOptionLayout));
- setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top);
+ setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0);
}
private void animateOpen() {
@@ -282,7 +284,7 @@
private void closeComplete() {
mIsOpen = false;
mActivity.getDragLayer().removeView(this);
- mActivity.getRootView().getViewTreeObserver().removeOnScrollChangedListener(this);
+ ((RecentsView) mActivity.getOverviewPanel()).removeOnScrollChangedListener(this);
}
private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 2bb14d2..35acdd1 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -523,7 +523,7 @@
if (mTask != null) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
- ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this);
+ ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this, null);
if (ActivityManagerWrapper.getInstance()
.startActivityFromRecents(mTask.key, opts.options)) {
return opts.onEndCallback;
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 2c096b4..7d48adf 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -38,8 +38,8 @@
<color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
<color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
<color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
- <color name="gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
- <color name="gesture_tutorial_primary_color">#1A73E8</color> <!-- Blue -->
+ <color name="gesture_tutorial_action_button_label_color">#FF000000</color>
+ <color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
<color name="popup_color_primary_light">#FFF</color>
<color name="popup_color_secondary_light">#F1F3F4</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index db98811..b75af7f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -134,8 +134,45 @@
<item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
<item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
+
+ <item name="swipe_up_scale_start" type="dimen" format="float">0.98</item>
+ <item name="swipe_up_duration" type="dimen" format="float">500</item>
+
+ <item name="swipe_up_trans_y_dp" type="dimen" format="float">3</item>
+ <item name="swipe_up_trans_y_dp_per_s" type="dimen" format="float">3</item>
+
+ <item name="swipe_up_trans_y_damping" type="dimen" format="float">0.4</item>
+ <item name="swipe_up_trans_y_stiffness" type="dimen" format="float">200</item>
+
<item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
- <item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
+ <item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">100</item>
+
+
+ <item name="swipe_up_rect_2_x_damping_ratio" type="dimen" format="float">1</item>
+ <item name="swipe_up_rect_2_x_stiffness" type="dimen" format="float">350</item>
+
+ <item name="swipe_up_rect_2_y_damping_ratio" type="dimen" format="float">1</item>
+ <item name="swipe_up_rect_2_y_stiffness" type="dimen" format="float">700</item>
+
+ <item name="swipe_up_rect_2_y_stiffness_low_swipe_multiplier" type="dimen" format="float">1</item>
+ <item name="swipe_up_low_swipe_duration_multiplier" type="dimen" format="float">1</item>
+
+ <item name="swipe_up_launcher_alpha_max_progress" type="dimen" format="float">0.85</item>
+
+
+ <item name="c1_a" type="dimen" format="float">0.05</item>
+ <item name="c1_b" type="dimen" format="float">0</item>
+ <item name="c1_c" type="dimen" format="float">0.133333</item>
+ <item name="c1_d" type="dimen" format="float">0.06</item>
+
+ <item name="mp_x" type="dimen" format="float">0.166666</item>
+ <item name="mp_y" type="dimen" format="float">.4</item>
+
+ <item name="c2_a" type="dimen" format="float">0.208333</item>
+ <item name="c2_b" type="dimen" format="float">.82</item>
+ <item name="c2_c" type="dimen" format="float">.25</item>
+ <item name="c2_d" type="dimen" format="float">1</item>
+
<item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
<item name="staggered_stiffness" type="dimen" format="float">150</item>
@@ -151,35 +188,32 @@
<dimen name="swipe_up_max_workspace_trans_y">-60dp</dimen>
<array name="dynamic_resources">
- <item>@dimen/all_apps_spring_damping_ratio</item>
- <item>@dimen/all_apps_spring_stiffness</item>
+ <item>@dimen/swipe_up_duration</item>
+ <item>@dimen/swipe_up_scale_start</item>
+ <item>@dimen/swipe_up_trans_y_dp</item>
+ <item>@dimen/swipe_up_trans_y_dp_per_s</item>
+ <item>@dimen/swipe_up_trans_y_damping</item>
+ <item>@dimen/swipe_up_trans_y_stiffness</item>
+ <item>@dimen/swipe_up_rect_2_x_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_2_x_stiffness</item>
+ <item>@dimen/swipe_up_rect_2_y_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_2_y_stiffness</item>
+ <item>@dimen/swipe_up_launcher_alpha_max_progress</item>
+ <item>@dimen/swipe_up_rect_2_y_stiffness_low_swipe_multiplier</item>
+ <item>@dimen/swipe_up_low_swipe_duration_multiplier</item>
- <item>@dimen/dismiss_task_trans_y_damping_ratio</item>
- <item>@dimen/dismiss_task_trans_y_stiffness</item>
+ <item>@dimen/c1_a</item>
+ <item>@dimen/c1_b</item>
+ <item>@dimen/c1_c</item>
+ <item>@dimen/c1_d</item>
- <item>@dimen/dismiss_task_trans_x_damping_ratio</item>
- <item>@dimen/dismiss_task_trans_x_stiffness</item>
+ <item>@dimen/mp_x</item>
+ <item>@dimen/mp_y</item>
- <item>@dimen/horizontal_spring_damping_ratio</item>
- <item>@dimen/horizontal_spring_stiffness</item>
-
- <item>@dimen/swipe_up_rect_scale_damping_ratio</item>
- <item>@dimen/swipe_up_rect_scale_stiffness</item>
-
- <item>@dimen/swipe_up_rect_xy_fling_friction</item>
- <item>@dimen/swipe_up_rect_xy_damping_ratio</item>
- <item>@dimen/swipe_up_rect_xy_stiffness</item>
-
- <item>@dimen/staggered_damping_ratio</item>
- <item>@dimen/staggered_stiffness</item>
- <item>@dimen/unlock_staggered_velocity_dp_per_s</item>
-
- <item>@dimen/swipe_up_fling_min_visible_change</item>
- <item>@dimen/swipe_up_y_overshoot</item>
-
- <item>@dimen/hint_scale_damping_ratio</item>
- <item>@dimen/hint_scale_stiffness</item>
- <item>@dimen/hint_scale_velocity_dp_per_s</item>
+ <item>@dimen/c2_a</item>
+ <item>@dimen/c2_b</item>
+ <item>@dimen/c2_c</item>
+ <item>@dimen/c2_d</item>
</array>
<string-array name="live_wallpapers_remove_sysui_scrims">
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 5ba03ed..cc9f594 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -17,7 +17,7 @@
package com.android.launcher3;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ROTATION;
+import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
@@ -28,7 +28,6 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.os.Binder;
import android.os.Bundle;
import android.os.Process;
import android.os.StrictMode;
@@ -92,7 +91,7 @@
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
- DisplayController.getDefaultDisplay(this).addChangeListener(this);
+ DisplayController.INSTANCE.get(this).addChangeListener(this);
// Update theme
WallpaperColorInfo.INSTANCE.get(this).addOnChangeListener(this);
@@ -166,7 +165,7 @@
}
@NonNull
- public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
+ public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
int left = 0, top = 0;
int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
if (v instanceof BubbleTextView) {
@@ -193,7 +192,7 @@
return false;
}
- Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v).toBundle() : null;
+ Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
UserHandle user = item == null ? null : item.user;
// Prepare intent
@@ -279,7 +278,7 @@
protected void onDestroy() {
super.onDestroy();
WallpaperColorInfo.INSTANCE.get(this).removeOnChangeListener(this);
- DisplayController.getDefaultDisplay(this).removeChangeListener(this);
+ DisplayController.INSTANCE.get(this).removeChangeListener(this);
}
public void runOnceOnStart(Runnable action) {
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 7926862..a26217c 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -240,6 +240,7 @@
final Rect to = getIconRect(d);
final float scale = (float) to.width() / from.width();
+ d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
mDropTargetBar.deferOnDragEnd();
Runnable onAnimationEndRunnable = () -> {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index dae4f3b..a6fc0f3 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,15 +16,20 @@
package com.android.launcher3;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Surface;
import android.view.WindowInsets;
@@ -43,6 +48,7 @@
import java.io.PrintWriter;
+@SuppressLint("NewApi")
public class DeviceProfile {
private static final float TABLET_MIN_DPS = 600;
@@ -51,6 +57,7 @@
public final InvariantDeviceProfile inv;
private final Info mInfo;
+ private final DisplayMetrics mMetrics;
// Device properties
public final boolean isTablet;
@@ -214,7 +221,8 @@
mInfo = info;
// Constants from resources
- float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y), info.metrics);
+ float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y),
+ info.densityDpi);
boolean allowRotation = context.getResources().getBoolean(R.bool.allow_rotation);
// Tablet UI is built with assumption that simulated landscape is disabled.
isTablet = allowRotation && swDPs >= TABLET_MIN_DPS;
@@ -227,6 +235,7 @@
context = getContext(context, info, isVerticalBarLayout()
? Configuration.ORIENTATION_LANDSCAPE
: Configuration.ORIENTATION_PORTRAIT);
+ mMetrics = context.getResources().getDisplayMetrics();
final Resources res = context.getResources();
isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get();
@@ -234,11 +243,13 @@
// Taskbar will be added later, but provides bottom insets that we should subtract
// from availableHeightPx.
taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
- WindowInsets windowInsets = DisplayController.INSTANCE.get(context).getHolder(mInfo.id)
- .getDisplayContext().getSystemService(WindowManager.class)
+ WindowInsets windowInsets =
+ context.createWindowContext(
+ context.getSystemService(DisplayManager.class).getDisplay(mInfo.id),
+ TYPE_APPLICATION, null)
+ .getSystemService(WindowManager.class)
.getCurrentWindowMetrics().getWindowInsets();
- nonOverlappingTaskbarInset =
- taskbarSize - windowInsets.getSystemWindowInsetBottom();
+ nonOverlappingTaskbarInset = taskbarSize - windowInsets.getSystemWindowInsetBottom();
if (nonOverlappingTaskbarInset > 0) {
nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset;
}
@@ -261,7 +272,7 @@
res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top);
- setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mInfo.metrics, 1f));
+ setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mMetrics, 1f));
cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx;
folderCellLayoutBorderSpacingPx = cellLayoutBorderSpacingPx;
@@ -308,7 +319,7 @@
hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
int hotseatExtraVerticalSize =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
- hotseatBarSizePx = pxFromDp(inv.iconSize, mInfo.metrics, 1f)
+ hotseatBarSizePx = pxFromDp(inv.iconSize, mMetrics, 1f)
+ (isVerticalBarLayout()
? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx)
: (hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx
@@ -511,16 +522,16 @@
// Workspace
final boolean isVerticalLayout = isVerticalBarLayout();
float invIconSizeDp = isLandscape ? inv.landscapeIconSize : inv.iconSize;
- iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale));
+ iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
float invIconTextSizeSp = isLandscape ? inv.landscapeIconTextSize : inv.iconTextSize;
- iconTextSizePx = (int) (Utilities.pxFromSp(invIconTextSizeSp, mInfo.metrics) * scale);
+ iconTextSizePx = (int) (Utilities.pxFromSp(invIconTextSizeSp, mMetrics) * scale);
iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale));
if (isScalableGrid) {
- cellWidthPx = pxFromDp(inv.minCellWidth, mInfo.metrics, scale);
- cellHeightPx = pxFromDp(inv.minCellHeight, mInfo.metrics, scale);
+ cellWidthPx = pxFromDp(inv.minCellWidth, mMetrics, scale);
+ cellHeightPx = pxFromDp(inv.minCellHeight, mMetrics, scale);
int cellContentHeight = iconSizePx + iconDrawablePaddingPx
+ Utilities.calculateTextHeight(iconTextSizePx);
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
@@ -542,8 +553,8 @@
// All apps
if (allAppsHasDifferentNumColumns()) {
- allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mInfo.metrics);
- allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mInfo.metrics);
+ allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
+ allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mMetrics);
allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
autoResizeAllAppsCells();
} else {
@@ -613,8 +624,8 @@
private void updateFolderCellSize(float scale, Resources res) {
float invIconSizeDp = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize;
- folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale));
- folderChildTextSizePx = pxFromDp(inv.iconTextSize, mInfo.metrics, scale);
+ folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
+ folderChildTextSizePx = pxFromDp(inv.iconTextSize, mMetrics, scale);
folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
@@ -801,14 +812,8 @@
*/
public boolean updateIsSeascape(Context context) {
if (isVerticalBarLayout()) {
- // Check an up-to-date info.
- DisplayController.Info displayInfo = DisplayController.getDefaultDisplay(context)
- .createInfoForContext(context);
- if (displayInfo == null) {
- return false;
- }
-
- boolean isSeascape = displayInfo.rotation == Surface.ROTATION_270;
+ boolean isSeascape = DisplayController.INSTANCE.get(context)
+ .getInfo().rotation == Surface.ROTATION_270;
if (mIsSeascape != isSeascape) {
mIsSeascape = isSeascape;
return true;
@@ -840,12 +845,12 @@
}
private String pxToDpStr(String name, float value) {
- return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mInfo.metrics) + "dp)";
+ return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mMetrics.densityDpi) + "dp)";
}
public void dump(String prefix, PrintWriter writer) {
writer.println(prefix + "DeviceProfile:");
- writer.println(prefix + "\t1 dp = " + mInfo.metrics.density + " px");
+ writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
writer.println(prefix + "\tisTablet:" + isTablet);
writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
@@ -938,7 +943,7 @@
private static Context getContext(Context c, Info info, int orientation) {
Configuration config = new Configuration(c.getResources().getConfiguration());
config.orientation = orientation;
- config.densityDpi = info.metrics.densityDpi;
+ config.densityDpi = info.densityDpi;
return c.createConfigurationContext(config);
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 61023be..11dc0c4 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -18,8 +18,9 @@
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.Utilities.getPointString;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
+import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
@@ -49,7 +50,6 @@
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IntArray;
@@ -156,7 +156,6 @@
public Rect defaultWidgetPadding;
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
- private ConfigMonitor mConfigMonitor;
private OverlayMonitor mOverlayMonitor;
@VisibleForTesting
@@ -203,7 +202,12 @@
.putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, getPointString(numColumns, numRows))
.apply();
- mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
+ DisplayController.INSTANCE.get(context).addChangeListener(
+ (info, flags) -> {
+ if ((flags & (CHANGE_SIZE | CHANGE_DENSITY)) != 0) {
+ onConfigChanged(context);
+ }
+ });
mOverlayMonitor = new OverlayMonitor(context);
}
@@ -227,7 +231,7 @@
// Get the display info based on default display and interpolate it to existing display
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
- DisplayController.getDefaultDisplay(context).getInfo(),
+ DisplayController.INSTANCE.get(context).getInfo(),
getPredefinedDeviceProfiles(context, gridName));
Info myInfo = new Info(context, display);
@@ -257,9 +261,6 @@
if (ENABLE_TWO_PANEL_HOME.get()) {
return ENABLE_TWO_PANEL_HOME.key;
}
- if (ENABLE_FOUR_COLUMNS.get()) {
- return ENABLE_FOUR_COLUMNS.key;
- }
return Utilities.isGridOptionsEnabled(context)
? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null;
}
@@ -276,7 +277,7 @@
}
private String initGrid(Context context, String gridName) {
- Info displayInfo = DisplayController.getDefaultDisplay(context).getInfo();
+ Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
@@ -286,6 +287,7 @@
private void initGrid(
Context context, Info displayInfo, DisplayOption displayOption) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
@@ -303,7 +305,7 @@
iconSize = displayOption.iconSize;
iconShapePath = getIconShapePath(context);
landscapeIconSize = displayOption.landscapeIconSize;
- iconBitmapSize = ResourceUtils.pxFromDp(iconSize, displayInfo.metrics);
+ iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
iconTextSize = displayOption.iconTextSize;
landscapeIconTextSize = displayOption.landscapeIconTextSize;
fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
@@ -328,7 +330,7 @@
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
- applyPartnerDeviceProfileOverrides(context, displayInfo.metrics);
+ applyPartnerDeviceProfileOverrides(context, metrics);
Point realSize = new Point(displayInfo.realSize);
// The real size never changes. smallSide and largeSide will remain the
@@ -425,10 +427,6 @@
}
private void apply(Context context, int changeFlags) {
- // Create a new config monitor
- mConfigMonitor.unregister();
- mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
-
for (OnIDPChangeListener listener : mChangeListeners) {
listener.onIdpChanged(changeFlags, this);
}
@@ -530,10 +528,10 @@
Point largestSize = new Point(displayInfo.largestSize);
// This guarantees that width < height
- float width = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y),
- displayInfo.metrics);
- float height = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y),
- displayInfo.metrics);
+ float width = Utilities.dpiFromPx((float) Math.min(smallestSize.x, smallestSize.y),
+ displayInfo.densityDpi);
+ float height = Utilities.dpiFromPx((float) Math.min(largestSize.x, largestSize.y),
+ displayInfo.densityDpi);
// Sort the profiles based on the closeness to the device size
Collections.sort(points, (a, b) ->
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 4754558..11585f9 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -17,9 +17,6 @@
package com.android.launcher3;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
-import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
-import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_WORKSPACE_SIZE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@@ -126,33 +123,6 @@
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
- // b/175329686 Temporary logic to gracefully migrate group of users to the new 4x5 grid.
- String gridName = InvariantDeviceProfile.getCurrentGridName(context);
- if (ENABLE_FOUR_COLUMNS.get()
- || "reasonable".equals(gridName)
- || ENABLE_FOUR_COLUMNS.key.equals(gridName)) {
- // Reset flag and remove it from developer options to prevent it from being enabled
- // again.
- ENABLE_FOUR_COLUMNS.reset(context);
- FeatureFlags.removeFlag(ENABLE_FOUR_COLUMNS);
-
- // Force migration code to run
- Utilities.getPrefs(context).edit()
- .remove(KEY_MIGRATION_SRC_HOTSEAT_COUNT)
- .remove(KEY_MIGRATION_SRC_WORKSPACE_SIZE)
- .apply();
-
- // We make an empty call here to ensure the database is created with the old IDP grid,
- // so that when we set the new grid the migration can proceeds as expected.
- LauncherSettings.Settings.call(context.getContentResolver(), "");
-
- String newGridName = "practical";
- Utilities.getPrefs(mContext).edit().putString("idp_grid_name", newGridName).commit();
- mInvariantDeviceProfile.setCurrentGrid(context, "practical");
- } else {
- FeatureFlags.removeFlag(ENABLE_FOUR_COLUMNS);
- }
-
mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 7496703..c9cc372 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -16,16 +16,14 @@
package com.android.launcher3;
+import static com.android.launcher3.anim.Interpolators.SCROLL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
-import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import static com.android.launcher3.touch.OverScroll.OVERSCROLL_DAMP_FACTOR;
-import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_BY;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_TO;
import android.animation.LayoutTransition;
-import android.animation.TimeInterpolator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
@@ -46,19 +44,17 @@
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.animation.Interpolator;
+import android.widget.OverScroller;
import android.widget.ScrollView;
import androidx.annotation.Nullable;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.pageindicators.PageIndicator;
-import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.PagedOrientationHandler.ChildBounds;
-import com.android.launcher3.util.OverScroller;
+import com.android.launcher3.util.EdgeEffectCompat;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
@@ -80,9 +76,6 @@
public static final int PAGE_SNAP_ANIMATION_DURATION = 750;
- // OverScroll constants
- private final static int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
-
private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
// The page is moved more than halfway, automatically move to the next page on touch up.
private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
@@ -113,7 +106,6 @@
protected int mMaxScroll;
protected int mMinScroll;
protected OverScroller mScroller;
- private Interpolator mDefaultInterpolator;
private VelocityTracker mVelocityTracker;
protected int mPageSpacing = 0;
@@ -144,12 +136,6 @@
protected boolean mIsPageInTransition = false;
private Runnable mOnPageTransitionEndCallback;
- protected float mSpringOverScroll;
-
- protected boolean mWasInOverscroll = false;
-
- protected int mUnboundedScroll;
-
// Page Indicator
@Thunk int mPageIndicatorViewId;
protected T mPageIndicator;
@@ -162,6 +148,9 @@
private int[] mTmpIntPair = new int[2];
+ protected EdgeEffectCompat mEdgeGlowLeft;
+ protected EdgeEffectCompat mEdgeGlowRight;
+
public PagedView(Context context) {
this(context, null);
}
@@ -181,8 +170,7 @@
setHapticFeedbackEnabled(false);
mIsRtl = Utilities.isRtl(getResources());
- mScroller = new OverScroller(context);
- setDefaultInterpolator(Interpolators.SCROLL);
+ mScroller = new OverScroller(context, SCROLL);
mCurrentPage = 0;
final ViewConfiguration configuration = ViewConfiguration.get(context);
@@ -196,12 +184,14 @@
mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * density);
mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density);
+ initEdgeEffect();
setDefaultFocusHighlightEnabled(false);
+ setWillNotDraw(false);
}
- protected void setDefaultInterpolator(Interpolator interpolator) {
- mDefaultInterpolator = interpolator;
- mScroller.setInterpolator(mDefaultInterpolator);
+ protected void initEdgeEffect() {
+ mEdgeGlowLeft = new EdgeEffectCompat(getContext());
+ mEdgeGlowRight = new EdgeEffectCompat(getContext());
}
public void initParentViews(View parent) {
@@ -256,7 +246,7 @@
newPosition = getScrollForPage(mCurrentPage);
}
mOrientationHandler.set(this, VIEW_SCROLL_TO, newPosition);
- mOrientationHandler.scrollerStartScroll(mScroller, newPosition);
+ mScroller.startScroll(mScroller.getCurrX(), 0, newPosition - mScroller.getCurrX(), 0);
forceFinishScroller(true);
}
@@ -420,7 +410,6 @@
* to provide custom behavior during animation.
*/
protected void onPageEndTransition() {
- mWasInOverscroll = false;
AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
AccessibilityManagerCompat.sendCustomAccessibilityEvent(getPageAt(mCurrentPage),
AccessibilityEvent.TYPE_VIEW_FOCUSED, null);
@@ -442,56 +431,12 @@
}
}
- protected int getUnboundedScroll() {
- return mUnboundedScroll;
- }
-
- @Override
- public void scrollBy(int x, int y) {
- mOrientationHandler.delegateScrollBy(this, getUnboundedScroll(), x, y);
- }
-
@Override
public void scrollTo(int x, int y) {
- int primaryScroll = mOrientationHandler.getPrimaryValue(x, y);
- int secondaryScroll = mOrientationHandler.getSecondaryValue(x, y);
- mUnboundedScroll = primaryScroll;
-
- boolean isBeforeFirstPage = mIsRtl ?
- (primaryScroll > mMaxScroll) : (primaryScroll < mMinScroll);
- boolean isAfterLastPage = mIsRtl ?
- (primaryScroll < mMinScroll) : (primaryScroll > mMaxScroll);
- if (!isBeforeFirstPage && !isAfterLastPage) {
- mSpringOverScroll = 0;
- }
-
- if (isBeforeFirstPage) {
- mOrientationHandler.delegateScrollTo(this,
- secondaryScroll, mIsRtl ? mMaxScroll : mMinScroll);
- if (mAllowOverScroll) {
- mWasInOverscroll = true;
- overScroll(primaryScroll - (mIsRtl ? mMaxScroll : mMinScroll));
- }
- } else if (isAfterLastPage) {
- mOrientationHandler.delegateScrollTo(this,
- secondaryScroll, mIsRtl ? mMinScroll : mMaxScroll);
- if (mAllowOverScroll) {
- mWasInOverscroll = true;
- overScroll(primaryScroll - (mIsRtl ? mMinScroll : mMaxScroll));
- }
- } else {
- if (mWasInOverscroll) {
- overScroll(0);
- mWasInOverscroll = false;
- }
- super.scrollTo(x, y);
- }
- }
-
- /**
- * Helper for {@link PagedOrientationHandler} to be able to call parent's scrollTo method
- */
- public void superScrollTo(int x, int y) {
+ x = Utilities.boundToRange(x,
+ mOrientationHandler.getPrimaryValue(mMinScroll, 0), mMaxScroll);
+ y = Utilities.boundToRange(y,
+ mOrientationHandler.getPrimaryValue(0, mMinScroll), mMaxScroll);
super.scrollTo(x, y);
}
@@ -524,12 +469,22 @@
protected boolean computeScrollHelper(boolean shouldInvalidate) {
if (mScroller.computeScrollOffset()) {
// Don't bother scrolling if the page does not need to be moved
- int currentScroll = mOrientationHandler.getPrimaryScroll(this);
- if (mUnboundedScroll != mScroller.getCurrPos()
- || currentScroll != mScroller.getCurrPos()) {
- mOrientationHandler.set(this, VIEW_SCROLL_TO, mScroller.getCurrPos());
+ int oldPos = mOrientationHandler.getPrimaryScroll(this);
+ int newPos = mScroller.getCurrX();
+ if (oldPos != newPos) {
+ mOrientationHandler.set(this, VIEW_SCROLL_TO, mScroller.getCurrX());
}
if (shouldInvalidate) {
+ if (mAllowOverScroll) {
+ if (newPos < mMinScroll && oldPos >= mMinScroll) {
+ mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
+ mScroller.abortAnimation();
+ } else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
+ mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
+ mScroller.abortAnimation();
+ }
+ }
+
invalidate();
}
return true;
@@ -982,9 +937,7 @@
mTotalMotion = 0;
mAllowEasyFling = false;
mActivePointerId = ev.getPointerId(0);
-
- updateIsBeingDraggedOnTouchDown();
-
+ updateIsBeingDraggedOnTouchDown(ev);
break;
}
@@ -1009,9 +962,9 @@
/**
* If being flinged and user touches the screen, initiate drag; otherwise don't.
*/
- private void updateIsBeingDraggedOnTouchDown() {
+ private void updateIsBeingDraggedOnTouchDown(MotionEvent ev) {
// mScroller.isFinished should be false when being flinged.
- final int xDist = Math.abs(mScroller.getFinalPos() - mScroller.getCurrPos());
+ final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mPageSlop / 3);
if (finishedScrolling) {
@@ -1020,9 +973,20 @@
setCurrentPage(getNextPage());
pageEndTransition();
}
+ mIsBeingDragged = !mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished();
} else {
mIsBeingDragged = true;
}
+
+ // Catch the edge effect if it is active.
+ float displacement = mOrientationHandler.getSecondaryValue(ev.getX(), ev.getY())
+ / mOrientationHandler.getSecondaryValue(getWidth(), getHeight());
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.onPullDistance(0f, 1f - displacement);
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.onPullDistance(0f, displacement);
+ }
}
public boolean isHandlingTouch() {
@@ -1053,7 +1017,6 @@
mTotalMotion += Math.abs(mLastMotion - primaryDirection);
mLastMotion = primaryDirection;
mLastMotionRemainder = 0;
- onScrollInteractionBegin();
pageBeginTransition();
// Stop listening for things like pinches.
requestDisallowInterceptTouchEvent(true);
@@ -1114,69 +1077,6 @@
}
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- if (mScroller.isSpringing() && mSpringOverScroll != 0) {
- int saveCount = canvas.save();
- mOrientationHandler.set(canvas, CANVAS_TRANSLATE, -mSpringOverScroll);
- super.dispatchDraw(canvas);
-
- canvas.restoreToCount(saveCount);
- } else {
- super.dispatchDraw(canvas);
- }
- }
-
- /**
- * Returns the amount of overscroll caused by the spring in {@link OverScroller}.
- */
- private int getSpringOverScroll(int amount) {
- if (mScroller.isSpringing()) {
- return amount < 0
- ? mScroller.getCurrPos() - mMinScroll
- : Math.max(0, mScroller.getCurrPos() - mMaxScroll);
- } else {
- return 0;
- }
- }
-
- protected void dampedOverScroll(int amount) {
- if (amount == 0) {
- return;
- }
-
- int size = mOrientationHandler.getMeasuredSize(this);
- int overScrollAmount = OverScroll.dampedScroll(amount, size);
- if (mScroller.isSpringing()) {
- mSpringOverScroll = getSpringOverScroll(amount);
- invalidate();
- return;
- }
-
- int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
- int boundedScroll = Utilities.boundToRange(primaryScroll, mMinScroll, mMaxScroll);
- mOrientationHandler.delegateScrollTo(this, boundedScroll + overScrollAmount);
- invalidate();
- }
-
- protected void overScroll(int amount) {
- if (mScroller.isSpringing()) {
- mSpringOverScroll = getSpringOverScroll(amount);
- invalidate();
- return;
- }
-
- if (amount == 0) return;
-
- if (mFreeScroll && !mScroller.isFinished()) {
- int scrollAmount = amount < 0 ? mMinScroll + amount : mMaxScroll + amount;
- mOrientationHandler.delegateScrollTo(this, scrollAmount);
- } else {
- dampedOverScroll(amount);
- }
- }
-
-
public void setEnableFreeScroll(boolean freeScroll) {
if (mFreeScroll == freeScroll) {
return;
@@ -1209,7 +1109,7 @@
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
- updateIsBeingDraggedOnTouchDown();
+ updateIsBeingDraggedOnTouchDown(ev);
/*
* If being flinged and user touches, stop the fling. isFinished
@@ -1228,7 +1128,6 @@
mAllowEasyFling = false;
mActivePointerId = ev.getPointerId(0);
if (mIsBeingDragged) {
- onScrollInteractionBegin();
pageBeginTransition();
}
break;
@@ -1245,19 +1144,62 @@
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) return true;
+ float oldScroll = mOrientationHandler.getPrimaryScroll(this);
+ float dx = ev.getX(pointerIndex);
+ float dy = ev.getY(pointerIndex);
- float direction = mOrientationHandler.getPrimaryDirection(ev, pointerIndex);
+ float direction = mOrientationHandler.getPrimaryValue(dx, dy);
float delta = mLastMotion + mLastMotionRemainder - direction;
+
+ int width = getWidth();
+ int height = getHeight();
+ int size = mOrientationHandler.getPrimaryValue(width, height);
+
+ final float displacement = mOrientationHandler.getSecondaryValue(dx, dy)
+ / mOrientationHandler.getSecondaryValue(width, height);
mTotalMotion += Math.abs(delta);
+ if (mAllowOverScroll) {
+ float consumed = 0;
+ if (delta < 0 && mEdgeGlowRight.getDistance() != 0f) {
+ consumed = size * mEdgeGlowRight.onPullDistance(delta / size, displacement);
+ } else if (delta > 0 && mEdgeGlowLeft.getDistance() != 0f) {
+ consumed = -size * mEdgeGlowLeft.onPullDistance(
+ -delta / size, 1 - displacement);
+ }
+ delta -= consumed;
+ }
+
// Only scroll and update mLastMotionX if we have moved some discrete amount. We
// keep the remainder because we are actually testing if we've moved from the last
// scrolled position (which is discrete).
- if (Math.abs(delta) >= 1.0f) {
- mLastMotion = direction;
- mLastMotionRemainder = delta - (int) delta;
+ mLastMotion = direction;
+ int movedDelta = (int) delta;
+ mLastMotionRemainder = delta - movedDelta;
- mOrientationHandler.set(this, VIEW_SCROLL_BY, (int) delta);
+ if (delta != 0) {
+ mOrientationHandler.set(this, VIEW_SCROLL_BY, movedDelta);
+
+ if (mAllowOverScroll) {
+ final float pulledToX = oldScroll + delta;
+
+ if (pulledToX < mMinScroll) {
+ mEdgeGlowLeft.onPullDistance(-delta / size, 1.f - displacement);
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.onRelease();
+ }
+ } else if (pulledToX > mMaxScroll) {
+ mEdgeGlowRight.onPullDistance(delta / size, displacement);
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.onRelease();
+ }
+ }
+
+ if (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished()) {
+ postInvalidateOnAnimation();
+ }
+ }
+
} else {
awakenScrollBars();
}
@@ -1335,45 +1277,24 @@
if (((initialScroll >= maxScroll) && (isVelocityLeft || !isFling)) ||
((initialScroll <= minScroll) && (!isVelocityLeft || !isFling))) {
- mScroller.springBack(initialScroll, minScroll, maxScroll);
+ mScroller.springBack(initialScroll, 0, minScroll, maxScroll, 0, 0);
mNextPage = getDestinationPage();
} else {
- mScroller.setInterpolator(mDefaultInterpolator);
- mScroller.fling(initialScroll, -velocity,
- minScroll, maxScroll,
- Math.round(getWidth() * 0.5f * OVERSCROLL_DAMP_FACTOR));
+ int velocity1 = -velocity;
+ // Continue a scroll or fling in progress
+ mScroller.fling(initialScroll, 0, velocity1, 0, minScroll, maxScroll, 0, 0,
+ Math.round(getWidth() * 0.5f * OVERSCROLL_DAMP_FACTOR), 0);
- int finalPos = mScroller.getFinalPos();
+ int finalPos = mScroller.getFinalX();
mNextPage = getDestinationPage(finalPos);
-
- int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
- int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
- if (snapToPageInFreeScroll() && finalPos > minScroll
- && finalPos < maxScroll) {
- // If scrolling ends in the half of the added space that is closer to
- // the end, settle to the end. Otherwise snap to the nearest page.
- // If flinging past one of the ends, don't change the velocity as it
- // will get stopped at the end anyway.
- int pageSnapped = finalPos < (firstPageScroll + minScroll) / 2
- ? minScroll
- : finalPos > (lastPageScroll + maxScroll) / 2
- ? maxScroll
- : getScrollForPage(mNextPage);
-
- mScroller.setFinalPos(pageSnapped);
- // Ensure the scroll/snap doesn't happen too fast;
- int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
- - mScroller.getDuration();
- if (extraScrollDuration > 0) {
- mScroller.extendDuration(extraScrollDuration);
- }
- }
+ onNotSnappingToPageInFreeScroll();
}
invalidate();
}
- onScrollInteractionEnd();
}
+ mEdgeGlowLeft.onRelease();
+ mEdgeGlowRight.onRelease();
// End any intermediate reordering states
resetTouchState();
break;
@@ -1381,8 +1302,9 @@
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged) {
snapToDestination();
- onScrollInteractionEnd();
}
+ mEdgeGlowLeft.onRelease();
+ mEdgeGlowRight.onRelease();
resetTouchState();
break;
@@ -1395,9 +1317,7 @@
return true;
}
- protected boolean snapToPageInFreeScroll() {
- return true;
- }
+ protected void onNotSnappingToPageInFreeScroll() { }
protected boolean shouldFlingForVelocity(int velocity) {
float threshold = mAllowEasyFling ? mEasyFlingThresholdVelocity : mFlingThresholdVelocity;
@@ -1410,15 +1330,6 @@
mActivePointerId = INVALID_POINTER;
}
- /**
- * Triggered by scrolling via touch
- */
- protected void onScrollInteractionBegin() {
- }
-
- protected void onScrollInteractionEnd() {
- }
-
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
@@ -1554,19 +1465,7 @@
}
protected void snapToDestination() {
- snapToPage(getDestinationPage(), getPageSnapDuration());
- }
-
- protected boolean isInOverScroll() {
- int scroll = mOrientationHandler.getPrimaryScroll(this);
- return scroll > mMaxScroll || scroll < mMinScroll;
- }
-
- protected int getPageSnapDuration() {
- if (isInOverScroll()) {
- return OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION;
- }
- return PAGE_SNAP_ANIMATION_DURATION;
+ snapToPage(getDestinationPage(), PAGE_SNAP_ANIMATION_DURATION);
}
// We want the duration of the page snap animation to be influenced by the distance that
@@ -1584,7 +1483,7 @@
int halfScreenSize = mOrientationHandler.getMeasuredSize(this) / 2;
final int newLoc = getScrollForPage(whichPage);
- int delta = newLoc - getUnboundedScroll();
+ int delta = newLoc - mOrientationHandler.getPrimaryScroll(this);
int duration = 0;
if (Math.abs(velocity) < mMinFlingVelocity) {
@@ -1609,12 +1508,7 @@
// interpolator at zero, ie. 5. We use 4 to make it a little slower.
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
- if (QUICKSTEP_SPRINGS.get() && mCurrentPage != whichPage) {
- return snapToPage(whichPage, delta, duration, false, null,
- velocity * Math.signum(delta), true);
- } else {
- return snapToPage(whichPage, delta, duration);
- }
+ return snapToPage(whichPage, delta, duration);
}
public boolean snapToPage(int whichPage) {
@@ -1622,32 +1516,26 @@
}
public boolean snapToPageImmediately(int whichPage) {
- return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null);
+ return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
}
public boolean snapToPage(int whichPage, int duration) {
- return snapToPage(whichPage, duration, false, null);
+ return snapToPage(whichPage, duration, false);
}
- public boolean snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
- return snapToPage(whichPage, duration, false, interpolator);
- }
-
- protected boolean snapToPage(int whichPage, int duration, boolean immediate,
- TimeInterpolator interpolator) {
+ protected boolean snapToPage(int whichPage, int duration, boolean immediate) {
whichPage = validateNewPage(whichPage);
int newLoc = getScrollForPage(whichPage);
- final int delta = newLoc - getUnboundedScroll();
- return snapToPage(whichPage, delta, duration, immediate, interpolator, 0, false);
+ final int delta = newLoc - mOrientationHandler.getPrimaryScroll(this);
+ return snapToPage(whichPage, delta, duration, immediate);
}
protected boolean snapToPage(int whichPage, int delta, int duration) {
- return snapToPage(whichPage, delta, duration, false, null, 0, false);
+ return snapToPage(whichPage, delta, duration, false);
}
- protected boolean snapToPage(int whichPage, int delta, int duration, boolean immediate,
- TimeInterpolator interpolator, float velocity, boolean spring) {
+ protected boolean snapToPage(int whichPage, int delta, int duration, boolean immediate) {
if (mFirstLayout) {
setCurrentPage(whichPage);
return false;
@@ -1677,18 +1565,7 @@
abortScrollerAnimation(false);
}
- if (interpolator != null) {
- mScroller.setInterpolator(interpolator);
- } else {
- mScroller.setInterpolator(mDefaultInterpolator);
- }
-
- if (spring && QUICKSTEP_SPRINGS.get()) {
- mScroller.startScrollSpring(getUnboundedScroll(), delta, duration, velocity);
- } else {
- mScroller.startScroll(getUnboundedScroll(), delta, duration);
- }
-
+ mScroller.startScroll(mOrientationHandler.getPrimaryScroll(this), 0, delta, 0, duration);
updatePageIndicator();
// Trigger a compute() to finish switching pages if necessary
@@ -1706,7 +1583,7 @@
snapToPage(getNextPage() - 1);
return true;
}
- return onOverscroll(-getMeasuredWidth());
+ return mAllowOverScroll;
}
public boolean scrollRight() {
@@ -1714,15 +1591,7 @@
snapToPage(getNextPage() + 1);
return true;
}
- return onOverscroll(getMeasuredWidth());
- }
-
- protected boolean onOverscroll(int amount) {
- if (!mAllowOverScroll) return false;
- onScrollInteractionBegin();
- overScroll(amount);
- onScrollInteractionEnd();
- return true;
+ return mAllowOverScroll;
}
@Override
@@ -1866,4 +1735,38 @@
mTmpIntPair[1] = rightChild;
return mTmpIntPair;
}
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ drawEdgeEffect(canvas);
+ }
+
+ protected void drawEdgeEffect(Canvas canvas) {
+ if (mAllowOverScroll && (!mEdgeGlowRight.isFinished() || !mEdgeGlowLeft.isFinished())) {
+ final int width = getWidth();
+ final int height = getHeight();
+ if (!mEdgeGlowLeft.isFinished()) {
+ final int restoreCount = canvas.save();
+ canvas.rotate(-90);
+ canvas.translate(-height, Math.min(mMinScroll, getScrollX()));
+ mEdgeGlowLeft.setSize(height, width);
+ if (mEdgeGlowLeft.draw(canvas)) {
+ postInvalidateOnAnimation();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ final int restoreCount = canvas.save();
+ canvas.rotate(90, width, 0);
+ canvas.translate(width, -(Math.max(mMaxScroll, getScrollX())));
+
+ mEdgeGlowRight.setSize(height, width);
+ if (mEdgeGlowRight.draw(canvas)) {
+ postInvalidateOnAnimation();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher3/Partner.java b/src/com/android/launcher3/Partner.java
index d79f62d..0bdb37c 100644
--- a/src/com/android/launcher3/Partner.java
+++ b/src/com/android/launcher3/Partner.java
@@ -129,7 +129,7 @@
"dimen", getPackageName());
if (resId > 0) {
int px = getResources().getDimensionPixelSize(resId);
- iconSize = Utilities.dpiFromPx(px, dm);
+ iconSize = Utilities.dpiFromPx((float) px, dm.densityDpi);
}
} catch (Resources.NotFoundException ex) {
Log.e(TAG, "Invalid Partner grid resource!", ex);
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 5036104..fe58da9 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -71,7 +71,7 @@
return;
}
- Log.i(LOG,
+ Log.d(LOG,
"Adding package name to install queue. Package name: " + info.getAppPackageName()
+ ", has app icon: " + (info.getAppIcon() != null)
+ ", has app label: " + !TextUtils.isEmpty(info.getAppLabel()));
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 6f12ec7..3312915 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -404,8 +404,8 @@
return res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
- public static float dpiFromPx(float size, DisplayMetrics metrics) {
- float densityRatio = (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT;
+ public static float dpiFromPx(float size, int densityDpi) {
+ float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT;
return (size / densityRatio);
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 10091a1..0c3a356 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -24,7 +24,6 @@
import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_INACCESSIBLE;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
@@ -96,10 +95,12 @@
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.WorkspaceTouchListener;
+import com.android.launcher3.util.EdgeEffectCompat;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.OverlayEdgeEffect;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.WallpaperOffsetInterpolator;
@@ -245,10 +246,7 @@
private float mTransitionProgress;
// State related to Launcher Overlay
- LauncherOverlay mLauncherOverlay;
- boolean mScrollInteractionBegan;
- boolean mStartedSendingScrollEvents;
- float mLastOverlayScroll = 0;
+ private OverlayEdgeEffect mOverlayEdgeEffect;
boolean mOverlayShown = false;
private Runnable mOnOverlayHiddenCallback;
@@ -945,47 +943,25 @@
}
}
- protected void onScrollInteractionBegin() {
- super.onScrollInteractionBegin();
- mScrollInteractionBegan = true;
- }
-
- protected void onScrollInteractionEnd() {
- super.onScrollInteractionEnd();
- mScrollInteractionBegan = false;
- if (mStartedSendingScrollEvents) {
- mStartedSendingScrollEvents = false;
- mLauncherOverlay.onScrollInteractionEnd();
- }
- }
-
public void setLauncherOverlay(LauncherOverlay overlay) {
- mLauncherOverlay = overlay;
- // A new overlay has been set. Reset event tracking
- mStartedSendingScrollEvents = false;
+ mOverlayEdgeEffect = overlay == null ? null : new OverlayEdgeEffect(getContext(), overlay);
+ EdgeEffectCompat newEffect = overlay == null
+ ? new EdgeEffectCompat(getContext()) : mOverlayEdgeEffect;
+ if (mIsRtl) {
+ mEdgeGlowRight = newEffect;
+ } else {
+ mEdgeGlowLeft = newEffect;
+ }
onOverlayScrollChanged(0);
}
public boolean hasOverlay() {
- return mLauncherOverlay != null;
- }
-
- private boolean isScrollingOverlay() {
- return mLauncherOverlay != null &&
- ((mIsRtl && getUnboundedScroll() > mMaxScroll)
- || (!mIsRtl && getUnboundedScroll() < mMinScroll));
+ return mOverlayEdgeEffect != null;
}
@Override
protected void snapToDestination() {
- // If we're overscrolling the overlay, we make sure to immediately reset the PagedView
- // to it's baseline position instead of letting the overscroll settle. The overlay handles
- // it's own settling, and every gesture to the overlay should be self-contained and start
- // from 0, so we zero it out here.
- if (isScrollingOverlay()) {
- // We reset mWasInOverscroll so that PagedView doesn't zero out the overscroll
- // interaction when we call snapToPageImmediately.
- mWasInOverscroll = false;
+ if (mOverlayEdgeEffect != null && !mOverlayEdgeEffect.isFinished()) {
snapToPageImmediately(0);
} else {
super.snapToDestination();
@@ -1018,38 +994,6 @@
}
@Override
- protected void overScroll(int amount) {
- boolean shouldScrollOverlay = mLauncherOverlay != null && !mScroller.isSpringing() &&
- ((amount <= 0 && !mIsRtl) || (amount >= 0 && mIsRtl));
-
- boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlayScroll != 0 &&
- ((amount >= 0 && !mIsRtl) || (amount <= 0 && mIsRtl));
-
- if (shouldScrollOverlay) {
- if (!mStartedSendingScrollEvents && mScrollInteractionBegan) {
- mStartedSendingScrollEvents = true;
- mLauncherOverlay.onScrollInteractionBegin();
- }
-
- mLastOverlayScroll = Math.abs(((float) amount) / getMeasuredWidth());
- mLauncherOverlay.onScrollChange(mLastOverlayScroll, mIsRtl);
- } else {
- dampedOverScroll(amount);
- }
-
- if (shouldZeroOverlay) {
- mLauncherOverlay.onScrollChange(0, mIsRtl);
- }
- }
-
- @Override
- protected boolean onOverscroll(int amount) {
- // Enforce overscroll on -1 direction
- if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false;
- return super.onOverscroll(amount);
- }
-
- @Override
protected boolean shouldFlingForVelocity(int velocityX) {
// When the overlay is moving, the fling or settle transition is controlled by the overlay.
return Float.compare(Math.abs(mOverlayTranslation), 0) == 0 &&
@@ -1377,10 +1321,6 @@
mOutlineProvider = outlineProvider;
}
- public void snapToPageFromOverView(int whichPage) {
- snapToPage(whichPage, OVERVIEW.getTransitionDuration(mLauncher), Interpolators.ZOOM_IN);
- }
-
private void onStartStateTransition(LauncherState state) {
mIsSwitchingState = true;
mTransitionProgress = 0;
@@ -2999,20 +2939,30 @@
* Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close
* animation.
*
+ * @param preferredItemId The id of the preferred item to match to if it exists.
* @param packageName The package name of the app to match.
* @param user The user of the app to match.
*/
- public View getFirstMatchForAppClose(String packageName, UserHandle user) {
- List<CellLayout> cellLayouts = new ArrayList<>(getPanelCount() + 1);
- cellLayouts.add(getHotseat());
- getVisiblePages().forEach(page -> cellLayouts.add((CellLayout) page));
-
- final Workspace.ItemOperator packageAndUser = (ItemInfo info, View view) -> info != null
- && info.getTargetComponent() != null
- && TextUtils.equals(info.getTargetComponent().getPackageName(), packageName)
- && info.user.equals(user);
+ public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user) {
+ final Workspace.ItemOperator preferredItem = (ItemInfo info, View view) ->
+ info != null && info.id == preferredItemId;
+ final Workspace.ItemOperator preferredItemInFolder = (info, view) -> {
+ if (info instanceof FolderInfo) {
+ FolderInfo folderInfo = (FolderInfo) info;
+ for (WorkspaceItemInfo shortcutInfo : folderInfo.contents) {
+ if (preferredItem.evaluate(shortcutInfo, view)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
final Workspace.ItemOperator packageAndUserAndApp = (ItemInfo info, View view) ->
- packageAndUser.evaluate(info, view) && info.itemType == ITEM_TYPE_APPLICATION;
+ info != null
+ && info.getTargetComponent() != null
+ && TextUtils.equals(info.getTargetComponent().getPackageName(), packageName)
+ && info.user.equals(user)
+ && info.itemType == ITEM_TYPE_APPLICATION;
final Workspace.ItemOperator packageAndUserAndAppInFolder = (info, view) -> {
if (info instanceof FolderInfo) {
FolderInfo folderInfo = (FolderInfo) info;
@@ -3025,13 +2975,18 @@
return false;
};
+ List<CellLayout> cellLayouts = new ArrayList<>(getPanelCount() + 1);
+ cellLayouts.add(getHotseat());
+ getVisiblePages().forEach(page -> cellLayouts.add((CellLayout) page));
+
// Order: App icons, app in folder. Items in hotseat get returned first.
if (ADAPTIVE_ICON_WINDOW_ANIM.get()) {
- return getFirstMatch(cellLayouts, packageAndUserAndApp, packageAndUserAndAppInFolder);
+ return getFirstMatch(cellLayouts, preferredItem, preferredItemInFolder,
+ packageAndUserAndApp, packageAndUserAndAppInFolder);
} else {
// Do not use Folder as a criteria, since it'll cause a crash when trying to draw
// FolderAdaptiveIcon as the background.
- return getFirstMatch(cellLayouts, packageAndUserAndApp);
+ return getFirstMatch(cellLayouts, preferredItem, packageAndUserAndApp);
}
}
@@ -3323,6 +3278,18 @@
}
}
+ /**
+ * Set the given view's pivot point to match the workspace's, so that it scales together. Since
+ * both this view and workspace can move, transform the point manually instead of using
+ * dragLayer.getDescendantCoordRelativeToSelf and related methods.
+ */
+ public void setPivotToScaleWithSelf(View sibling) {
+ sibling.setPivotY(getPivotY() + getTop()
+ - sibling.getTop() - sibling.getTranslationY());
+ sibling.setPivotX(getPivotX() + getLeft()
+ - sibling.getLeft() - sibling.getTranslationX());
+ }
+
@Override
public int getExpectedHeight() {
return getMeasuredHeight() <= 0 || !mIsLayoutValid
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index f4986f4..ed854dc 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -119,7 +119,7 @@
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
}
- setPivotToScaleWithWorkspace(hotseat);
+ mWorkspace.setPivotToScaleWithSelf(hotseat);
float hotseatScale = hotseatScaleAndTranslation.scale;
if (shouldSpring) {
PendingAnimation pa = (PendingAnimation) propertySetter;
@@ -156,18 +156,6 @@
}
}
- /**
- * Set the given view's pivot point to match the workspace's, so that it scales together. Since
- * both this view and workspace can move, transform the point manually instead of using
- * dragLayer.getDescendantCoordRelativeToSelf and related methods.
- */
- private void setPivotToScaleWithWorkspace(View sibling) {
- sibling.setPivotY(mWorkspace.getPivotY() + mWorkspace.getTop()
- - sibling.getTop() - sibling.getTranslationY());
- sibling.setPivotX(mWorkspace.getPivotX() + mWorkspace.getLeft()
- - sibling.getLeft() - sibling.getTranslationX());
- }
-
public void setScrim(PropertySetter propertySetter, LauncherState state,
StateAnimationConfig config) {
Scrim workspaceDragScrim = mLauncher.getDragLayer().getWorkspaceDragScrim();
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 7a38937..11e831e 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -27,7 +27,6 @@
import com.android.launcher3.Utilities;
-
/**
* Common interpolators used in Launcher
*/
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 44e3138..7d5ed60 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -199,10 +199,6 @@
"EXPANDED_SMARTSPACE", false, "Expands smartspace height to two rows. "
+ "Any apps occupying the first row will be removed from workspace.");
- public static final DeviceFlag ENABLE_FOUR_COLUMNS = new DeviceFlag(
- "ENABLE_FOUR_COLUMNS", false, "Uses 4 columns in launcher grid."
- + "Warning: This will permanently alter your home screen items and is not reversible.");
-
// TODO: b/172467144 Remove ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE feature flag.
public static final BooleanFlag ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE = new DeviceFlag(
"ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE", false, "Enables a "
@@ -233,6 +229,9 @@
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false,
"Sends a notification whenever launcher encounters an uncaught exception.");
+ public static final BooleanFlag PROTOTYPE_APP_CLOSE = getDebugFlag(
+ "PROTOTYPE_APP_CLOSE", false, "Enables new app close");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
@@ -242,12 +241,6 @@
}
}
- public static void removeFlag(DebugFlag flag) {
- synchronized (sDebugFlags) {
- sDebugFlags.remove(flag);
- }
- }
-
static List<DebugFlag> getDebugFlags() {
synchronized (sDebugFlags) {
return new ArrayList<>(sDebugFlags);
@@ -325,15 +318,6 @@
.getBoolean(key, defaultValue);
}
- /**
- * Resets value to default value.
- */
- public void reset(Context context) {
- mCurrentValue = defaultValue;
- context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
- .edit().putBoolean(key, defaultValue).apply();
- }
-
@Override
protected StringBuilder appendProps(StringBuilder src) {
return super.appendProps(src).append(", mCurrentValue=").append(mCurrentValue);
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index c1f4643..a4e8be6 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -42,7 +42,6 @@
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace.ItemOperator;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -433,8 +432,7 @@
int scroll = getScrollForPage(getNextPage()) + hint;
int delta = scroll - getScrollX();
if (delta != 0) {
- mScroller.setInterpolator(Interpolators.DEACCEL);
- mScroller.startScroll(getScrollX(), delta, Folder.SCROLL_HINT_DURATION);
+ mScroller.startScroll(getScrollX(), 0, delta, 0, Folder.SCROLL_HINT_DURATION);
invalidate();
}
}
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index fd51ba8..29287d9 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -32,11 +32,13 @@
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.PackageManagerHelper;
@@ -126,6 +128,12 @@
}
SessionInfo sessionInfo = packageInstaller.getActiveSessionInfo(item.user,
packageName);
+
+ if (!packageInstaller.verifySessionInfo(sessionInfo)) {
+ Log.d(LOG, "Item info failed session info verification: "
+ + workspaceInfo);
+ }
+
List<LauncherActivityInfo> activities = launcherApps
.getActivityList(packageName, item.user);
boolean hasActivity = activities != null && !activities.isEmpty();
@@ -171,7 +179,15 @@
// Save the WorkspaceItemInfo for binding in the workspace
addedItemsFinal.add(itemInfo);
- Log.i(LOG, "Adding item info to workspace: " + itemInfo);
+ // log bitmap and label
+ Log.d(LOG, "Adding item info to workspace: " + itemInfo);
+ if (itemInfo instanceof ItemInfoWithIcon) {
+ ItemInfoWithIcon infoWithIcon = (ItemInfoWithIcon) itemInfo;
+
+ Log.d(LOG, "Item info icon base 64 string: "
+ + infoWithIcon.bitmap.icon == null
+ ? "null" : IOUtils.toBase64String(infoWithIcon.bitmap.icon));
+ }
}
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 836d804..22cb46b 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -130,6 +130,7 @@
// Add the items and clear queue
if (!installQueue.isEmpty()) {
+ // add log
launcher.getModel().addAndBindAddedWorkspaceItems(installQueue);
}
mItems.clear();
@@ -184,14 +185,20 @@
}
private void queuePendingShortcutInfo(PendingInstallShortcutInfo info) {
+ final Exception stackTrace = new Exception();
+
// Queue the item up for adding if launcher has not loaded properly yet
MODEL_EXECUTOR.post(() -> {
Pair<ItemInfo, Object> itemInfo = info.getItemInfo(mContext);
if (itemInfo == null) {
- Log.i(LOG, "Adding PendingInstallShortcutInfo with no attached info to queue.");
+ Log.d(LOG,
+ "Adding PendingInstallShortcutInfo with no attached info to queue.",
+ stackTrace);
} else {
- Log.i(LOG, "Adding PendingInstallShortcutInfo to queue. Attached info: "
- + itemInfo.first);
+ Log.d(LOG,
+ "Adding PendingInstallShortcutInfo to queue. Attached info: "
+ + itemInfo.first,
+ stackTrace);
}
addToQueue(info);
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 72f1c58..88db430 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -25,6 +25,7 @@
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
@@ -40,6 +41,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.ItemInstallQueue;
+import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.MainThreadInitializedObject;
@@ -215,14 +217,8 @@
void tryQueuePromiseAppIcon(PackageInstaller.SessionInfo sessionInfo) {
if (FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
&& SessionCommitReceiver.isEnabled(mAppContext)
- && verify(sessionInfo) != null
- && sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
- && sessionInfo.getAppIcon() != null
- && !TextUtils.isEmpty(sessionInfo.getAppLabel())
- && !promiseIconAddedForId(sessionInfo.getSessionId())
- && !new PackageManagerHelper(mAppContext).isAppInstalled(
- sessionInfo.getAppPackageName(), getUserHandle(sessionInfo))) {
- Log.i(LOG, "Adding package name to install queue: "
+ && verifySessionInfo(sessionInfo)) {
+ Log.d(LOG, "Adding package name to install queue: "
+ sessionInfo.getAppPackageName());
ItemInstallQueue.INSTANCE.get(mAppContext)
@@ -233,6 +229,37 @@
}
}
+ public boolean verifySessionInfo(PackageInstaller.SessionInfo sessionInfo) {
+ boolean validSessionInfo = verify(sessionInfo) != null
+ && sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
+ && sessionInfo.getAppIcon() != null
+ && !TextUtils.isEmpty(sessionInfo.getAppLabel())
+ && !promiseIconAddedForId(sessionInfo.getSessionId())
+ && !new PackageManagerHelper(mAppContext).isAppInstalled(
+ sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
+
+ if (sessionInfo != null) {
+ Bitmap appIcon = sessionInfo.getAppIcon();
+
+ Log.d(LOG, String.format(
+ "Verifying session info. Valid: %b, Session verified: %b, Install reason valid:"
+ + " %b, App icon: %s, App label: %s, Promise icon added: %b, "
+ + "App installed: %b.",
+ validSessionInfo,
+ verify(sessionInfo) != null,
+ sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER,
+ appIcon == null ? "null" : IOUtils.toBase64String(appIcon),
+ sessionInfo.getAppLabel(),
+ promiseIconAddedForId(sessionInfo.getSessionId()),
+ new PackageManagerHelper(mAppContext).isAppInstalled(
+ sessionInfo.getAppPackageName(), getUserHandle(sessionInfo))));
+ } else {
+ Log.d(LOG, "Verifying session info failed: session info null.");
+ }
+
+ return validSessionInfo;
+ }
+
public InstallSessionTracker registerInstallTracker(InstallSessionTracker.Callback callback) {
InstallSessionTracker tracker = new InstallSessionTracker(this, callback);
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index e8695c9..217453f 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -269,6 +269,20 @@
}
PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
sandboxCategory.setSummary("Learn and practice navigation gestures");
+ Preference launchOnboardingTutorialPreference = new Preference(context);
+ launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
+ launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
+ launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
+ launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
+ startActivity(launchSandboxIntent.putExtra(
+ "tutorial_steps",
+ new String[] {
+ "LEFT_EDGE_BACK_NAVIGATION",
+ "HOME_NAVIGATION",
+ "OVERVIEW_NAVIGATION"}));
+ return true;
+ });
+ sandboxCategory.addPreference(launchOnboardingTutorialPreference);
Preference launchBackTutorialPreference = new Preference(context);
launchBackTutorialPreference.setKey("launchBackTutorial");
launchBackTutorialPreference.setTitle("Launch Back Tutorial");
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 2e54904..ce7dc07 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -180,7 +180,7 @@
LauncherApps launcherApps = launcher.getSystemService(LauncherApps.class);
try {
launcherApps.startPackageInstallerSessionDetailsActivity(sessionInfo, null,
- launcher.getActivityLaunchOptions(v).toBundle());
+ launcher.getActivityLaunchOptions(v, item).toBundle());
return;
} catch (Exception e) {
Log.e(TAG, "Unable to launch market intent for package=" + packageName, e);
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 18e27a4..2254ab3 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -38,10 +38,8 @@
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import java.util.Collections;
@@ -60,18 +58,23 @@
}
@Override
- public void delegateScrollTo(PagedView pagedView, int secondaryScroll, int minMaxScroll) {
- pagedView.superScrollTo(secondaryScroll, minMaxScroll);
+ public int getPrimaryValue(int x, int y) {
+ return y;
}
@Override
- public void delegateScrollBy(PagedView pagedView, int unboundedScroll, int x, int y) {
- pagedView.scrollTo(pagedView.getScrollX() + x, unboundedScroll + y);
+ public int getSecondaryValue(int x, int y) {
+ return x;
}
@Override
- public void scrollerStartScroll(OverScroller scroller, int newPosition) {
- scroller.startScroll(scroller.getCurrPos(), newPosition - scroller.getCurrPos());
+ public float getPrimaryValue(float x, float y) {
+ return y;
+ }
+
+ @Override
+ public float getSecondaryValue(float x, float y) {
+ return x;
}
@Override
@@ -87,11 +90,6 @@
}
@Override
- public void delegateScrollTo(PagedView pagedView, int primaryScroll) {
- pagedView.superScrollTo(pagedView.getScrollX(), primaryScroll);
- }
-
- @Override
public <T> void set(T target, Int2DAction<T> action, int param) {
action.call(target, 0, param);
}
@@ -241,13 +239,13 @@
}
@Override
- public float getTaskMenuX(float x, View thumbnailView) {
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
return thumbnailView.getMeasuredWidth() + x;
}
@Override
- public float getTaskMenuY(float y, View thumbnailView) {
- return y;
+ public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
+ return y + overScroll;
}
@Override
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 560df86..c9149ff 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -30,8 +30,6 @@
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.PagedView;
-import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
@@ -89,16 +87,19 @@
boolean getRecentsRtlSetting(Resources resources);
float getDegreesRotated();
int getRotation();
+
<T> T getPrimaryValue(T x, T y);
<T> T getSecondaryValue(T x, T y);
- void delegateScrollTo(PagedView pagedView, int secondaryScroll, int primaryScroll);
- /** Uses {@params pagedView}.getScroll[X|Y]() method for the secondary amount*/
- void delegateScrollTo(PagedView pagedView, int primaryScroll);
- void delegateScrollBy(PagedView pagedView, int unboundedScroll, int x, int y);
- void scrollerStartScroll(OverScroller scroller, int newPosition);
+
+ int getPrimaryValue(int x, int y);
+ int getSecondaryValue(int x, int y);
+
+ float getPrimaryValue(float x, float y);
+ float getSecondaryValue(float x, float y);
+
boolean isLayoutNaturalToLauncher();
- float getTaskMenuX(float x, View thumbnailView);
- float getTaskMenuY(float y, View thumbnailView);
+ float getTaskMenuX(float x, View thumbnailView, int overScroll);
+ float getTaskMenuY(float y, View thumbnailView, int overScroll);
int getTaskMenuWidth(View view);
int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate, LinearLayout taskMenuLayout);
void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 86508c4..31586e7 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -36,10 +36,8 @@
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import java.util.ArrayList;
@@ -58,18 +56,23 @@
}
@Override
- public void delegateScrollTo(PagedView pagedView, int secondaryScroll, int primaryScroll) {
- pagedView.superScrollTo(primaryScroll, secondaryScroll);
+ public int getPrimaryValue(int x, int y) {
+ return x;
}
@Override
- public void delegateScrollBy(PagedView pagedView, int unboundedScroll, int x, int y) {
- pagedView.scrollTo(unboundedScroll + x, pagedView.getScrollY() + y);
+ public int getSecondaryValue(int x, int y) {
+ return y;
}
@Override
- public void scrollerStartScroll(OverScroller scroller, int newPosition) {
- scroller.startScroll(newPosition - scroller.getCurrPos(), scroller.getCurrPos());
+ public float getPrimaryValue(float x, float y) {
+ return x;
+ }
+
+ @Override
+ public float getSecondaryValue(float x, float y) {
+ return y;
}
@Override
@@ -83,11 +86,6 @@
}
@Override
- public void delegateScrollTo(PagedView pagedView, int primaryScroll) {
- pagedView.superScrollTo(primaryScroll, pagedView.getScrollY());
- }
-
- @Override
public <T> void set(T target, Int2DAction<T> action, int param) {
action.call(target, param, 0);
}
@@ -240,12 +238,12 @@
}
@Override
- public float getTaskMenuX(float x, View thumbnailView) {
- return x;
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
+ return x + overScroll;
}
@Override
- public float getTaskMenuY(float y, View thumbnailView) {
+ public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
return y;
}
@@ -313,21 +311,31 @@
@Override
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
List<SplitPositionOption> options = new ArrayList<>(1);
+ // Add both left and right options if we're in tablet mode
// TODO: Add in correct icons
- if (dp.isSeascape()) { // or seascape
- // Add left/right options
+ if (dp.isTablet && dp.isLandscape) {
options.add(new SplitPositionOption(
R.drawable.ic_split_screen, R.string.split_screen_position_right,
- STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
- } else if (dp.isLandscape) {
+ STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
options.add(new SplitPositionOption(
R.drawable.ic_split_screen, R.string.split_screen_position_left,
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
} else {
- // Only add top option
- options.add(new SplitPositionOption(
- R.drawable.ic_split_screen, R.string.split_screen_position_top,
- STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
+ if (dp.isSeascape()) {
+ // Add left/right options
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_right,
+ STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
+ } else if (dp.isLandscape) {
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_left,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
+ } else {
+ // Only add top option
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_top,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
+ }
}
return options;
}
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index bd6e31b..893a274 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -79,13 +79,13 @@
}
@Override
- public float getTaskMenuX(float x, View thumbnailView) {
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
return x;
}
@Override
- public float getTaskMenuY(float y, View thumbnailView) {
- return y + thumbnailView.getMeasuredHeight();
+ public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
+ return y + thumbnailView.getMeasuredHeight() + overScroll;
}
@Override
diff --git a/src/com/android/launcher3/util/ActivityTracker.java b/src/com/android/launcher3/util/ActivityTracker.java
index 59266b4..b5b9c2f 100644
--- a/src/com/android/launcher3/util/ActivityTracker.java
+++ b/src/com/android/launcher3/util/ActivityTracker.java
@@ -75,9 +75,8 @@
private boolean handleIntent(T activity, Intent intent, boolean alreadyOnHome) {
if (intent != null && intent.getExtras() != null) {
IBinder stateBinder = intent.getExtras().getBinder(EXTRA_SCHEDULER_CALLBACK);
- if (stateBinder instanceof ObjectWrapper) {
- SchedulerCallback<T> handler =
- ((ObjectWrapper<SchedulerCallback>) stateBinder).get();
+ SchedulerCallback<T> handler = ObjectWrapper.unwrap(stateBinder);
+ if (handler != null) {
if (!handler.init(activity, alreadyOnHome)) {
intent.getExtras().remove(EXTRA_SCHEDULER_CALLBACK);
}
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
deleted file mode 100644
index f7023e8..0000000
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package com.android.launcher3.util;
-
-/**
- * Copyright (C) 2015 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.
- */
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.util.Log;
-
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
-import com.android.launcher3.util.DisplayController.Info;
-
-import java.util.function.Consumer;
-
-/**
- * {@link BroadcastReceiver} which watches configuration changes and
- * notifies the callback in case changes which affect the device profile occur.
- */
-public class ConfigMonitor extends BroadcastReceiver implements DisplayInfoChangeListener {
-
- private static final String TAG = "ConfigMonitor";
-
- private final Point mTmpPoint1 = new Point();
- private final Point mTmpPoint2 = new Point();
-
- private final Context mContext;
- private final float mFontScale;
- private final int mDensity;
-
- private final int mDisplayId;
- private final Point mRealSize;
- private final Point mSmallestSize, mLargestSize;
-
- private Consumer<Context> mCallback;
-
- public ConfigMonitor(Context context, Consumer<Context> callback) {
- mContext = context;
-
- Configuration config = context.getResources().getConfiguration();
- mFontScale = config.fontScale;
- mDensity = config.densityDpi;
-
- DisplayController.DisplayHolder display = DisplayController.getDefaultDisplay(context);
- display.addChangeListener(this);
- Info displayInfo = display.getInfo();
- mDisplayId = displayInfo.id;
-
- mRealSize = new Point(displayInfo.realSize);
- mSmallestSize = new Point(displayInfo.smallestSize);
- mLargestSize = new Point(displayInfo.largestSize);
-
- mCallback = callback;
-
- // Listen for configuration change
- mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "ConfigMonitor.register: this="
- + System.identityHashCode(this) + " callback=" + callback.getClass().getName());
- }
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Configuration config = context.getResources().getConfiguration();
- if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
- Log.d(TAG, "Configuration changed.");
- notifyChange();
- }
- }
-
- @Override
- public void onDisplayInfoChanged(Info info, int flags) {
- if (info.id != mDisplayId) {
- return;
- }
- mTmpPoint1.set(info.realSize.x, info.realSize.y);
- if (!mRealSize.equals(mTmpPoint1) && !mRealSize.equals(mTmpPoint1.y, mTmpPoint1.x)) {
- Log.d(TAG, String.format("Display size changed from %s to %s", mRealSize, mTmpPoint1));
- notifyChange();
- return;
- }
-
- mTmpPoint1.set(info.smallestSize.x, info.smallestSize.y);
- mTmpPoint2.set(info.largestSize.x, info.largestSize.y);
- if (!mSmallestSize.equals(mTmpPoint1) || !mLargestSize.equals(mTmpPoint2)) {
- Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
- mSmallestSize, mLargestSize, mTmpPoint1, mTmpPoint2));
- notifyChange();
- }
- }
-
- private synchronized void notifyChange() {
- if (mCallback != null) {
- Consumer<Context> callback = mCallback;
- mCallback = null;
- MAIN_EXECUTOR.execute(() -> callback.accept(mContext));
- }
- }
-
- public void unregister() {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "ConfigMonitor.unregister: this="
- + System.identityHashCode(this));
- }
- try {
- mContext.unregisterReceiver(this);
- DisplayController.getDefaultDisplay(mContext).removeChangeListener(this);
- } catch (Exception e) {
- Log.e(TAG, "Failed to unregister config monitor", e);
- }
- }
-}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index d0e8bb1..07c89b9 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -16,21 +16,28 @@
package com.android.launcher3.util;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.ComponentCallbacks;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
-import android.util.DisplayMetrics;
+import android.os.Build;
import android.util.Log;
-import android.util.SparseArray;
import android.view.Display;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
+import androidx.annotation.AnyThread;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
import com.android.launcher3.Utilities;
@@ -39,104 +46,78 @@
/**
* Utility class to cache properties of default display to avoid a system RPC on every call.
*/
-public class DisplayController implements DisplayListener {
+@SuppressLint("NewApi")
+public class DisplayController implements DisplayListener, ComponentCallbacks {
private static final String TAG = "DisplayController";
public static final MainThreadInitializedObject<DisplayController> INSTANCE =
new MainThreadInitializedObject<>(DisplayController::new);
- private final SparseArray<DisplayHolder> mOtherDisplays = new SparseArray<>(0);
- // We store the default display separately, to avoid null checks for primary use case.
- private final DisplayHolder mDefaultDisplay;
+ public static final int CHANGE_SIZE = 1 << 0;
+ public static final int CHANGE_ROTATION = 1 << 1;
+ public static final int CHANGE_FRAME_DELAY = 1 << 2;
+ public static final int CHANGE_DENSITY = 1 << 3;
- private final ArrayList<DisplayListChangeListener> mListListeners = new ArrayList<>();
+ public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION
+ | CHANGE_FRAME_DELAY | CHANGE_DENSITY;
+
+ private final Context mContext;
+ private final DisplayManager mDM;
+
+ // Null for SDK < S
+ private final Context mWindowContext;
+
+ private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
+ private Info mInfo;
private DisplayController(Context context) {
- mDefaultDisplay = DisplayHolder.create(context, DEFAULT_DISPLAY);
+ mContext = context;
+ mDM = context.getSystemService(DisplayManager.class);
- DisplayManager dm = context.getSystemService(DisplayManager.class);
- dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
- }
-
- @Override
- public final void onDisplayAdded(int displayId) {
- DisplayHolder holder = DisplayHolder.create(mDefaultDisplay.mDisplayContext, displayId);
- if (holder == null) {
- // Display is already removed by the time we dot this.
- return;
- }
- synchronized (mOtherDisplays) {
- mOtherDisplays.put(displayId, holder);
- }
- MAIN_EXECUTOR.execute(() -> mListListeners.forEach(l-> l.onDisplayAdded(holder)));
- }
-
- @Override
- public final void onDisplayRemoved(int displayId) {
- synchronized (mOtherDisplays) {
- mOtherDisplays.remove(displayId);
- }
- MAIN_EXECUTOR.execute(() -> mListListeners.forEach(l-> l.onDisplayRemoved(displayId)));
- }
-
- /**
- * Returns the holder corresponding to the given display
- */
- public DisplayHolder getHolder(int displayId) {
- if (displayId == mDefaultDisplay.mId) {
- return mDefaultDisplay;
+ Display display = mDM.getDisplay(DEFAULT_DISPLAY);
+ if (Utilities.ATLEAST_S) {
+ mWindowContext = mContext.createWindowContext(display, TYPE_APPLICATION, null);
+ mWindowContext.registerComponentCallbacks(this);
} else {
- synchronized (mOtherDisplays) {
- return mOtherDisplays.get(displayId);
- }
+ mWindowContext = null;
+ SimpleBroadcastReceiver configChangeReceiver =
+ new SimpleBroadcastReceiver(this::onConfigChanged);
+ mContext.registerReceiver(configChangeReceiver,
+ new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
+
+ mInfo = createInfo(display);
+ mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
}
- /**
- * Adds a listener for display list changes
- */
- public void addListChangeListener(DisplayListChangeListener listener) {
- mListListeners.add(listener);
- }
+ @Override
+ public final void onDisplayAdded(int displayId) { }
- /**
- * Removes a previously added display list change listener
- */
- public void removeListChangeListener(DisplayListChangeListener listener) {
- mListListeners.remove(listener);
- }
+ @Override
+ public final void onDisplayRemoved(int displayId) { }
+ @WorkerThread
@Override
public final void onDisplayChanged(int displayId) {
- DisplayHolder holder = getHolder(displayId);
- if (holder != null) {
- holder.handleOnChange();
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
}
+ Display display = mDM.getDisplay(DEFAULT_DISPLAY);
+ if (display == null) {
+ return;
+ }
+ if (Utilities.ATLEAST_S) {
+ // Only check for refresh rate. Everything else comes from component callbacks
+ if (getSingleFrameMs(display) == mInfo.singleFrameMs) {
+ return;
+ }
+ }
+ handleInfoChange(display);
}
public static int getSingleFrameMs(Context context) {
- return getDefaultDisplay(context).getInfo().singleFrameMs;
- }
-
- public static DisplayHolder getDefaultDisplay(Context context) {
- return INSTANCE.get(context).mDefaultDisplay;
- }
-
- /**
- * A listener to receiving addition or removal of new displays
- */
- public interface DisplayListChangeListener {
-
- /**
- * Called when a new display is added
- */
- void onDisplayAdded(DisplayHolder holder);
-
- /**
- * Called when a previously added display is removed
- */
- void onDisplayRemoved(int displayId);
+ return INSTANCE.get(context).getInfo().singleFrameMs;
}
/**
@@ -147,147 +128,121 @@
void onDisplayInfoChanged(Info info, int flags);
}
- public static class DisplayHolder {
-
- public static final int CHANGE_SIZE = 1 << 0;
- public static final int CHANGE_ROTATION = 1 << 1;
- public static final int CHANGE_FRAME_DELAY = 1 << 2;
-
- public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY;
-
- final Context mDisplayContext;
- final int mId;
- private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
- private DisplayController.Info mInfo;
-
- private DisplayHolder(Context displayContext) {
- mDisplayContext = displayContext;
- // Note that the Display object must be obtained from DisplayManager which is
- // associated to the display context, so the Display is isolated from Activity and
- // Application to provide the actual state of device that excludes the additional
- // adjustment and override.
- mInfo = new DisplayController.Info(mDisplayContext);
- mId = mInfo.id;
- }
-
- public void addChangeListener(DisplayInfoChangeListener listener) {
- mListeners.add(listener);
- }
-
- public void removeChangeListener(DisplayInfoChangeListener listener) {
- mListeners.remove(listener);
- }
-
- public DisplayController.Info getInfo() {
- return mInfo;
- }
-
- /** Creates and up-to-date DisplayController.Info for the given context. */
- @Nullable
- public Info createInfoForContext(Context context) {
- Display display = Utilities.ATLEAST_R ? context.getDisplay() : null;
- if (display == null) {
- display = context.getSystemService(DisplayManager.class).getDisplay(mId);
- }
- if (display == null) {
- return null;
- }
- // Refresh the Context the prevent stale DisplayMetrics.
- Context displayContext = context.getApplicationContext().createDisplayContext(display);
- return new Info(displayContext, display);
- }
-
- public Context getDisplayContext() {
- return mDisplayContext;
- }
-
- protected void handleOnChange() {
- Info oldInfo = mInfo;
- Info newInfo = createInfoForContext(mDisplayContext);
- if (newInfo == null) {
- return;
- }
-
- int change = 0;
- if (newInfo.hasDifferentSize(oldInfo)) {
- change |= CHANGE_SIZE;
- }
- if (newInfo.rotation != oldInfo.rotation) {
- change |= CHANGE_ROTATION;
- }
- if (newInfo.singleFrameMs != oldInfo.singleFrameMs) {
- change |= CHANGE_FRAME_DELAY;
- }
-
- if (change != 0) {
- mInfo = newInfo;
- final int flags = change;
- MAIN_EXECUTOR.execute(() -> notifyChange(flags));
+ /**
+ * Only used for pre-S
+ */
+ private void onConfigChanged(Intent intent) {
+ Configuration config = mContext.getResources().getConfiguration();
+ if (config.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
+ Log.d(TAG, "Configuration changed, notifying listeners");
+ Display display = mDM.getDisplay(DEFAULT_DISPLAY);
+ if (display != null) {
+ handleInfoChange(display);
}
}
+ }
- private void notifyChange(int flags) {
- for (int i = mListeners.size() - 1; i >= 0; i--) {
- mListeners.get(i).onDisplayInfoChanged(mInfo, flags);
- }
+ @UiThread
+ @Override
+ @TargetApi(Build.VERSION_CODES.S)
+ public final void onConfigurationChanged(Configuration config) {
+ Display display = mWindowContext.getDisplay();
+ if (config.densityDpi != mInfo.densityDpi
+ || config.fontScale != mInfo.fontScale
+ || display.getRotation() != mInfo.rotation
+ || !mInfo.mScreenSizeDp.equals(
+ Math.min(config.screenHeightDp, config.screenWidthDp),
+ Math.max(config.screenHeightDp, config.screenWidthDp))) {
+ handleInfoChange(display);
+ }
+ }
+
+ @Override
+ public final void onLowMemory() { }
+
+ public void addChangeListener(DisplayInfoChangeListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeChangeListener(DisplayInfoChangeListener listener) {
+ mListeners.remove(listener);
+ }
+
+ public Info getInfo() {
+ return mInfo;
+ }
+
+ private Info createInfo(Display display) {
+ return new Info(mContext.createDisplayContext(display), display);
+ }
+
+ @AnyThread
+ private void handleInfoChange(Display display) {
+ Info oldInfo = mInfo;
+ Info newInfo = createInfo(display);
+ int change = 0;
+ if (newInfo.hasDifferentSize(oldInfo)) {
+ change |= CHANGE_SIZE;
+ }
+ if (newInfo.rotation != oldInfo.rotation) {
+ change |= CHANGE_ROTATION;
+ }
+ if (newInfo.singleFrameMs != oldInfo.singleFrameMs) {
+ change |= CHANGE_FRAME_DELAY;
+ }
+ if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
+ change |= CHANGE_DENSITY;
}
- private static DisplayHolder create(Context context, int id) {
- DisplayManager dm = context.getSystemService(DisplayManager.class);
- Display display = dm.getDisplay(id);
- if (display == null) {
- return null;
- }
- // Use application context to create display context so that it can have its own
- // Resources.
- Context displayContext = context.getApplicationContext().createDisplayContext(display);
- return new DisplayHolder(displayContext);
+ if (change != 0) {
+ mInfo = newInfo;
+ final int flags = change;
+ MAIN_EXECUTOR.execute(() -> notifyChange(flags));
+ }
+ }
+
+ private void notifyChange(int flags) {
+ for (int i = mListeners.size() - 1; i >= 0; i--) {
+ mListeners.get(i).onDisplayInfoChanged(mInfo, flags);
}
}
public static class Info {
public final int id;
- public final int rotation;
public final int singleFrameMs;
+ // Configuration properties
+ public final int rotation;
+ public final float fontScale;
+ public final int densityDpi;
+
+ private final Point mScreenSizeDp;
+
public final Point realSize;
public final Point smallestSize;
public final Point largestSize;
- public final DisplayMetrics metrics;
-
- @VisibleForTesting
- public Info(int id, int rotation, int singleFrameMs, Point realSize, Point smallestSize,
- Point largestSize, DisplayMetrics metrics) {
- this.id = id;
- this.rotation = rotation;
- this.singleFrameMs = singleFrameMs;
- this.realSize = realSize;
- this.smallestSize = smallestSize;
- this.largestSize = largestSize;
- this.metrics = metrics;
- }
-
- private Info(Context context) {
- this(context, context.getSystemService(DisplayManager.class)
- .getDisplay(DEFAULT_DISPLAY));
- }
-
public Info(Context context, Display display) {
id = display.getDisplayId();
+
rotation = display.getRotation();
- float refreshRate = display.getRefreshRate();
- singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
+ Configuration config = context.getResources().getConfiguration();
+ fontScale = config.fontScale;
+ densityDpi = config.densityDpi;
+ mScreenSizeDp = new Point(
+ Math.min(config.screenHeightDp, config.screenWidthDp),
+ Math.max(config.screenHeightDp, config.screenWidthDp));
+
+ singleFrameMs = getSingleFrameMs(display);
realSize = new Point();
smallestSize = new Point();
largestSize = new Point();
+
display.getRealSize(realSize);
display.getCurrentSizeRange(smallestSize, largestSize);
-
- metrics = context.getResources().getDisplayMetrics();
}
private boolean hasDifferentSize(Info info) {
@@ -307,4 +262,9 @@
return false;
}
}
+
+ private static int getSingleFrameMs(Display display) {
+ float refreshRate = display.getRefreshRate();
+ return refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
+ }
}
diff --git a/src/com/android/launcher3/util/EdgeEffectCompat.java b/src/com/android/launcher3/util/EdgeEffectCompat.java
new file mode 100644
index 0000000..491582b
--- /dev/null
+++ b/src/com/android/launcher3/util/EdgeEffectCompat.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.content.Context;
+import android.widget.EdgeEffect;
+
+import com.android.launcher3.Utilities;
+
+/**
+ * Extension of {@link EdgeEffect} to allow backwards compatibility
+ */
+public class EdgeEffectCompat extends EdgeEffect {
+
+ public EdgeEffectCompat(Context context) {
+ super(context);
+ }
+
+ @Override
+ public float getDistance() {
+ return Utilities.ATLEAST_S ? super.getDistance() : 0;
+ }
+
+ @Override
+ public float onPullDistance(float deltaDistance, float displacement) {
+ if (Utilities.ATLEAST_S) {
+ return super.onPullDistance(deltaDistance, displacement);
+ } else {
+ onPull(deltaDistance, displacement);
+ return deltaDistance;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/util/IOUtils.java b/src/com/android/launcher3/util/IOUtils.java
index 1cec0ec..d7fa905 100644
--- a/src/com/android/launcher3/util/IOUtils.java
+++ b/src/com/android/launcher3/util/IOUtils.java
@@ -16,7 +16,9 @@
package com.android.launcher3.util;
+import android.graphics.Bitmap;
import android.os.FileUtils;
+import android.util.Base64;
import android.util.Log;
import com.android.launcher3.Utilities;
@@ -50,6 +52,12 @@
return out.toByteArray();
}
+ public static String toBase64String(Bitmap bitmap) {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
+ return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
+ }
+
public static long copy(InputStream from, OutputStream to) throws IOException {
if (Utilities.ATLEAST_Q) {
return FileUtils.copy(from, to);
diff --git a/src/com/android/launcher3/util/ObjectWrapper.java b/src/com/android/launcher3/util/ObjectWrapper.java
index e5b4707..a715821 100644
--- a/src/com/android/launcher3/util/ObjectWrapper.java
+++ b/src/com/android/launcher3/util/ObjectWrapper.java
@@ -42,4 +42,11 @@
public static IBinder wrap(Object obj) {
return new ObjectWrapper<>(obj);
}
+
+ public static <T> T unwrap(IBinder binder) {
+ if (binder instanceof ObjectWrapper) {
+ return ((ObjectWrapper<T>) binder).get();
+ }
+ return null;
+ }
}
diff --git a/src/com/android/launcher3/util/OverScroller.java b/src/com/android/launcher3/util/OverScroller.java
deleted file mode 100644
index 87e6986..0000000
--- a/src/com/android/launcher3/util/OverScroller.java
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import static com.android.launcher3.anim.Interpolators.SCROLL;
-
-import android.animation.TimeInterpolator;
-import android.content.Context;
-import android.hardware.SensorManager;
-import android.util.Log;
-import android.view.ViewConfiguration;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-import androidx.dynamicanimation.animation.FloatPropertyCompat;
-import androidx.dynamicanimation.animation.SpringAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
-
-import com.android.launcher3.R;
-import com.android.systemui.plugins.ResourceProvider;
-
-/**
- * Based on {@link android.widget.OverScroller} supporting only 1-d scrolling and with more
- * customization options.
- */
-public class OverScroller {
- private int mMode;
-
- private final SplineOverScroller mScroller;
-
- private TimeInterpolator mInterpolator;
-
- private final boolean mFlywheel;
-
- private static final int DEFAULT_DURATION = 250;
- private static final int SCROLL_MODE = 0;
- private static final int FLING_MODE = 1;
-
- /**
- * Creates an OverScroller with a viscous fluid scroll interpolator and flywheel.
- * @param context
- */
- public OverScroller(Context context) {
- this(context, null);
- }
-
- /**
- * Creates an OverScroller with flywheel enabled.
- * @param context The context of this application.
- * @param interpolator The scroll interpolator. If null, a default (viscous) interpolator will
- * be used.
- */
- public OverScroller(Context context, Interpolator interpolator) {
- this(context, interpolator, true);
- }
-
- /**
- * Creates an OverScroller.
- * @param context The context of this application.
- * @param interpolator The scroll interpolator. If null, a default (viscous) interpolator will
- * be used.
- * @param flywheel If true, successive fling motions will keep on increasing scroll speed.
- */
- public OverScroller(Context context, Interpolator interpolator, boolean flywheel) {
- if (interpolator == null) {
- mInterpolator = SCROLL;
- } else {
- mInterpolator = interpolator;
- }
- mFlywheel = flywheel;
- mScroller = new SplineOverScroller(context);
- }
-
- public void setInterpolator(TimeInterpolator interpolator) {
- if (interpolator == null) {
- mInterpolator = SCROLL;
- } else {
- mInterpolator = interpolator;
- }
- }
-
- /**
- * The amount of friction applied to flings. The default value
- * is {@link ViewConfiguration#getScrollFriction}.
- *
- * @param friction A scalar dimension-less value representing the coefficient of
- * friction.
- */
- public final void setFriction(float friction) {
- mScroller.setFriction(friction);
- }
-
- /**
- *
- * Returns whether the scroller has finished scrolling.
- *
- * @return True if the scroller has finished scrolling, false otherwise.
- */
- public final boolean isFinished() {
- return mScroller.mFinished;
- }
-
- /**
- * Force the finished field to a particular value. Contrary to
- * {@link #abortAnimation()}, forcing the animation to finished
- * does NOT cause the scroller to move to the final x and y
- * position.
- *
- * @param finished The new finished value.
- */
- public final void forceFinished(boolean finished) {
- mScroller.mFinished = finished;
- }
-
- /**
- * Returns the current offset in the scroll.
- *
- * @return The new offset as an absolute distance from the origin.
- */
- public final int getCurrPos() {
- return mScroller.mCurrentPosition;
- }
-
- /**
- * Returns the absolute value of the current velocity.
- *
- * @return The original velocity less the deceleration, norm of the X and Y velocity vector.
- */
- public float getCurrVelocity() {
- return mScroller.mCurrVelocity;
- }
-
- /**
- * Returns the start offset in the scroll.
- *
- * @return The start offset as an absolute distance from the origin.
- */
- public final int getStartPos() {
- return mScroller.mStart;
- }
-
- /**
- * Returns where the scroll will end. Valid only for "fling" scrolls.
- *
- * @return The final offset as an absolute distance from the origin.
- */
- public final int getFinalPos() {
- return mScroller.mFinal;
- }
-
- /**
- * Returns how long the scroll event will take, in milliseconds.
- *
- * Note that if mScroller.mState == SPRING, this duration is ignored, so can only
- * serve as an estimate for how long the spring-controlled scroll will take.
- *
- * @return The duration of the scroll in milliseconds.
- */
- public final int getDuration() {
- return mScroller.mDuration;
- }
-
- /**
- * Extend the scroll animation. This allows a running animation to scroll
- * further and longer, when used with {@link #setFinalPos(int)}.
- *
- * @param extend Additional time to scroll in milliseconds.
- * @see #setFinalPos(int)
- */
- public void extendDuration(int extend) {
- mScroller.extendDuration(extend);
- }
-
- /**
- * Sets the final position for this scroller.
- *
- * @param newPos The new offset as an absolute distance from the origin.
- * @see #extendDuration(int)
- */
- public void setFinalPos(int newPos) {
- mScroller.setFinalPosition(newPos);
- }
-
- /**
- * Call this when you want to know the new location. If it returns true, the
- * animation is not yet finished.
- */
- public boolean computeScrollOffset() {
- if (isFinished()) {
- return false;
- }
-
- switch (mMode) {
- case SCROLL_MODE:
- if (isSpringing()) {
- return true;
- }
- long time = AnimationUtils.currentAnimationTimeMillis();
- // Any scroller can be used for time, since they were started
- // together in scroll mode. We use X here.
- final long elapsedTime = time - mScroller.mStartTime;
-
- final int duration = mScroller.mDuration;
- if (elapsedTime < duration) {
- final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
- mScroller.updateScroll(q);
- } else {
- abortAnimation();
- }
- break;
-
- case FLING_MODE:
- if (!mScroller.mFinished) {
- if (!mScroller.update()) {
- if (!mScroller.continueWhenFinished()) {
- mScroller.finish();
- }
- }
- }
-
- break;
- }
-
- return true;
- }
-
- /**
- * Start scrolling by providing a starting point and the distance to travel.
- * The scroll will use the default value of 250 milliseconds for the
- * duration.
- *
- * @param start Starting horizontal scroll offset in pixels. Positive
- * numbers will scroll the content to the left.
- * @param delta Distance to travel. Positive numbers will scroll the
- * content to the left.
- */
- public void startScroll(int start, int delta) {
- startScroll(start, delta, DEFAULT_DURATION);
- }
-
- /**
- * Start scrolling by providing a starting point and the distance to travel.
- *
- * @param start Starting scroll offset in pixels. Positive
- * numbers will scroll the content to the left.
- * @param delta Distance to travel. Positive numbers will scroll the
- * content to the left.
- * @param duration Duration of the scroll in milliseconds.
- */
- public void startScroll(int start, int delta, int duration) {
- mMode = SCROLL_MODE;
- mScroller.startScroll(start, delta, duration);
- }
-
- /**
- * Start scrolling using a spring by providing a starting point and the distance to travel.
- *
- * @param start Starting scroll offset in pixels. Positive
- * numbers will scroll the content to the left.
- * @param delta Distance to travel. Positive numbers will scroll the
- * content to the left.
- * @param duration Duration of the scroll in milliseconds.
- * @param velocity The starting velocity for the spring in px per ms.
- */
- public void startScrollSpring(int start, int delta, int duration, float velocity) {
- mMode = SCROLL_MODE;
- mScroller.mState = mScroller.SPRING;
- mScroller.startScroll(start, delta, duration, velocity);
- }
-
- /**
- * Call this when you want to 'spring back' into a valid coordinate range.
- *
- * @param start Starting X coordinate
- * @param min Minimum valid X value
- * @param max Maximum valid X value
- * @return true if a springback was initiated, false if startX and startY were
- * already within the valid range.
- */
- public boolean springBack(int start, int min, int max) {
- mMode = FLING_MODE;
- return mScroller.springback(start, min, max);
- }
-
- public void fling(int start, int velocity, int min, int max) {
- fling(start, velocity, min, max, 0);
- }
-
- /**
- * Start scrolling based on a fling gesture. The distance traveled will
- * depend on the initial velocity of the fling.
- * @param start Starting point of the scroll (X)
- * @param velocity Initial velocity of the fling (X) measured in pixels per
- * second.
- * @param min Minimum X value. The scroller will not scroll past this point
- * unless overX > 0. If overfling is allowed, it will use minX as
- * a springback boundary.
- * @param max Maximum X value. The scroller will not scroll past this point
-* unless overX > 0. If overfling is allowed, it will use maxX as
-* a springback boundary.
- * @param over Overfling range. If > 0, horizontal overfling in either
-* direction will be possible.
- */
- public void fling(int start, int velocity, int min, int max, int over) {
- // Continue a scroll or fling in progress
- if (mFlywheel && !isFinished()) {
- float oldVelocityX = mScroller.mCurrVelocity;
- if (Math.signum(velocity) == Math.signum(oldVelocityX)) {
- velocity += oldVelocityX;
- }
- }
-
- mMode = FLING_MODE;
- mScroller.fling(start, velocity, min, max, over);
- }
-
- /**
- * Notify the scroller that we've reached a horizontal boundary.
- * Normally the information to handle this will already be known
- * when the animation is started, such as in a call to one of the
- * fling functions. However there are cases where this cannot be known
- * in advance. This function will transition the current motion and
- * animate from startX to finalX as appropriate.
- * @param start Starting/current X position
- * @param finalPos Desired final X position
- * @param over Magnitude of overscroll allowed. This should be the maximum
- */
- public void notifyEdgeReached(int start, int finalPos, int over) {
- mScroller.notifyEdgeReached(start, finalPos, over);
- }
-
- /**
- * Returns whether the current Scroller is currently returning to a valid position.
- * Valid bounds were provided by the
- * {@link #fling(int, int, int, int, int)} method.
- *
- * One should check this value before calling
- * {@link #startScroll(int, int)} as the interpolation currently in progress
- * to restore a valid position will then be stopped. The caller has to take into account
- * the fact that the started scroll will start from an overscrolled position.
- *
- * @return true when the current position is overscrolled and in the process of
- * interpolating back to a valid value.
- */
- public boolean isOverScrolled() {
- return (!mScroller.mFinished && mScroller.mState != SplineOverScroller.SPLINE);
- }
-
- /**
- * Stops the animation. Contrary to {@link #forceFinished(boolean)},
- * aborting the animating causes the scroller to move to the final x and y
- * positions.
- *
- * @see #forceFinished(boolean)
- */
- public void abortAnimation() {
- mScroller.finish();
- }
-
- /**
- * Returns the time elapsed since the beginning of the scrolling.
- *
- * @return The elapsed time in milliseconds.
- *
- * @hide
- */
- public int timePassed() {
- final long time = AnimationUtils.currentAnimationTimeMillis();
- return (int) (time - mScroller.mStartTime);
- }
-
- public boolean isSpringing() {
- return mScroller.mState == SplineOverScroller.SPRING && !isFinished();
- }
-
- static class SplineOverScroller {
- // Initial position
- private int mStart;
-
- // Current position
- private int mCurrentPosition;
-
- // Final position
- private int mFinal;
-
- // Initial velocity
- private int mVelocity;
-
- // Current velocity
- private float mCurrVelocity;
-
- // Constant current deceleration
- private float mDeceleration;
-
- // Animation starting time, in system milliseconds
- private long mStartTime;
-
- // Animation duration, in milliseconds
- private int mDuration;
-
- // Duration to complete spline component of animation
- private int mSplineDuration;
-
- // Distance to travel along spline animation
- private int mSplineDistance;
-
- // Whether the animation is currently in progress
- private boolean mFinished;
-
- // The allowed overshot distance before boundary is reached.
- private int mOver;
-
- // Fling friction
- private float mFlingFriction = ViewConfiguration.getScrollFriction();
-
- // Current state of the animation.
- private int mState = SPLINE;
-
- private Context mContext;
- private SpringAnimation mSpring;
-
- // Constant gravity value, used in the deceleration phase.
- private static final float GRAVITY = 2000.0f;
-
- // A context-specific coefficient adjusted to physical values.
- private float mPhysicalCoeff;
-
- private static float DECELERATION_RATE = (float) (Math.log(0.78) / Math.log(0.9));
- private static final float INFLEXION = 0.35f; // Tension lines cross at (INFLEXION, 1)
- private static final float START_TENSION = 0.5f;
- private static final float END_TENSION = 1.0f;
- private static final float P1 = START_TENSION * INFLEXION;
- private static final float P2 = 1.0f - END_TENSION * (1.0f - INFLEXION);
-
- private static final int NB_SAMPLES = 100;
- private static final float[] SPLINE_POSITION = new float[NB_SAMPLES + 1];
- private static final float[] SPLINE_TIME = new float[NB_SAMPLES + 1];
-
- private static final int SPLINE = 0;
- private static final int CUBIC = 1;
- private static final int BALLISTIC = 2;
- private static final int SPRING = 3;
-
- private static final FloatPropertyCompat<SplineOverScroller> SPRING_PROPERTY =
- new FloatPropertyCompat<SplineOverScroller>("splineOverScrollerSpring") {
- @Override
- public float getValue(SplineOverScroller scroller) {
- return scroller.mCurrentPosition;
- }
-
- @Override
- public void setValue(SplineOverScroller scroller, float value) {
- scroller.mCurrentPosition = (int) value;
- }
- };
-
- static {
- float x_min = 0.0f;
- float y_min = 0.0f;
- for (int i = 0; i < NB_SAMPLES; i++) {
- final float alpha = (float) i / NB_SAMPLES;
-
- float x_max = 1.0f;
- float x, tx, coef;
- while (true) {
- x = x_min + (x_max - x_min) / 2.0f;
- coef = 3.0f * x * (1.0f - x);
- tx = coef * ((1.0f - x) * P1 + x * P2) + x * x * x;
- if (Math.abs(tx - alpha) < 1E-5) break;
- if (tx > alpha) x_max = x;
- else x_min = x;
- }
- SPLINE_POSITION[i] = coef * ((1.0f - x) * START_TENSION + x) + x * x * x;
-
- float y_max = 1.0f;
- float y, dy;
- while (true) {
- y = y_min + (y_max - y_min) / 2.0f;
- coef = 3.0f * y * (1.0f - y);
- dy = coef * ((1.0f - y) * START_TENSION + y) + y * y * y;
- if (Math.abs(dy - alpha) < 1E-5) break;
- if (dy > alpha) y_max = y;
- else y_min = y;
- }
- SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
- }
- SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
- }
-
- void setFriction(float friction) {
- mFlingFriction = friction;
- }
-
- SplineOverScroller(Context context) {
- mContext = context;
- mFinished = true;
- final float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
- mPhysicalCoeff = SensorManager.GRAVITY_EARTH // g (m/s^2)
- * 39.37f // inch/meter
- * ppi
- * 0.84f; // look and feel tuning
- }
-
- void updateScroll(float q) {
- if (mState == SPRING) {
- return;
- }
- mCurrentPosition = mStart + Math.round(q * (mFinal - mStart));
- }
-
- /*
- * Get a signed deceleration that will reduce the velocity.
- */
- static private float getDeceleration(int velocity) {
- return velocity > 0 ? -GRAVITY : GRAVITY;
- }
-
- /*
- * Modifies mDuration to the duration it takes to get from start to newFinal using the
- * spline interpolation. The previous duration was needed to get to oldFinal.
- */
- private void adjustDuration(int start, int oldFinal, int newFinal) {
- final int oldDistance = oldFinal - start;
- final int newDistance = newFinal - start;
- final float x = Math.abs((float) newDistance / oldDistance);
- final int index = (int) (NB_SAMPLES * x);
- if (index < NB_SAMPLES) {
- final float x_inf = (float) index / NB_SAMPLES;
- final float x_sup = (float) (index + 1) / NB_SAMPLES;
- final float t_inf = SPLINE_TIME[index];
- final float t_sup = SPLINE_TIME[index + 1];
- final float timeCoef = t_inf + (x - x_inf) / (x_sup - x_inf) * (t_sup - t_inf);
- mDuration *= timeCoef;
- }
- }
-
- void startScroll(int start, int distance, int duration) {
- startScroll(start, distance, duration, 0);
- }
-
- void startScroll(int start, int distance, int duration, float velocity) {
- mFinished = false;
-
- mCurrentPosition = mStart = start;
- mFinal = start + distance;
-
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mDuration = duration;
-
- if (mSpring != null) {
- mSpring.cancel();
- }
-
- if (mState == SPRING) {
- mSpring = new SpringAnimation(this, SPRING_PROPERTY);
-
- ResourceProvider rp = DynamicResource.provider(mContext);
- float stiffness = rp.getFloat(R.dimen.horizontal_spring_stiffness);
- float damping = rp.getFloat(R.dimen.horizontal_spring_damping_ratio);
- mSpring.setSpring(new SpringForce(mFinal)
- .setStiffness(stiffness)
- .setDampingRatio(damping));
- mSpring.setStartVelocity(velocity);
- mSpring.animateToFinalPosition(mFinal);
- mSpring.addEndListener((animation, canceled, value, velocity1) -> {
- mSpring = null;
- finish();
- mState = SPLINE;
- });
- }
- // Unused
- mDeceleration = 0.0f;
- mVelocity = 0;
- }
-
- void finish() {
- if (mSpring != null && mSpring.isRunning()) mSpring.cancel();
-
- mCurrentPosition = mFinal;
- // Not reset since WebView relies on this value for fast fling.
- // TODO: restore when WebView uses the fast fling implemented in this class.
- // mCurrVelocity = 0.0f;
- mFinished = true;
- }
-
- void setFinalPosition(int position) {
- mFinal = position;
- if (mState == SPRING && mSpring != null) {
- mSpring.animateToFinalPosition(mFinal);
- }
- mSplineDistance = mFinal - mStart;
- mFinished = false;
- }
-
- void extendDuration(int extend) {
- final long time = AnimationUtils.currentAnimationTimeMillis();
- final int elapsedTime = (int) (time - mStartTime);
- mDuration = mSplineDuration = elapsedTime + extend;
- mFinished = false;
- }
-
- boolean springback(int start, int min, int max) {
- mFinished = true;
-
- mCurrentPosition = mStart = mFinal = start;
- mVelocity = 0;
-
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mDuration = 0;
-
- if (start < min) {
- startSpringback(start, min, 0);
- } else if (start > max) {
- startSpringback(start, max, 0);
- }
-
- return !mFinished;
- }
-
- private void startSpringback(int start, int end, int velocity) {
- // mStartTime has been set
- mFinished = false;
- mState = CUBIC;
- mCurrentPosition = mStart = start;
- mFinal = end;
- final int delta = start - end;
- mDeceleration = getDeceleration(delta);
- // TODO take velocity into account
- mVelocity = -delta; // only sign is used
- mOver = Math.abs(delta);
- mDuration = (int) (1000.0 * Math.sqrt(-2.0 * delta / mDeceleration));
- }
-
- void fling(int start, int velocity, int min, int max, int over) {
- mOver = over;
- mFinished = false;
- mCurrVelocity = mVelocity = velocity;
- mDuration = mSplineDuration = 0;
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mCurrentPosition = mStart = start;
-
- if (start > max || start < min) {
- startAfterEdge(start, min, max, velocity);
- return;
- }
-
- mState = SPLINE;
- double totalDistance = 0.0;
-
- if (velocity != 0) {
- mDuration = mSplineDuration = getSplineFlingDuration(velocity);
- totalDistance = getSplineFlingDistance(velocity);
- }
-
- mSplineDistance = (int) (totalDistance * Math.signum(velocity));
- mFinal = start + mSplineDistance;
-
- // Clamp to a valid final position
- if (mFinal < min) {
- adjustDuration(mStart, mFinal, min);
- mFinal = min;
- }
-
- if (mFinal > max) {
- adjustDuration(mStart, mFinal, max);
- mFinal = max;
- }
- }
-
- private double getSplineDeceleration(int velocity) {
- return Math.log(INFLEXION * Math.abs(velocity) / (mFlingFriction * mPhysicalCoeff));
- }
-
- private double getSplineFlingDistance(int velocity) {
- final double l = getSplineDeceleration(velocity);
- final double decelMinusOne = DECELERATION_RATE - 1.0;
- return mFlingFriction * mPhysicalCoeff * Math.exp(DECELERATION_RATE / decelMinusOne * l);
- }
-
- /* Returns the duration, expressed in milliseconds */
- private int getSplineFlingDuration(int velocity) {
- final double l = getSplineDeceleration(velocity);
- final double decelMinusOne = DECELERATION_RATE - 1.0;
- return (int) (1000.0 * Math.exp(l / decelMinusOne));
- }
-
- private void fitOnBounceCurve(int start, int end, int velocity) {
- // Simulate a bounce that started from edge
- final float durationToApex = - velocity / mDeceleration;
- // The float cast below is necessary to avoid integer overflow.
- final float velocitySquared = (float) velocity * velocity;
- final float distanceToApex = velocitySquared / 2.0f / Math.abs(mDeceleration);
- final float distanceToEdge = Math.abs(end - start);
- final float totalDuration = (float) Math.sqrt(
- 2.0 * (distanceToApex + distanceToEdge) / Math.abs(mDeceleration));
- mStartTime -= (int) (1000.0f * (totalDuration - durationToApex));
- mCurrentPosition = mStart = end;
- mVelocity = (int) (- mDeceleration * totalDuration);
- }
-
- private void startBounceAfterEdge(int start, int end, int velocity) {
- mDeceleration = getDeceleration(velocity == 0 ? start - end : velocity);
- fitOnBounceCurve(start, end, velocity);
- onEdgeReached();
- }
-
- private void startAfterEdge(int start, int min, int max, int velocity) {
- if (start > min && start < max) {
- Log.e("OverScroller", "startAfterEdge called from a valid position");
- mFinished = true;
- return;
- }
- final boolean positive = start > max;
- final int edge = positive ? max : min;
- final int overDistance = start - edge;
- boolean keepIncreasing = overDistance * velocity >= 0;
- if (keepIncreasing) {
- // Will result in a bounce or a to_boundary depending on velocity.
- startBounceAfterEdge(start, edge, velocity);
- } else {
- final double totalDistance = getSplineFlingDistance(velocity);
- if (totalDistance > Math.abs(overDistance)) {
- fling(start, velocity, positive ? min : start, positive ? start : max, mOver);
- } else {
- startSpringback(start, edge, velocity);
- }
- }
- }
-
- void notifyEdgeReached(int start, int end, int over) {
- // mState is used to detect successive notifications
- if (mState == SPLINE) {
- mOver = over;
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- // We were in fling/scroll mode before: current velocity is such that distance to
- // edge is increasing. This ensures that startAfterEdge will not start a new fling.
- startAfterEdge(start, end, end, (int) mCurrVelocity);
- }
- }
-
- private void onEdgeReached() {
- // mStart, mVelocity and mStartTime were adjusted to their values when edge was reached.
- // The float cast below is necessary to avoid integer overflow.
- final float velocitySquared = (float) mVelocity * mVelocity;
- float distance = velocitySquared / (2.0f * Math.abs(mDeceleration));
- final float sign = Math.signum(mVelocity);
-
- if (distance > mOver) {
- // Default deceleration is not sufficient to slow us down before boundary
- mDeceleration = - sign * velocitySquared / (2.0f * mOver);
- distance = mOver;
- }
-
- mOver = (int) distance;
- mState = BALLISTIC;
- mFinal = mStart + (int) (mVelocity > 0 ? distance : -distance);
- mDuration = - (int) (1000.0f * mVelocity / mDeceleration);
- }
-
- boolean continueWhenFinished() {
- switch (mState) {
- case SPLINE:
- // Duration from start to null velocity
- if (mDuration < mSplineDuration) {
- // If the animation was clamped, we reached the edge
- mCurrentPosition = mStart = mFinal;
- // TODO Better compute speed when edge was reached
- mVelocity = (int) mCurrVelocity;
- mDeceleration = getDeceleration(mVelocity);
- mStartTime += mDuration;
- onEdgeReached();
- } else {
- // Normal stop, no need to continue
- return false;
- }
- break;
- case BALLISTIC:
- mStartTime += mDuration;
- startSpringback(mFinal, mStart, 0);
- break;
- case CUBIC:
- return false;
- }
-
- update();
- return true;
- }
-
- /*
- * Update the current position and velocity for current time. Returns
- * true if update has been done and false if animation duration has been
- * reached.
- */
- boolean update() {
- if (mState == SPRING) {
- return mFinished;
- }
-
- final long time = AnimationUtils.currentAnimationTimeMillis();
- final long currentTime = time - mStartTime;
-
- if (currentTime == 0) {
- // Skip work but report that we're still going if we have a nonzero duration.
- return mDuration > 0;
- }
- if (currentTime > mDuration) {
- return false;
- }
-
- double distance = 0.0;
- switch (mState) {
- case SPLINE: {
- final float t = (float) currentTime / mSplineDuration;
- final int index = (int) (NB_SAMPLES * t);
- float distanceCoef = 1.f;
- float velocityCoef = 0.f;
- if (index < NB_SAMPLES) {
- final float t_inf = (float) index / NB_SAMPLES;
- final float t_sup = (float) (index + 1) / NB_SAMPLES;
- final float d_inf = SPLINE_POSITION[index];
- final float d_sup = SPLINE_POSITION[index + 1];
- velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
- distanceCoef = d_inf + (t - t_inf) * velocityCoef;
- }
-
- distance = distanceCoef * mSplineDistance;
- mCurrVelocity = velocityCoef * mSplineDistance / mSplineDuration * 1000.0f;
- break;
- }
-
- case BALLISTIC: {
- final float t = currentTime / 1000.0f;
- mCurrVelocity = mVelocity + mDeceleration * t;
- distance = mVelocity * t + mDeceleration * t * t / 2.0f;
- break;
- }
-
- case CUBIC: {
- final float t = (float) (currentTime) / mDuration;
- final float t2 = t * t;
- final float sign = Math.signum(mVelocity);
- distance = sign * mOver * (3.0f * t2 - 2.0f * t * t2);
- mCurrVelocity = sign * mOver * 6.0f * (- t + t2);
- break;
- }
- }
-
- mCurrentPosition = mStart + (int) Math.round(distance);
-
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/util/OverlayEdgeEffect.java b/src/com/android/launcher3/util/OverlayEdgeEffect.java
new file mode 100644
index 0000000..8d455c6
--- /dev/null
+++ b/src/com/android/launcher3/util/OverlayEdgeEffect.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.widget.EdgeEffect;
+
+import com.android.launcher3.Utilities;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
+
+/**
+ * Extension of {@link EdgeEffect} which shows the Launcher overlay
+ */
+public class OverlayEdgeEffect extends EdgeEffectCompat {
+
+ private final LauncherOverlay mOverlay;
+ private final boolean mIsRtl;
+
+ private float mDistance;
+ private boolean mIsScrolling;
+
+ public OverlayEdgeEffect(Context context, LauncherOverlay overlay) {
+ super(context);
+ mOverlay = overlay;
+ mIsRtl = Utilities.isRtl(context.getResources());
+
+ }
+
+ @Override
+ public float getDistance() {
+ return mDistance;
+ }
+
+ public float onPullDistance(float deltaDistance, float displacement) {
+ mDistance = Math.max(0f, deltaDistance + mDistance);
+ if (!mIsScrolling) {
+ mOverlay.onScrollInteractionBegin();
+ mIsScrolling = true;
+ }
+ mOverlay.onScrollChange(mDistance, mIsRtl);
+ return mDistance > 0 ? deltaDistance : 0;
+ }
+
+ @Override
+ public void onAbsorb(int velocity) { }
+
+ @Override
+ public boolean isFinished() {
+ return mDistance <= 0;
+ }
+
+ @Override
+ public void onRelease() {
+ if (mIsScrolling) {
+ mDistance = 0;
+ mOverlay.onScrollInteractionEnd();
+ mIsScrolling = false;
+ }
+ }
+
+ @Override
+ public boolean draw(Canvas canvas) {
+ return false;
+ }
+
+ public void finish() {
+ mDistance = 0;
+ }
+}
diff --git a/src/com/android/launcher3/util/TranslateEdgeEffect.java b/src/com/android/launcher3/util/TranslateEdgeEffect.java
new file mode 100644
index 0000000..8fdc8df
--- /dev/null
+++ b/src/com/android/launcher3/util/TranslateEdgeEffect.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.RenderNode;
+import android.widget.EdgeEffect;
+
+/**
+ * Extension of {@link EdgeEffect} which translates the content instead of the default
+ * platform implementation
+ */
+@SuppressWarnings("NewApi")
+public class TranslateEdgeEffect extends EdgeEffectCompat {
+
+ private final RenderNode mNode;
+
+ public TranslateEdgeEffect(Context context) {
+ super(context);
+ mNode = new RenderNode("TranslateEdgeEffect");
+ }
+
+ @Override
+ public boolean draw(Canvas canvas) {
+ return false;
+ }
+
+ public boolean getTranslationShift(float[] out) {
+ Canvas c = mNode.beginRecording(1, 1);
+ boolean result = super.draw(c);
+ mNode.endRecording();
+
+ out[0] = getDistance();
+ return result;
+ }
+}
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
index 4e82336..a66b3f9 100644
--- a/src/com/android/launcher3/views/ClipIconView.java
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -15,10 +15,13 @@
*/
package com.android.launcher3.views;
+import static com.android.launcher3.Utilities.boundToRange;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
+import static java.lang.Math.max;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -143,10 +146,9 @@
/**
* Update the icon UI to match the provided parameters during an animation frame
*/
- public void update(RectF rect, float progress, float shapeProgressStart,
- float cornerRadius, boolean isOpening, View container,
- DeviceProfile dp, boolean isVerticalBarLayout) {
-
+ public void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
+ int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp,
+ boolean isVerticalBarLayout) {
MarginLayoutParams lp = (MarginLayoutParams) container.getLayoutParams();
float dX = mIsRtl
@@ -166,7 +168,7 @@
return;
}
- update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale,
+ update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, isOpening, scale,
minSize, lp, isVerticalBarLayout, dp);
container.setPivotX(0);
@@ -178,8 +180,8 @@
}
private void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
- boolean isOpening, float scale, float minSize, MarginLayoutParams parentLp,
- boolean isVerticalBarLayout, DeviceProfile dp) {
+ int fgIconAlpha, boolean isOpening, float scale, float minSize,
+ MarginLayoutParams parentLp, boolean isVerticalBarLayout, DeviceProfile dp) {
float dX = mIsRtl
? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
: rect.left - parentLp.getMarginStart();
@@ -187,9 +189,9 @@
// shapeRevealProgress = 1 when progress = shapeProgressStart + SHAPE_PROGRESS_DURATION
float toMax = isOpening ? 1 / SHAPE_PROGRESS_DURATION : 1f;
- float shapeRevealProgress = Utilities.boundToRange(mapToRange(
- Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax,
- LINEAR), 0, 1);
+
+ float shapeRevealProgress = boundToRange(mapToRange(max(shapeProgressStart, progress),
+ shapeProgressStart, 1f, 0, toMax, LINEAR), 0, 1);
if (isVerticalBarLayout) {
mOutline.right = (int) (rect.width() / scale);
@@ -231,6 +233,8 @@
sTmpRect.offset(diffX, diffY);
mForeground.setBounds(sTmpRect);
} else {
+ mForeground.setAlpha(fgIconAlpha);
+
// Spring the foreground relative to the icon's movement within the DragLayer.
int diffX = (int) (dX / dp.availableWidthPx * FG_TRANS_X_FACTOR);
int diffY = (int) (dY / dp.availableHeightPx * FG_TRANS_Y_FACTOR);
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 96268ce..d49320b 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -100,6 +100,8 @@
private ListenerView mListenerView;
private Runnable mFastFinishRunnable;
+ private float mIconOffsetY;
+
public FloatingIconView(Context context) {
this(context, null);
}
@@ -136,16 +138,18 @@
/**
* Positions this view to match the size and location of {@param rect}.
- * @param alpha The alpha to set this view.
+ * @param alpha The alpha[0, 1] of the entire floating view.
+ * @param fgIconAlpha The alpha[0-255] of the foreground layer of the icon (if applicable).
* @param progress A value from [0, 1] that represents the animation progress.
* @param shapeProgressStart The progress value at which to start the shape reveal.
* @param cornerRadius The corner radius of {@param rect}.
+ * @param isOpening True if view is used for app open animation, false for app close animation.
*/
- public void update(RectF rect, float alpha, float progress, float shapeProgressStart,
- float cornerRadius, boolean isOpening) {
+ public void update(float alpha, int fgIconAlpha, RectF rect, float progress,
+ float shapeProgressStart, float cornerRadius, boolean isOpening) {
setAlpha(alpha);
- mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, isOpening,
- this, mLauncher.getDeviceProfile(), mIsVerticalBarLayout);
+ mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha,
+ isOpening, this, mLauncher.getDeviceProfile(), mIsVerticalBarLayout);
}
@Override
@@ -478,11 +482,19 @@
@Override
public void onAnimationRepeat(Animator animator) {}
+ /**
+ * Offsets and updates the position of this view by {@param y}.
+ */
+ public void setPositionOffsetY(float y) {
+ mIconOffsetY = y;
+ onGlobalLayout();
+ }
+
@Override
public void onGlobalLayout() {
- if (mOriginalIcon.isAttachedToWindow() && mPositionOut != null) {
- getLocationBoundsForView(mLauncher, mOriginalIcon, mIsOpening,
- sTmpRectF);
+ if (mOriginalIcon != null && mOriginalIcon.isAttachedToWindow() && mPositionOut != null) {
+ getLocationBoundsForView(mLauncher, mOriginalIcon, mIsOpening, sTmpRectF);
+ sTmpRectF.offset(0, mIconOffsetY);
if (!sTmpRectF.equals(mPositionOut)) {
updatePosition(sTmpRectF, (InsettableFrameLayout.LayoutParams) getLayoutParams());
if (mOnTargetChangeRunnable != null) {
@@ -617,6 +629,7 @@
mClipIconView.recycle();
mBtvDrawable.setBackground(null);
mFastFinishRunnable = null;
+ mIconOffsetY = 0;
}
private static class IconLoadResult {
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 011f6de..e2e3be7 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -97,7 +97,7 @@
// Remove after some time, to avoid flickering
Executors.MAIN_EXECUTOR.getHandler().postDelayed(mRemoveViewRunnable,
- DisplayController.getDefaultDisplay(mLauncher).getInfo().singleFrameMs);
+ DisplayController.INSTANCE.get(mLauncher).getInfo().singleFrameMs);
}
private void removeViewFromParent() {
@@ -158,7 +158,7 @@
if (mContract == null) {
return;
}
- View icon = mLauncher.getWorkspace().getFirstMatchForAppClose(
+ View icon = mLauncher.getWorkspace().getFirstMatchForAppClose(-1,
mContract.componentName.getPackageName(), mContract.user);
boolean iconChanged = mIcon != icon;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index d9c9d4d..0504e74 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -186,8 +186,10 @@
* Resets any expanded widget header.
*/
public void resetExpandedHeader() {
- mWidgetsContentVisiblePackageUserKey = null;
- updateVisibleEntries();
+ if (mWidgetsContentVisiblePackageUserKey != null) {
+ mWidgetsContentVisiblePackageUserKey = null;
+ updateVisibleEntries();
+ }
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index cf935f3..ebad154 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -636,6 +636,7 @@
}
SystemClock.sleep(100);
}
+ checkForAnomaly();
fail("Launcher didn't initialize");
}