Merge "Not using stale object to diagnose stale object" into sc-v2-dev
diff --git a/Android.bp b/Android.bp
index 45d022f..43d28c9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -224,7 +224,6 @@
srcs: ["proguard.flags"],
}
-
// Library with all the dependencies for building Launcher Go
android_library {
name: "LauncherGoResLib",
@@ -253,3 +252,24 @@
},
}
+// Build rule for Quickstep library
+android_library {
+ name: "Launcher3QuickStepLib",
+ srcs: [
+ ":launcher-src-no-build-config",
+ ],
+ resource_dirs: [
+ "quickstep/res",
+ ],
+ static_libs: [
+ "SystemUI-statsd",
+ "SystemUISharedLib",
+ "Launcher3CommonDepsLib"
+ ],
+ manifest: "quickstep/AndroidManifest.xml",
+ platform_apis: true,
+ min_sdk_version: "current",
+ lint: {
+ baseline_filename: "lint-baseline-launcher3.xml",
+ },
+}
diff --git a/Android.mk b/Android.mk
index c222f24..c1dbc53 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,42 +53,6 @@
include $(BUILD_PACKAGE)
#
-# Build rule for Quickstep library.
-#
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_AAPT2_ONLY := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- SystemUI-statsd \
- SystemUISharedLib
-ifneq (,$(wildcard frameworks/base))
- LOCAL_PRIVATE_PLATFORM_APIS := true
-else
- LOCAL_SDK_VERSION := system_current
- LOCAL_MIN_SDK_VERSION := 26
-endif
-LOCAL_MODULE := Launcher3QuickStepLib
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
-LOCAL_PRIVILEGED_MODULE := true
-LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
-
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-java-files-under, quickstep/src) \
- $(call all-java-files-under, src_shortcuts_overrides)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
-LOCAL_PROGUARD_ENABLED := disabled
-
-
-LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-#
# Build rule for Quickstep app.
#
include $(CLEAR_VARS)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8066816..c72f62d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -31,6 +31,7 @@
android:fullBackupOnly="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
+ android:debuggable="true"
android:icon="@drawable/ic_launcher_home"
android:label="@string/derived_app_name"
android:theme="@style/AppTheme"
diff --git a/quickstep/Android.bp b/quickstep/Android.bp
index 38c9919..7b3e6c4 100644
--- a/quickstep/Android.bp
+++ b/quickstep/Android.bp
@@ -26,3 +26,19 @@
path: "robolectric_tests",
srcs: ["robolectric_tests/src/**/*.java"],
}
+
+filegroup {
+ name: "launcher3-quickstep-tests-src",
+ path: "tests",
+ srcs: ["tests/src/**/*.java"],
+}
+
+filegroup {
+ name: "launcher3-quickstep-oop-tests-src",
+ path: "tests",
+ srcs: [
+ "tests/src/com/android/quickstep/NavigationModeSwitchRule.java",
+ "tests/src/com/android/quickstep/AbstractQuickStepTest.java",
+ "tests/src/com/android/quickstep/TaplTestsQuickstep.java",
+ ]
+}
diff --git a/quickstep/res/drawable/bg_overview_clear_all_button.xml b/quickstep/res/drawable/bg_overview_clear_all_button.xml
new file mode 100644
index 0000000..47cbd9f
--- /dev/null
+++ b/quickstep/res/drawable/bg_overview_clear_all_button.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<ripple android:color="?android:attr/colorControlHighlight"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <item>
+ <shape android:shape="rectangle"
+ android:tint="?colorButtonNormal">
+ <corners android:radius="18dp" />
+ <solid android:color="?androidprv:attr/colorSurface"/>
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_finger_dot.xml b/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
new file mode 100644
index 0000000..5f8aafd
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="@color/gesture_tutorial_primary_color" />
+ <size android:width="92dp" android:height="92dp"/>
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back.xml b/quickstep/res/drawable/gesture_tutorial_motion_back.xml
deleted file mode 100644
index a6860fa..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_back.xml
+++ /dev/null
@@ -1,1233 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillAlpha"
- android:startOffset="1217"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1367"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:propertyName="scaleX"
- android:startOffset="1217"
- 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:duration="283"
- android:propertyName="scaleY"
- android:startOffset="1217"
- 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_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2417"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="333"
- android:propertyName="fillAlpha"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_L_0_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1417"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1417"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1417"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="667"
- android:pathData="M 123.282,129.757C 134.28199999999998,129.757 178.282,129.757 189.282,129.757"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="217">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:pathData="M 189.282,129.757C 189.282,129.757 189.282,129.757 189.282,129.757"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="883">
- <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:duration="250"
- android:pathData="M 189.282,129.757C 178.282,129.757 134.28199999999998,129.757 123.282,129.757"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="1217">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="217"
- android:valueFrom="0"
- android:valueTo="1"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2383"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.75"
- 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:duration="967"
- android:propertyName="fillAlpha"
- android:startOffset="217"
- android:valueFrom="0.75"
- android:valueTo="0.75"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="1183"
- android:valueFrom="0.75"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c "
- android:valueTo="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
- android:valueType="pathType">
- <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:duration="583"
- android:propertyName="pathData"
- android:startOffset="217"
- android:valueFrom="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
- android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
- 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:duration="383"
- android:propertyName="pathData"
- android:startOffset="800"
- android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
- android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
- android:valueType="pathType">
- <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:duration="167"
- android:propertyName="pathData"
- android:startOffset="1183"
- android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
- android:valueTo="M0 13.5 C20.16,13.5 36.5,29.84 36.5,50 C36.5,70.16 20.16,86.5 0,86.5 C-20.16,86.5 -36.5,70.16 -36.5,50 C-36.5,29.84 -20.16,13.5 0,13.5c "
- android:valueType="pathType">
- <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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="1767"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_4_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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_3_G"
- android:pivotX="206"
- android:pivotY="446"
- android:scaleX="1"
- android:scaleY="1">
- <group android:name="_R_G_L_3_G_L_0_G">
- <group android:name="_R_G_L_3_G_L_0_G_L_0_G">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f1f3f4"
- android:fillType="nonZero"
- android:pathData=" M412 101 C412,101 412,892 412,892 C412,892 0,892 0,892 C0,892 0,101 0,101 C0,101 412,101 412,101c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M383 804 C383,816.15 373.15,826 361,826 C361,826 51,826 51,826 C38.85,826 29,816.15 29,804 C29,791.85 38.85,782 51,782 C51,782 361,782 361,782 C373.15,782 383,791.85 383,804c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M201 47 C201,47 201,75 201,75 C201,77.21 199.21,79 197,79 C197,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 197,43 197,43 C199.21,43 201,44.79 201,47c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M388 47 C388,47 388,75 388,75 C388,77.21 386.21,79 384,79 C384,79 356,79 356,79 C353.79,79 352,77.21 352,75 C352,75 352,47 352,47 C352,44.79 353.79,43 356,43 C356,43 384,43 384,43 C386.21,43 388,44.79 388,47c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M336 47 C336,47 336,75 336,75 C336,77.21 334.21,79 332,79 C332,79 304,79 304,79 C301.79,79 300,77.21 300,75 C300,75 300,47 300,47 C300,44.79 301.79,43 304,43 C304,43 332,43 332,43 C334.21,43 336,44.79 336,47c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M70 618 C70,630.15 60.15,640 48,640 C35.85,640 26,630.15 26,618 C26,605.85 35.85,596 48,596 C60.15,596 70,605.85 70,618c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M70 396 C70,408.15 60.15,418 48,418 C35.85,418 26,408.15 26,396 C26,383.85 35.85,374 48,374 C60.15,374 70,383.85 70,396c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M394 248 C394,248 394,324 394,324 C394,333.94 385.94,342 376,342 C376,342 142,342 142,342 C132.06,342 124,333.94 124,324 C124,324 124,248 124,248 C124,238.06 132.06,230 142,230 C142,230 376,230 376,230 C385.94,230 394,238.06 394,248c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M393.94 468.38 C393.94,468.38 393.94,481.5 393.94,481.5 C393.94,483.71 392.15,485.5 389.94,485.5 C389.94,485.5 303.5,485.5 303.5,485.5 C301.29,485.5 299.5,483.71 299.5,481.5 C299.5,481.5 299.5,468.38 299.5,468.38 C299.5,466.17 301.29,464.38 303.5,464.38 C303.5,464.38 389.94,464.38 389.94,464.38 C392.15,464.38 393.94,466.17 393.94,468.38c M394 468 C394,477.67 386.17,485.5 376.5,485.5 C376.5,485.5 290,485.5 290,485.5 C280.33,485.5 272.5,477.67 272.5,468 C272.5,458.34 280.33,450.5 290,450.5 C290,450.5 376.5,450.5 376.5,450.5 C386.17,450.5 394,458.34 394,468c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M394 494 C394,494 394,547 394,547 C394,549.21 392.21,551 390,551 C390,551 164,551 164,551 C161.79,551 160,549.21 160,547 C160,547 160,494 160,494 C160,491.79 161.79,490 164,490 C164,490 390,490 390,490 C392.21,490 394,491.79 394,494c M394 508 C394,508 394,545 394,545 C394,554.94 385.94,563 376,563 C376,563 142,563 142,563 C132.06,563 124,554.94 124,545 C124,545 124,508 124,508 C124,498.06 132.06,490 142,490 C142,490 376,490 376,490 C385.94,490 394,498.06 394,508c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M394 690 C394,690 394,727 394,727 C394,736.94 385.94,745 376,745 C376,745 142,745 142,745 C132.06,745 124,736.94 124,727 C124,727 124,690 124,690 C124,680.06 132.06,672 142,672 C142,672 376,672 376,672 C385.94,672 394,680.06 394,690c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M267.5 617 C267.5,626.67 259.67,634.5 250,634.5 C250,634.5 104.5,634.5 104.5,634.5 C94.84,634.5 87,626.67 87,617 C87,607.34 94.84,599.5 104.5,599.5 C104.5,599.5 250,599.5 250,599.5 C259.67,599.5 267.5,607.34 267.5,617c " />
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M299 395.5 C299,405.17 291.16,413 281.5,413 C281.5,413 104.5,413 104.5,413 C94.84,413 87,405.17 87,395.5 C87,385.84 94.84,378 104.5,378 C104.5,378 281.5,378 281.5,378 C291.16,378 299,385.84 299,395.5c " />
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_2_G"
- android:scaleY="0">
- <group
- android:name="_R_G_L_2_G_L_0_G"
- android:scaleY="0">
- <group
- android:name="_R_G_L_2_G_L_0_G_L_0_G"
- android:scaleY="0">
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M412 0 C412,0 412,892 412,892 C412,892 0,892 0,892 C0,892 0,0 0,0 C0,0 412,0 412,0c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0"
- android:fillAlpha="0"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M195 143 C195,143 195,153 195,153 C195,155.21 193.21,157 191,157 C191,157 106,157 106,157 C103.79,157 102,155.21 102,153 C102,153 102,143 102,143 C102,140.79 103.79,139 106,139 C106,139 191,139 191,139 C193.21,139 195,140.79 195,143c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M270 165 C270,165 270,173 270,173 C270,175.21 268.21,177 266,177 C266,177 106,177 106,177 C103.79,177 102,175.21 102,173 C102,173 102,165 102,165 C102,162.79 103.79,161 106,161 C106,161 266,161 266,161 C268.21,161 270,162.79 270,165c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M222 231 C222,231 222,241 222,241 C222,243.21 220.21,245 218,245 C218,245 106,245 106,245 C103.79,245 102,243.21 102,241 C102,241 102,231 102,231 C102,228.79 103.79,227 106,227 C106,227 218,227 218,227 C220.21,227 222,228.79 222,231c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M241 253 C241,253 241,261 241,261 C241,263.21 239.21,265 237,265 C237,265 106,265 106,265 C103.79,265 102,263.21 102,261 C102,261 102,253 102,253 C102,250.79 103.79,249 106,249 C106,249 237,249 237,249 C239.21,249 241,250.79 241,253c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M214 319 C214,319 214,329 214,329 C214,331.21 212.21,333 210,333 C210,333 106,333 106,333 C103.79,333 102,331.21 102,329 C102,329 102,319 102,319 C102,316.79 103.79,315 106,315 C106,315 210,315 210,315 C212.21,315 214,316.79 214,319c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M333 341 C333,341 333,349 333,349 C333,351.21 331.21,353 329,353 C329,353 106,353 106,353 C103.79,353 102,351.21 102,349 C102,349 102,341 102,341 C102,338.79 103.79,337 106,337 C106,337 329,337 329,337 C331.21,337 333,338.79 333,341c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M238 407 C238,407 238,417 238,417 C238,419.21 236.21,421 234,421 C234,421 106,421 106,421 C103.79,421 102,419.21 102,417 C102,417 102,407 102,407 C102,404.79 103.79,403 106,403 C106,403 234,403 234,403 C236.21,403 238,404.79 238,407c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M295 429 C295,429 295,437 295,437 C295,439.21 293.21,441 291,441 C291,441 106,441 106,441 C103.79,441 102,439.21 102,437 C102,437 102,429 102,429 C102,426.79 103.79,425 106,425 C106,425 291,425 291,425 C293.21,425 295,426.79 295,429c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M168 495 C168,495 168,505 168,505 C168,507.21 166.21,509 164,509 C164,509 106,509 106,509 C103.79,509 102,507.21 102,505 C102,505 102,495 102,495 C102,492.79 103.79,491 106,491 C106,491 164,491 164,491 C166.21,491 168,492.79 168,495c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M269 517 C269,517 269,525 269,525 C269,527.21 267.21,529 265,529 C265,529 106,529 106,529 C103.79,529 102,527.21 102,525 C102,525 102,517 102,517 C102,514.79 103.79,513 106,513 C106,513 265,513 265,513 C267.21,513 269,514.79 269,517c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M235 583 C235,583 235,593 235,593 C235,595.21 233.21,597 231,597 C231,597 106,597 106,597 C103.79,597 102,595.21 102,593 C102,593 102,583 102,583 C102,580.79 103.79,579 106,579 C106,579 231,579 231,579 C233.21,579 235,580.79 235,583c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M295 605 C295,605 295,613 295,613 C295,615.21 293.21,617 291,617 C291,617 106,617 106,617 C103.79,617 102,615.21 102,613 C102,613 102,605 102,605 C102,602.79 103.79,601 106,601 C106,601 291,601 291,601 C293.21,601 295,602.79 295,605c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M223 671 C223,671 223,681 223,681 C223,683.21 221.21,685 219,685 C219,685 106,685 106,685 C103.79,685 102,683.21 102,681 C102,681 102,671 102,671 C102,668.79 103.79,667 106,667 C106,667 219,667 219,667 C221.21,667 223,668.79 223,671c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M246 693 C246,693 246,701 246,701 C246,703.21 244.21,705 242,705 C242,705 106,705 106,705 C103.79,705 102,703.21 102,701 C102,701 102,693 102,693 C102,690.79 103.79,689 106,689 C106,689 242,689 242,689 C244.21,689 246,690.79 246,693c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0"
- android:fillAlpha="0"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M388 798 C388,798 388,798 388,798 C388,813.45 375.45,826 360,826 C360,826 267,826 267,826 C251.55,826 239,813.45 239,798 C239,798 239,798 239,798 C239,782.55 251.55,770 267,770 C267,770 360,770 360,770 C375.45,770 388,782.55 388,798c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0"
- android:fillAlpha="0"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M377 47 C377,47 377,75 377,75 C377,77.21 375.21,79 373,79 C373,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 373,43 373,43 C375.21,43 377,44.79 377,47c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 157 C82,172.46 69.46,185 54,185 C38.54,185 26,172.46 26,157 C26,141.54 38.54,129 54,129 C69.46,129 82,141.54 82,157c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 245 C82,260.46 69.46,273 54,273 C38.54,273 26,260.46 26,245 C26,229.54 38.54,217 54,217 C69.46,217 82,229.54 82,245c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 333 C82,348.46 69.46,361 54,361 C38.54,361 26,348.46 26,333 C26,317.54 38.54,305 54,305 C69.46,305 82,317.54 82,333c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 421 C82,436.46 69.46,449 54,449 C38.54,449 26,436.46 26,421 C26,405.54 38.54,393 54,393 C69.46,393 82,405.54 82,421c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 509 C82,524.46 69.46,537 54,537 C38.54,537 26,524.46 26,509 C26,493.54 38.54,481 54,481 C69.46,481 82,493.54 82,509c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 597 C82,612.46 69.46,625 54,625 C38.54,625 26,612.46 26,597 C26,581.54 38.54,569 54,569 C69.46,569 82,581.54 82,597c " />
- <path
- android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0"
- android:fillAlpha="0"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M82 685 C82,700.46 69.46,713 54,713 C38.54,713 26,700.46 26,685 C26,669.54 38.54,657 54,657 C69.46,657 82,669.54 82,685c " />
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_1_G"
- android:scaleY="0"
- android:translateX="-17.875"
- android:translateY="322.017">
- <group
- android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"
- android:translateX="123.282"
- android:translateY="129.757">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#3b4043"
- android:fillType="nonZero"
- android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " />
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="@color/gesture_tutorial_primary_color"
- android:fillType="nonZero"
- android:pathData=" M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c " />
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
deleted file mode 100644
index aff35c1..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
+++ /dev/null
@@ -1,1254 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="50"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="650"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="50"
- android:pathData="M 206,776C 206,776 206,776 206,776"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="700"
- android:pathData="M 206,776C 206,776 206,797 206,797"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="650">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="650"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 56,673C 56,673 56,706 56,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 156,673C 156,673 156,706 156,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 256,673C 256,673 256,706 256,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 356,673C 356,673 356,706 356,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#dadce0"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#e8eaed"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#80868b"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#80868b"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#202124"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#202124"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#3c4043"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillColor"
- android:startOffset="500"
- android:valueFrom="#bac4d6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="50"
- android:propertyName="fillColor"
- android:startOffset="633"
- android:valueFrom="#bac4d6"
- android:valueTo="#8ab4f8"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:propertyName="fillAlpha"
- android:startOffset="500"
- android:valueFrom="1"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:propertyName="pathData"
- android:startOffset="500"
- android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
- android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="500"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="850"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="217">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="500">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="467"
- android:propertyName="scaleX"
- android:startOffset="217"
- android:valueFrom="1"
- android:valueTo="0.5"
- 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:duration="467"
- android:propertyName="scaleY"
- android:startOffset="217"
- android:valueFrom="1"
- android:valueTo="0.5"
- 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_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2167"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.75"
- 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:duration="233"
- android:propertyName="fillAlpha"
- android:startOffset="217"
- android:valueFrom="0.75"
- android:valueTo="0.75"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="450"
- android:valueFrom="0.75"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
- android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
- android:valueType="pathType">
- <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:duration="433"
- android:propertyName="pathData"
- android:startOffset="217"
- android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
- android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
- 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">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="0"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2167"
- 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:duration="1367"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_3_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/fake_wallpaper_color_dark_mode"
- 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_2_G"
- android:scaleY="0">
- <group
- android:name="_R_G_L_2_G_L_4_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="776">
- <path
- android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#3c4043"
- 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:scaleY="0"
- android:translateX="56"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#8ab4f8"
- 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:scaleY="0"
- android:translateX="156"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#f28b82"
- 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:scaleY="0"
- android:translateX="256"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#fdd663"
- 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:scaleY="0"
- android:translateX="356"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#81c995"
- 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_T_1"
- android:scaleX="1"
- android:scaleY="1"
- android:translateX="206"
- android:translateY="446">
- <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:scaleX="0.87473"
- android:scaleY="0.98643"
- android:translateX="206"
- android:translateY="472.769">
- <path
- android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
- </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_0_G"
- android:translateX="182"
- android:translateY="120">
- <path
- android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
- </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:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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:fillAlpha="1"
- android:fillColor="#80868b"
- 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:fillAlpha="1"
- android:fillColor="#80868b"
- 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">
- <group
- android:name="_R_G_L_1_G_L_1_G_L_2_G"
- android:translateX="206"
- android:translateY="51">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#202124"
- 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_1_G_L_1_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#202124"
- 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_1_G_L_0_G"
- android:translateX="206"
- android:translateY="66.5">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#3c4043"
- 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_1_G_L_0_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bac4d6"
- android:fillType="nonZero"
- android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="@color/gesture_tutorial_primary_color"
- android:fillType="nonZero"
- android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
deleted file mode 100644
index 98d97ad..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
+++ /dev/null
@@ -1,1254 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="50"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="650"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="50"
- android:pathData="M 206,776C 206,776 206,776 206,776"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="700"
- android:pathData="M 206,776C 206,776 206,797 206,797"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="650">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="650"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 56,673C 56,673 56,706 56,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 156,673C 156,673 156,706 156,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 256,673C 256,673 256,706 256,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 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:duration="700"
- android:pathData="M 356,673C 356,673 356,706 356,706"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="600">
- <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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="600"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#dadce0"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_4_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#bdc1c6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#e8eaed"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#80868b"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="100"
- android:propertyName="fillColor"
- android:startOffset="400"
- android:valueFrom="#80868b"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_2_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#6e7175"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#6e7175"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.676 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillColor"
- android:startOffset="350"
- android:valueFrom="#9a9a9a"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.584 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_1_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="517"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="fillColor"
- android:startOffset="500"
- android:valueFrom="#bac4d6"
- android:valueTo="#bac4d6"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="50"
- android:propertyName="fillColor"
- android:startOffset="633"
- android:valueFrom="#bac4d6"
- android:valueTo="#8ab4f8"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:propertyName="fillAlpha"
- android:startOffset="500"
- android:valueFrom="1"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:propertyName="pathData"
- android:startOffset="500"
- android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
- android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="500"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_L_0_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="850"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="283"
- android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="217">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="500">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="467"
- android:propertyName="scaleX"
- android:startOffset="217"
- android:valueFrom="1"
- android:valueTo="0.5"
- 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:duration="467"
- android:propertyName="scaleY"
- android:startOffset="217"
- android:valueFrom="1"
- android:valueTo="0.5"
- 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_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2167"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.75"
- 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:duration="233"
- android:propertyName="fillAlpha"
- android:startOffset="217"
- android:valueFrom="0.75"
- android:valueTo="0.75"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="450"
- android:valueFrom="0.75"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
- android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
- android:valueType="pathType">
- <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:duration="433"
- android:propertyName="pathData"
- android:startOffset="217"
- android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
- android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
- 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">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="0"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2167"
- 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:duration="1367"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_3_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/fake_wallpaper_color_light_mode"
- 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_2_G"
- android:scaleY="0">
- <group
- android:name="_R_G_L_2_G_L_4_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="776">
- <path
- android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#d9d9da"
- 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:scaleY="0"
- android:translateX="56"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#8ab4f8"
- 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:scaleY="0"
- android:translateX="156"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#f28b82"
- 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:scaleY="0"
- android:translateX="256"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#fdd663"
- 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:scaleY="0"
- android:translateX="356"
- android:translateY="673">
- <path
- android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#81c995"
- 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_T_1"
- android:scaleX="1"
- android:scaleY="1"
- android:translateX="206"
- android:translateY="446">
- <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:scaleX="0.87473"
- android:scaleY="0.98643"
- android:translateX="206"
- android:translateY="472.769">
- <path
- android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
- </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:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
- </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_0_G"
- android:translateX="182"
- android:translateY="120">
- <path
- android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
- </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:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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:fillAlpha="1"
- android:fillColor="#80868b"
- 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:fillAlpha="1"
- android:fillColor="#80868b"
- 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">
- <group
- android:name="_R_G_L_1_G_L_1_G_L_2_G"
- android:translateX="206"
- android:translateY="51">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#6e7175"
- 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_1_G_L_1_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#6e7175"
- 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_1_G_L_0_G"
- android:translateX="206"
- android:translateY="66.5">
- <path
- android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9a9a9a"
- 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_1_G_L_0_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bac4d6"
- android:fillType="nonZero"
- android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#84ba69"
- android:fillType="nonZero"
- android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
deleted file mode 100644
index b007d20..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
+++ /dev/null
@@ -1,1623 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="_R_G_L_4_G_N_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="1050"
- android:pathData="M 206,446C 206,446 206,395 206,395"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="217">
- <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_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="1050"
- android:propertyName="scaleX"
- android:startOffset="217"
- 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:duration="1050"
- android:propertyName="scaleY"
- android:startOffset="217"
- 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_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- 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_0_G_L_28_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_27_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_26_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_25_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_24_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_23_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_22_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_21_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_20_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_19_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_18_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_17_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_16_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_15_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_14_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_13_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_12_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_11_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_10_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_9_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_8_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_7_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_6_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_5_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_4_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_N_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- android:valueFrom="0"
- android:valueTo="0.6"
- 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:duration="167"
- android:propertyName="scaleX"
- android:startOffset="2567"
- android:valueFrom="0"
- 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:duration="167"
- android:propertyName="scaleY"
- android:startOffset="2567"
- android:valueFrom="0"
- 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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_N_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2567"
- 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:duration="250"
- android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="1350">
- <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:duration="417"
- android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="1600">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1350"
- android:valueFrom="0"
- android:valueTo="0.6"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.75"
- 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:duration="1833"
- android:propertyName="fillAlpha"
- android:startOffset="217"
- android:valueFrom="0.75"
- android:valueTo="0.75"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="2050"
- android:valueFrom="0.75"
- android:valueTo="0"
- 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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
- android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
- android:valueType="pathType">
- <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:duration="1050"
- android:propertyName="pathData"
- android:startOffset="217"
- android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
- android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- 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:duration="783"
- android:propertyName="pathData"
- android:startOffset="1267"
- android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueType="pathType">
- <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:duration="167"
- android:propertyName="pathData"
- android:startOffset="2050"
- android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
- android:valueType="pathType">
- <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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="2750"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_5_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/fake_wallpaper_color_dark_mode"
- 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_4_G_N_3_T_0"
- android:scaleX="1"
- android:scaleY="1"
- android:translateX="206"
- android:translateY="446">
- <group
- android:name="_R_G_L_4_G"
- android:translateX="-206"
- android:translateY="-446">
- <group android:name="_R_G_L_4_G_L_0_G">
- <group
- android:name="_R_G_L_4_G_L_0_G_L_28_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_28_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#000000"
- android:fillType="nonZero"
- android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_27_G"
- android:translateX="206"
- android:translateY="422.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_26_G"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_25_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_24_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_23_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_22_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_21_G"
- android:translateX="148.5"
- android:translateY="148">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_20_G"
- android:translateX="186"
- android:translateY="169">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_19_G"
- android:translateX="54"
- android:translateY="245">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_18_G"
- android:translateX="162"
- android:translateY="236">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_17_G"
- android:translateX="171.5"
- android:translateY="257">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_16_G"
- android:translateX="54"
- android:translateY="333">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_15_G"
- android:translateX="158"
- android:translateY="324">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_14_G"
- android:translateX="217.5"
- android:translateY="345">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_13_G"
- android:translateX="54"
- android:translateY="421">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_12_G"
- android:translateX="170"
- android:translateY="412">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_11_G"
- android:translateX="198.5"
- android:translateY="433">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_10_G"
- android:translateX="54"
- android:translateY="509">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_9_G"
- android:translateX="135"
- android:translateY="500">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_8_G"
- android:translateX="185.5"
- android:translateY="521">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_7_G"
- android:translateX="54"
- android:translateY="597">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_6_G"
- android:translateX="168.5"
- android:translateY="588">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_5_G"
- android:translateX="198.5"
- android:translateY="609">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_4_G"
- android:translateX="54"
- android:translateY="685">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_3_G"
- android:translateX="162.5"
- android:translateY="676">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_2_G"
- android:translateX="174"
- android:translateY="697">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_1_G"
- android:translateX="313.5"
- android:translateY="798">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_0_G"
- android:translateX="205.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
- </group>
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_3_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_3_G"
- android:translateX="-206"
- android:translateY="-446">
- <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_28_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_28_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#000000"
- android:fillType="nonZero"
- android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_27_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="422.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_26_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_25_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_24_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_23_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_22_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_21_G"
- android:scaleY="0"
- android:translateX="148.5"
- android:translateY="148">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_20_G"
- android:scaleY="0"
- android:translateX="186"
- android:translateY="169">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_19_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="245">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_18_G"
- android:scaleY="0"
- android:translateX="162"
- android:translateY="236">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_17_G"
- android:scaleY="0"
- android:translateX="171.5"
- android:translateY="257">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_16_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="333">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_15_G"
- android:scaleY="0"
- android:translateX="158"
- android:translateY="324">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_14_G"
- android:scaleY="0"
- android:translateX="217.5"
- android:translateY="345">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_13_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="421">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_12_G"
- android:scaleY="0"
- android:translateX="170"
- android:translateY="412">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_11_G"
- android:scaleY="0"
- android:translateX="198.5"
- android:translateY="433">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_10_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="509">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_9_G"
- android:scaleY="0"
- android:translateX="135"
- android:translateY="500">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_8_G"
- android:scaleY="0"
- android:translateX="185.5"
- android:translateY="521">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_7_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="597">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_6_G"
- android:scaleY="0"
- android:translateX="168.5"
- android:translateY="588">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_5_G"
- android:scaleY="0"
- android:translateX="198.5"
- android:translateY="609">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_4_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="685">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_3_G"
- android:scaleY="0"
- android:translateX="162.5"
- android:translateY="676">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_2_G"
- android:scaleY="0"
- android:translateX="174"
- android:translateY="697">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_1_G"
- android:scaleY="0"
- android:translateX="313.5"
- android:translateY="798">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_0_G"
- android:scaleY="0"
- android:translateX="205.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
- </group>
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_2_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_2_G"
- android:scaleX="1.3767699999999998"
- android:scaleY="1.3767699999999998"
- android:translateY="-508.163">
- <group
- android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
- android:scaleX="0"
- android:scaleY="0">
- <path
- android:name="_R_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- 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>
- <group
- android:name="_R_G_L_1_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_1_G"
- android:scaleX="1.39"
- android:scaleY="1.39"
- android:translateX="-556.176"
- android:translateY="-7.307">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
- android:fillType="nonZero"
- android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="@color/gesture_tutorial_primary_color"
- android:fillType="nonZero"
- android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/res/drawable/gesture_tutorial_ripple.xml b/quickstep/res/drawable/gesture_tutorial_ripple.xml
similarity index 100%
rename from res/drawable/gesture_tutorial_ripple.xml
rename to quickstep/res/drawable/gesture_tutorial_ripple.xml
diff --git a/quickstep/res/drawable/mock_conversation.xml b/quickstep/res/drawable/mock_conversation.xml
deleted file mode 100644
index 272d9ed..0000000
--- a/quickstep/res/drawable/mock_conversation.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="83"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_1_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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_0_G"
- android:pivotX="206"
- android:pivotY="446"
- android:scaleX="1"
- android:scaleY="1">
- <group android:name="_R_G_L_0_G_L_0_G">
- <group
- android:name="_R_G_L_0_G_L_0_G_L_14_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#000000"
- android:fillType="nonZero"
- android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_13_G"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f1f3f4"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_12_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_0_G_L_0_G_L_11_G"
- android:translateX="206"
- android:translateY="804">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M177 0 C177,12.15 167.15,22 155,22 C155,22 -155,22 -155,22 C-167.15,22 -177,12.15 -177,0 C-177,-12.15 -167.15,-22 -155,-22 C-155,-22 155,-22 155,-22 C167.15,-22 177,-12.15 177,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_10_G"
- android:translateX="117.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M83.5 -14 C83.5,-14 83.5,14 83.5,14 C83.5,16.21 81.71,18 79.5,18 C79.5,18 -79.5,18 -79.5,18 C-81.71,18 -83.5,16.21 -83.5,14 C-83.5,14 -83.5,-14 -83.5,-14 C-83.5,-16.21 -81.71,-18 -79.5,-18 C-79.5,-18 79.5,-18 79.5,-18 C81.71,-18 83.5,-16.21 83.5,-14c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_9_G"
- android:translateX="370"
- android:translateY="61">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_8_G"
- android:translateX="318"
- android:translateY="61">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_7_G"
- android:translateX="48"
- android:translateY="618">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_6_G"
- android:translateX="48"
- android:translateY="396">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_5_G"
- android:translateX="259"
- android:translateY="286">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M135 -38 C135,-38 135,38 135,38 C135,47.94 126.94,56 117,56 C117,56 -117,56 -117,56 C-126.94,56 -135,47.94 -135,38 C-135,38 -135,-38 -135,-38 C-135,-47.94 -126.94,-56 -117,-56 C-117,-56 117,-56 117,-56 C126.94,-56 135,-47.94 135,-38c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_4_G"
- android:translateX="259"
- android:translateY="468">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M134.5 4 C134.5,4 134.5,14 134.5,14 C134.5,16.21 132.71,18 130.5,18 C130.5,18 44.5,18 44.5,18 C42.29,18 40.5,16.21 40.5,14 C40.5,14 40.5,4 40.5,4 C40.5,1.79 42.29,0 44.5,0 C44.5,0 130.5,0 130.5,0 C132.71,0 134.5,1.79 134.5,4c M135 0 C135,9.66 127.17,17.5 117.5,17.5 C117.5,17.5 31,17.5 31,17.5 C21.34,17.5 13.5,9.66 13.5,0 C13.5,-9.66 21.34,-17.5 31,-17.5 C31,-17.5 117.5,-17.5 117.5,-17.5 C127.17,-17.5 135,-9.66 135,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_3_G"
- android:translateX="259"
- android:translateY="526.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M135 -32.5 C135,-32.5 135,20.5 135,20.5 C135,22.71 133.21,24.5 131,24.5 C131,24.5 -95,24.5 -95,24.5 C-97.21,24.5 -99,22.71 -99,20.5 C-99,20.5 -99,-32.5 -99,-32.5 C-99,-34.71 -97.21,-36.5 -95,-36.5 C-95,-36.5 131,-36.5 131,-36.5 C133.21,-36.5 135,-34.71 135,-32.5c M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_2_G"
- android:translateX="259"
- android:translateY="708.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_1_G"
- android:translateX="222"
- android:translateY="617">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M45.5 0 C45.5,9.66 37.67,17.5 28,17.5 C28,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 28,-17.5 28,-17.5 C37.67,-17.5 45.5,-9.66 45.5,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_0_G"
- android:translateX="222"
- android:translateY="395.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M77 0 C77,9.66 69.16,17.5 59.5,17.5 C59.5,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 59.5,-17.5 59.5,-17.5 C69.16,-17.5 77,-9.66 77,0c " />
- </group>
- </group>
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_conversations_list.xml b/quickstep/res/drawable/mock_conversations_list.xml
deleted file mode 100644
index 2dbc88f..0000000
--- a/quickstep/res/drawable/mock_conversations_list.xml
+++ /dev/null
@@ -1,361 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="83"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_1_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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_0_G">
- <group android:name="_R_G_L_0_G_L_0_G">
- <group
- android:name="_R_G_L_0_G_L_0_G_L_28_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_28_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#000000"
- android:fillType="nonZero"
- android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_27_G"
- android:translateX="206"
- android:translateY="422.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_27_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_26_G"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_26_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_25_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_25_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_24_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_24_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_0_G_L_0_G_L_23_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_23_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_22_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_22_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_21_G"
- android:translateX="148.5"
- android:translateY="148">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_21_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_20_G"
- android:translateX="186"
- android:translateY="169">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_20_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_19_G"
- android:translateX="54"
- android:translateY="245">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_19_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_18_G"
- android:translateX="162"
- android:translateY="236">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_18_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_17_G"
- android:translateX="171.5"
- android:translateY="257">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_17_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_16_G"
- android:translateX="54"
- android:translateY="333">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_16_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_15_G"
- android:translateX="158"
- android:translateY="324">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_15_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_14_G"
- android:translateX="217.5"
- android:translateY="345">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_13_G"
- android:translateX="54"
- android:translateY="421">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_12_G"
- android:translateX="170"
- android:translateY="412">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_11_G"
- android:translateX="198.5"
- android:translateY="433">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_10_G"
- android:translateX="54"
- android:translateY="509">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_9_G"
- android:translateX="135"
- android:translateY="500">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_8_G"
- android:translateX="185.5"
- android:translateY="521">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_7_G"
- android:translateX="54"
- android:translateY="597">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_6_G"
- android:translateX="168.5"
- android:translateY="588">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_5_G"
- android:translateX="198.5"
- android:translateY="609">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_4_G"
- android:translateX="54"
- android:translateY="685">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_3_G"
- android:translateX="162.5"
- android:translateY="676">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_2_G"
- android:translateX="174"
- android:translateY="697">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_1_G"
- android:translateX="313.5"
- android:translateY="798">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_0_G_L_0_G"
- android:translateX="205.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
- </group>
- </group>
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_dark_mode.xml b/quickstep/res/drawable/mock_webpage_dark_mode.xml
deleted file mode 100644
index 93b22b7..0000000
--- a/quickstep/res/drawable/mock_webpage_dark_mode.xml
+++ /dev/null
@@ -1,251 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="83"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group android:name="_R_G_L_0_G">
- <group android:name="_R_G_L_0_G_L_3_G">
- <group
- android:name="_R_G_L_0_G_L_3_G_L_11_G"
- android:scaleX="0.87473"
- android:scaleY="0.98643"
- android:translateX="206"
- android:translateY="472.769">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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_0_G_L_3_G_L_10_G"
- android:translateX="182.5"
- android:translateY="831">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_9_G"
- android:translateX="186"
- android:translateY="801">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_8_G"
- android:translateX="119"
- android:translateY="755">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_7_G"
- android:translateX="182.5"
- android:translateY="725">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_6_G"
- android:translateX="197.5"
- android:translateY="695">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_5_G"
- android:translateX="192"
- android:translateY="665">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_4_G"
- android:translateX="105.5"
- android:translateY="360">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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_0_G_L_3_G_L_3_G"
- android:translateX="47.5"
- android:translateY="360">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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_0_G_L_3_G_L_2_G"
- android:translateX="142.5"
- android:translateY="328">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_1_G"
- android:translateX="186"
- android:translateY="284">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G_L_0_G"
- android:translateX="155"
- android:translateY="240">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G_L_2_G"
- android:translateX="24"
- android:translateY="390">
- <group
- android:name="_R_G_L_0_G_L_2_G_L_0_G"
- android:translateX="182"
- android:translateY="120">
- <path
- android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
- </group>
- </group>
- <group android:name="_R_G_L_0_G_L_1_G">
- <group
- android:name="_R_G_L_0_G_L_1_G_L_2_G"
- android:translateX="206"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_0_G_L_1_G_L_1_G"
- android:translateX="206"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#80868b"
- 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_0_G_L_1_G_L_0_G"
- android:translateX="46"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#80868b"
- 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_0_G_L_0_G">
- <group
- android:name="_R_G_L_0_G_L_0_G_L_2_G"
- android:translateX="206"
- android:translateY="51">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#202124"
- 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_0_G_L_0_G_L_1_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#202124"
- 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_0_G_L_0_G_L_0_G"
- android:translateX="206"
- android:translateY="66.5">
- <path
- android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#3c4043"
- 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="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_light_mode.xml b/quickstep/res/drawable/mock_webpage_light_mode.xml
deleted file mode 100644
index 98abb92..0000000
--- a/quickstep/res/drawable/mock_webpage_light_mode.xml
+++ /dev/null
@@ -1,263 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="83"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group android:name="_R_G_L_0_G">
- <group android:name="_R_G_L_0_G_L_4_G">
- <group
- android:name="_R_G_L_0_G_L_4_G_L_11_G"
- android:scaleX="0.87473"
- android:scaleY="0.98643"
- android:translateX="206"
- android:translateY="472.769">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- 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_0_G_L_4_G_L_10_G"
- android:translateX="182.5"
- android:translateY="831">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_9_G"
- android:translateX="186"
- android:translateY="801">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_8_G"
- android:translateX="119"
- android:translateY="755">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_7_G"
- android:translateX="182.5"
- android:translateY="725">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_6_G"
- android:translateX="197.5"
- android:translateY="695">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_5_G"
- android:translateX="192"
- android:translateY="665">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_4_G"
- android:translateX="105.5"
- android:translateY="360">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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_0_G_L_4_G_L_3_G"
- android:translateX="47.5"
- android:translateY="360">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- 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_0_G_L_4_G_L_2_G"
- android:translateX="142.5"
- android:translateY="328">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_1_G"
- android:translateX="186"
- android:translateY="284">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
- </group>
- <group
- android:name="_R_G_L_0_G_L_4_G_L_0_G"
- android:translateX="155"
- android:translateY="240">
- <path
- android:name="_R_G_L_0_G_L_4_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G_L_3_G"
- android:translateX="24"
- android:translateY="390">
- <group
- android:name="_R_G_L_0_G_L_3_G_L_0_G"
- android:translateX="182"
- android:translateY="120">
- <path
- android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
- </group>
- </group>
- <group android:name="_R_G_L_0_G_L_2_G">
- <group
- android:name="_R_G_L_0_G_L_2_G_L_2_G"
- android:translateX="206"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_2_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_0_G_L_2_G_L_1_G"
- android:translateX="206"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_2_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#80868b"
- 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_0_G_L_2_G_L_0_G"
- android:translateX="46"
- android:translateY="145">
- <path
- android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#80868b"
- 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_0_G_L_1_G">
- <group
- android:name="_R_G_L_0_G_L_1_G_L_2_G"
- android:translateX="206"
- android:translateY="51">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#6e7175"
- 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_0_G_L_1_G_L_1_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#6e7175"
- 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_0_G_L_1_G_L_0_G"
- android:translateX="206"
- android:translateY="66.5">
- <path
- android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9a9a9a"
- 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_0_G_L_0_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bac4d6"
- android:fillType="nonZero"
- android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
- </group>
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.png b/quickstep/res/drawable/taskbar_edu_splitscreen.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_splitscreen.png
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.webp b/quickstep/res/drawable/taskbar_edu_splitscreen.webp
deleted file mode 100644
index 2f4402f..0000000
--- a/quickstep/res/drawable/taskbar_edu_splitscreen.webp
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_stashing.png b/quickstep/res/drawable/taskbar_edu_stashing.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_stashing.png
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_switch_apps.png b/quickstep/res/drawable/taskbar_edu_switch_apps.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_switch_apps.png
Binary files differ
diff --git a/quickstep/res/interpolator/app_open_x.xml b/quickstep/res/interpolator/app_open_x.xml
new file mode 100644
index 0000000..5fa0bcb
--- /dev/null
+++ b/quickstep/res/interpolator/app_open_x.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0, 0 C 0.1217, 0.0462, 0.15, 0.4686, 0.1667, 0.66 C 0.1834, 0.8878, 0.1667, 1, 1, 1"/>
diff --git a/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
new file mode 100644
index 0000000..70c4231
--- /dev/null
+++ b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"/>
diff --git a/quickstep/res/layout/gesture_tutorial_dialog.xml b/quickstep/res/layout/gesture_tutorial_dialog.xml
index 59bf7b9..db6ec85 100644
--- a/quickstep/res/layout/gesture_tutorial_dialog.xml
+++ b/quickstep/res/layout/gesture_tutorial_dialog.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index cdda43c..cfb3eb0 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -49,7 +49,7 @@
android:scaleY="0.98"
android:visibility="invisible" />
- <View
+ <FrameLayout
android:id="@+id/gesture_tutorial_fake_task_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -62,7 +62,7 @@
android:background="@drawable/gesture_tutorial_ripple"/>
<ImageView
- android:id="@+id/gesture_tutorial_feedback_video"
+ android:id="@+id/gesture_tutorial_edge_gesture_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
@@ -73,14 +73,12 @@
android:visibility="gone"/>
<ImageView
- android:id="@+id/gesture_tutorial_gesture_video"
- 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"
- android:scaleType="fitXY"
+ android:id="@+id/gesture_tutorial_finger_dot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_finger_dot"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
android:visibility="gone"/>
<androidx.constraintlayout.widget.ConstraintLayout
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
new file mode 100644
index 0000000..89973d3
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<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="match_parent">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/top_bar"
+ android:layout_width="match_parent"
+ android:layout_height="101dp"
+ android:background="@color/mock_conversation_top_bar"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="43dp"
+ android:layout_marginBottom="22dp"
+ android:layout_marginStart="34dp"
+ android:layout_marginEnd="211dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="43dp"
+ android:layout_marginBottom="22dp"
+ android:layout_marginStart="300dp"
+ android:layout_marginEnd="16dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/top_bar_button"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/top_bar_button"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="43dp"
+ android:layout_marginBottom="22dp"
+ android:layout_marginStart="300dp"
+ android:layout_marginEnd="24dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:background="@color/mock_conversation_background"
+ android:paddingBottom="66dp"
+
+ app:layout_constraintTop_toBottomOf="@id/top_bar"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:paddingBottom="36dp"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/message_bar"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/message_1"
+ android:layout_width="0dp"
+ android:layout_height="112dp"
+ android:layout_marginBottom="32dp"
+ android:layout_marginStart="124dp"
+ android:layout_marginEnd="18dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_sent_message"
+ app:layout_constraintBottom_toTopOf="@id/reply_icon_1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/reply_icon_1"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginBottom="32dp"
+ android:layout_marginStart="26dp"
+ android:layout_marginEnd="342dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_conversation_profile_icon"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintBottom_toTopOf="@id/message_2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginStart="17dp"
+ android:layout_marginEnd="112dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_received_message"
+ app:layout_constraintTop_toTopOf="@id/reply_icon_1"
+ app:layout_constraintBottom_toBottomOf="@id/reply_icon_1"
+ app:layout_constraintStart_toEndOf="@id/reply_icon_1"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/message_2"
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginBottom="4dp"
+ android:layout_marginStart="280dp"
+ android:layout_marginEnd="18dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_sent_message"
+ app:layout_constraintBottom_toTopOf="@id/message_3"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/message_3"
+ android:layout_width="0dp"
+ android:layout_height="74dp"
+ android:layout_marginBottom="32dp"
+ android:layout_marginStart="124dp"
+ android:layout_marginEnd="18dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_sent_message"
+ app:layout_constraintBottom_toTopOf="@id/reply_icon_2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/reply_icon_2"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginBottom="32dp"
+ android:layout_marginStart="26dp"
+ android:layout_marginEnd="342dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_conversation_profile_icon"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintBottom_toTopOf="@id/message_4"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginStart="17dp"
+ android:layout_marginEnd="144dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_received_message"
+ app:layout_constraintTop_toTopOf="@id/reply_icon_2"
+ app:layout_constraintBottom_toBottomOf="@id/reply_icon_2"
+ app:layout_constraintStart_toEndOf="@id/reply_icon_2"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/message_4"
+ android:layout_width="0dp"
+ android:layout_height="74dp"
+ android:layout_marginStart="124dp"
+ android:layout_marginEnd="18dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="18dp"
+ app:cardBackgroundColor="@color/mock_conversation_sent_message"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/message_bar"
+ android:layout_width="0dp"
+ android:layout_height="44dp"
+ android:layout_marginTop="36dp"
+ android:layout_marginStart="34dp"
+ android:layout_marginEnd="24dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="164dp"
+ app:cardBackgroundColor="@color/mock_conversation_message_input"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
new file mode 100644
index 0000000..ad6b165
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<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="match_parent">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/top_bar"
+ android:layout_width="match_parent"
+ android:layout_height="101dp"
+ android:background="@color/mock_list_top_bar"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="43dp"
+ android:layout_marginBottom="22dp"
+ android:layout_marginStart="34dp"
+ android:layout_marginEnd="35dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_top_bar_item"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:background="@color/mock_list_background"
+ android:paddingBottom="66dp"
+
+ app:layout_constraintTop_toBottomOf="@id/top_bar"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:paddingTop="28dp"
+ android:paddingStart="26dp"
+ android:paddingBottom="14dp"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/mock_button">
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_1"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_1"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="217dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_1"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_2"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_2"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="142dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_1"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_1"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_2"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_1"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_3"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="190dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_2"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_4"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_4"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="171dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_3"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_2"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_3"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_2"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_5"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="198dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_3"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_6"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_6"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="79dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_5"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_3"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_4"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_3"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_7"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="174dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_4"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_8"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_8"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="117dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_7"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_4"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_5"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_4"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_9"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="244dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_5"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_10"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_10"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="143dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_9"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_5"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_6"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_5"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_11"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="177dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_6"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_12"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_12"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="117dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_11"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_6"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_icon_7"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_marginTop="32dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_list_profile_icon"
+ app:layout_constraintTop_toBottomOf="@id/conversation_icon_6"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_13"
+ android:layout_width="0dp"
+ android:layout_height="18dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="189dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="@id/conversation_icon_7"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/conversation_line_14"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/conversation_line_14"
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="166dp"
+ android:layout_marginTop="4dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_list_preview_message"
+ app:layout_constraintTop_toBottomOf="@id/conversation_line_13"
+ app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/conversation_icon_7"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_button"
+ android:layout_width="149dp"
+ android:layout_height="56dp"
+ android:layout_marginEnd="24dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="164dp"
+ app:cardBackgroundColor="@color/mock_list_button"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_webpage.xml b/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
new file mode 100644
index 0000000..ab00a11
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<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="match_parent">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/url_bar"
+ android:layout_width="match_parent"
+ android:layout_height="101dp"
+ android:background="@color/mock_webpage_url_bar"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="48dp"
+ android:layout_marginBottom="16dp"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="100dp"
+ app:cardBackgroundColor="@color/mock_webpage_url_bar_item"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/top_bar"
+ android:layout_width="match_parent"
+ android:layout_height="88dp"
+ android:background="@color/mock_webpage_top_bar"
+
+ app:layout_constraintTop_toBottomOf="@id/url_bar"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/top_bar_button"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="22dp"
+ android:layout_marginBottom="22dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="344dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="28dp"
+ android:layout_marginBottom="28dp"
+ android:layout_marginStart="97dp"
+ android:layout_marginEnd="97dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="2dp"
+ app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:background="@color/mock_webpage_background"
+ android:paddingTop="32dp"
+ android:paddingStart="24dp"
+ android:paddingBottom="50dp"
+
+ app:layout_constraintTop_toBottomOf="@id/top_bar"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_1"
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginEnd="126dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_2"
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="64dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_3"
+ android:layout_width="0dp"
+ android:layout_height="36dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="151dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_button"
+ android:layout_width="47dp"
+ android:layout_height="12dp"
+ android:layout_marginTop="8dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_3"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="47dp"
+ android:layout_height="12dp"
+ android:background="@color/mock_webpage_page_text"
+ android:layout_marginStart="11dp"
+ android:layout_marginTop="8dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="4dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_3"
+ app:layout_constraintStart_toEndOf="@id/mock_button"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_block"
+ android:layout_width="0dp"
+ android:layout_height="240dp"
+ android:layout_marginTop="24dp"
+ android:layout_marginEnd="24dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="22dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_button"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_4"
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="24dp"
+ android:layout_marginEnd="52dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_block"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_5"
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="41dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_4"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_6"
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="71dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_5"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_7"
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="198dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_6"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mock_line_8"
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="24dp"
+ android:layout_marginEnd="64dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_7"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="22dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="71dp"
+
+ app:cardElevation="0dp"
+ app:cardCornerRadius="8dp"
+ app:cardBackgroundColor="@color/mock_webpage_page_text"
+ app:layout_constraintTop_toBottomOf="@id/mock_line_8"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 0c2a28c..acbb5b9 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -47,6 +47,23 @@
android:layout_weight="1" />
<Button
+ android:id="@+id/action_split"
+ style="@style/OverviewActionButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableStart="@drawable/ic_split_screen"
+ android:text="@string/action_split"
+ android:theme="@style/ThemeControlHighlightWorkspaceColor"
+ android:visibility="gone" />
+
+ <Space
+ android:id="@+id/action_split_space"
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:layout_weight="1"
+ android:visibility="gone" />
+
+ <Button
android:id="@+id/action_share"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 1ee726e..1dea57e 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -16,7 +16,7 @@
-->
<com.android.quickstep.views.ClearAllButton
xmlns:android="http://schemas.android.com/apk/res/android"
- style="@android:style/Widget.DeviceDefault.Button.Borderless"
+ style="@style/OverviewClearAllButton"
android:id="@+id/clear_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index c0e0862..b4c168c 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -65,13 +65,12 @@
android:layout_gravity="end"/>
</FrameLayout>
- <View
+ <com.android.launcher3.taskbar.StashedHandleView
android:id="@+id/stashed_handle"
tools:comment1="The actual size and shape will be set as a ViewOutlineProvider at runtime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- tools:comment2="TODO: Tint dynamically"
- android:background="?android:attr/textColorPrimary"
+ android:background="@color/taskbar_stashed_handle_dark_color"
android:clipToOutline="true"
android:layout_gravity="bottom"/>
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
index b7717b7..3796ff9 100644
--- a/quickstep/res/layout/taskbar_edu.xml
+++ b/quickstep/res/layout/taskbar_edu.xml
@@ -17,6 +17,7 @@
<com.android.launcher3.taskbar.TaskbarEduView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
@@ -33,47 +34,104 @@
android:paddingHorizontal="36dp"
android:paddingTop="64dp">
- <TextView
- android:id="@+id/edu_header"
+ <com.android.launcher3.taskbar.TaskbarEduPagedView
+ android:id="@+id/content"
+ android:clipToPadding="false"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="16dp"
+ android:layout_height="378dp"
app:layout_constraintTop_toTopOf="parent"
- android:gravity="center_horizontal"
- style="@style/TextHeadline"
- android:text="@string/taskbar_edu_header_1"
- android:fontFamily="google-sans"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="24sp"
- android:maxLines="2"/>
+ launcher:pageIndicator="@+id/content_page_indicator">
- <ImageView
- android:id="@+id/edu_illustration"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- app:layout_constraintTop_toBottomOf="@id/edu_header"
- android:src="@drawable/taskbar_edu_splitscreen"/>
+ <LinearLayout
+ android:id="@+id/page_switch_apps"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.TaskbarEdu.Title"
+ android:text="@string/taskbar_edu_switch_apps"/>
+
+ <ImageView
+ android:layout_width="322dp"
+ android:layout_height="282dp"
+ android:layout_marginTop="16dp"
+ android:src="@drawable/taskbar_edu_switch_apps"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/page_splitscreen"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.TaskbarEdu.Title"
+ android:text="@string/taskbar_edu_splitscreen"/>
+
+ <ImageView
+ android:layout_width="322dp"
+ android:layout_height="282dp"
+ android:layout_marginTop="16dp"
+ android:src="@drawable/taskbar_edu_splitscreen"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/page_stashing"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.TaskbarEdu.Title"
+ android:text="@string/taskbar_edu_stashing"/>
+
+ <ImageView
+ android:layout_width="322dp"
+ android:layout_height="282dp"
+ android:layout_marginTop="16dp"
+ android:src="@drawable/taskbar_edu_stashing"/>
+ </LinearLayout>
+ </com.android.launcher3.taskbar.TaskbarEduPagedView>
<Button
- android:id="@+id/edu_close_button"
+ android:id="@+id/edu_start_button"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginBottom="92dp"
- app:layout_constraintTop_toBottomOf="@id/edu_illustration"
+ android:layout_marginTop="32dp"
+ app:layout_constraintTop_toBottomOf="@id/content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/taskbar_edu_close"
style="@style/TaskbarEdu.Button.Close"
android:textColor="?android:attr/textColorPrimary"/>
- <Button
- android:id="@+id/edu_next_button"
+ <com.android.launcher3.pageindicators.PageIndicatorDots
+ android:id="@+id/content_page_indicator"
android:layout_width="wrap_content"
- android:layout_height="36dp"
- android:layout_marginBottom="92dp"
- app:layout_constraintTop_toBottomOf="@id/edu_illustration"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="@id/edu_start_button"
+ app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:elevation="1dp" />
+
+ <Button
+ android:id="@+id/edu_end_button"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ app:layout_constraintTop_toTopOf="@id/edu_start_button"
+ app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/taskbar_edu_next"
style="@style/TaskbarEdu.Button.Next"
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 433ef86..4a83a4b 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Jy kan dit later in die <xliff:g id="NAME">%1$s</xliff:g>-program kry"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselleer"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Slaan oor"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gebruik 2 programme tegelyk en wissel programme met die taakbalk"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Maak toe"</string>
</resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 838dd60..4bb9c15 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ይህን በኋላ በ<xliff:g id="NAME">%1$s</xliff:g> መተግበሪያው ውስጥ ማግኘት ይችላሉ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ይቅር"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ዝለል"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"በአንድ ጊዜ 2 መተግበሪያዎችን ይጠቀሙ እና በተግባር አሞሌው አማካኝነት መተግበሪያዎችን ይቀያይሩ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"ቀጣይ"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"ዝጋ"</string>
</resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 3f26977..6557abb 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"يمكنك العثور على هذا الدليل التوجيهي لاحقًا في التطبيق \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"إلغاء"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"التخطي"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"يمكنك استخدام تطبيقين في الوقت نفسه والتبديل بينهما من شريط المهام."</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"الشاشة التالية"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"إغلاق"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 2551fc4..a506618 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপুনি এয়া পাছত <xliff:g id="NAME">%1$s</xliff:g> এপ্টোত বিচাৰিব পাৰিব"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল কৰক"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এৰি যাওক"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"এবাৰতে ২ টা এপ্ ব্যৱহাৰ কৰক আৰু টাস্কবাৰ ব্যৱহাৰ কৰি এপ্ সলনি কৰক"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"পৰৱৰ্তী"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ কৰক"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index d01bf3f..ba235f4 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu sonra <xliff:g id="NAME">%1$s</xliff:g> tətbiqində tapa bilərsiniz"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ləğv edin"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ötürün"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Eyni anda 2 tətbiqdən istifadə edin və tapşırıq paneli ilə tətbiqlər arasında keçid edin"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Sonra"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Bağlayın"</string>
</resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index bde409f..5001491 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Možete da pronađete ovo kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Koristite 2 aplikacije odjednom i menjajte aplikacije pomoću trake zadataka"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 8e57bd8..1662423 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Знайсці дапаможнік можна ў праграме \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасаваць"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прапусціць"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Адначасова выкарыстоўвайце 2 праграмы і пераключайцеся паміж імі на панэлі задач"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Далей"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 7305d9d..7712020 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Урокът е налице в приложението <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отказ"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропускане"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Използвайте две приложения едновременно и превключвайте между приложенията посредством лентата на задачите"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Напред"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
</resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 1d0b45f..83f6656 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপনি <xliff:g id="NAME">%1$s</xliff:g> অ্যাপে পরে এটি খুঁজে পাবেন"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল করুন"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এড়িয়ে যান"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index acd7b10..eba8275 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To možete pronaći kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Koristite 2 aplikacije odjednom i prebacujte između aplikacija putem programske trake"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprijed"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index a0d6aee..62d1ed0 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pots trobar-lo més tard a l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel·la"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omet"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilitza 2 aplicacions alhora i canvia d\'aplicació amb la barra de tasques"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Següent"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index b2d092e..c4e632c 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Program později najdete v aplikaci <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušit"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Přeskočit"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Používejte 2 aplikace naráz a přepínejte mezi aplikacemi pomocí hlavního panelu"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Další"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index f2e2df0..ed63f40 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finde dette senere i appen <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuller"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Spring over"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Brug to apps på samme tid, og skift mellem dem via proceslinjen"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Næste"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
</resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 4a023e3..0ff759e 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du findest es später auch in der <xliff:g id="NAME">%1$s</xliff:g> App"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Abbrechen"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Überspringen"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Du kannst 2 Apps auf einmal verwenden und über die Taskleiste zwischen ihnen wechseln"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Weiter"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
</resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 7243e03..1c5e24a 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Βρείτε τον αργότερα στην εφαρμογή <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ακύρωση"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Παράβλεψη"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Χρησιμοποιήστε 2 εφαρμογές ταυτόχρονα και κάντε εναλλαγή εφαρμογών με τη γραμμή εργασιών"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Επόμενο"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
</resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
</resources>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
</resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
</resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
</resources>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index 35ec6bb..1550285 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use 2 apps at once and switch apps with the taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
</resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index e61fd91..02f6ea6 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes encontrarlo en la app de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa 2 apps a la vez e intercámbialas con la barra de tareas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 8e8829e..b4fee8b 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes consultarlo en otro momento en la aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltar"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa dos aplicaciones a la vez y cambia de aplicación con la barra de tareas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 74b7528..9f8737c 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Leiate selle hiljem rakendusest <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Tühista"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Jäta vahele"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Tegumiribal kahe rakenduse korraga kasutamine ja rakenduste vahel vahetamine"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Järgmine"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
</resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index bd016e9..e4186a4 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioan dago eskuragarri tutoriala"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Utzi"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltatu"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Erabili bi aplikazio aldi berean eta aldatu aplikazioz zereginen barra erabilita"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Hurrengoa"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
</resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index ae260ed..0a27952 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"میتوانید آن را بعداً در برنامه <xliff:g id="NAME">%1$s</xliff:g> پیدا کنید"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"لغو"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"رد شدن"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"همزمان از ۲ برنامه استفاده کنید و ازطریق نوار وظیفه بین برنامهها جابهجا شوید"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"بعدی"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"بستن"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 8762feb..fc19646 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Löydät tämän myöhemmin sovelluksesta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Peru"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ohita"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Voit käyttää kahta sovellusta samaan aikaan ja vaihtaa sovelluksesta toiseen tehtäväpalkin kautta"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Seuraava"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index a3c9393..cb1eff6 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous trouverez le tutoriel dans l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorer"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 5164792..67106b8 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous le retrouverez dans l\'appli <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Passer"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilisez deux applis à la fois et changez d\'appli avec la barre des tâches"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index baa87e7..8600412 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Podes atopar isto máis tarde na aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa dúas aplicacións á vez e alterna unha coa outra mediante a barra de ferramentas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
</resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 33e8617..cf5e464 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"તમે આને પછીથી <xliff:g id="NAME">%1$s</xliff:g> ઍપમાં જોઈ શકો છો"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"રદ કરો"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"છોડો"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 50ebb27..2c7a5ac 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"आप बाद में <xliff:g id="NAME">%1$s</xliff:g> ऐप्लिकेशन पर इसे देख सकते हैं"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"अभी नहीं"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"अभी नहीं"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"एक साथ दो ऐप्लिकेशन इस्तेमाल करें और टास्कबार से एक से दूसरे ऐप्लिकेशन पर जाएं"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"आगे बढ़ें"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करें"</string>
</resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 50efb74..b8d4e4f 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Kasnije ga možete pronaći u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Odustani"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Upotrebljavajte dvije aplikacije odjednom i prebacujte se između aplikacija i programske trake"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index e9bd2bf..429b364 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ezt később megtalálhatja a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazásban"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Mégse"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kihagyás"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Két alkalmazást használhat egyszerre, és az eszköztárral válthat az alkalmazások között"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Tovább"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
</resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index e2c0af3..0a18ae9 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Հետագայում սա կարող եք գտնել «<xliff:g id="NAME">%1$s</xliff:g>» հավելվածում"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Չեղարկել"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Բաց թողնել"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Միաժամանակ օգտագործեք 2 հավելված և խնդրագոտու միջոցով անցեք մեկից մյուսը։"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Առաջ"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
</resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 3e24fcb..8ef7355 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda dapat menemukan tutorial ini di lain waktu di aplikasi <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Lewati"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gunakan 2 aplikasi sekaligus dan beralihlah antar-aplikasi dengan taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Berikutnya"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index eeebc71..5bcc545 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Þú getur fundið þetta síðar í forritinu <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hætta við"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Sleppa"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Notaðu 2 forrit í einu og skiptu á milli forrita á verkefnastikunni"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Áfram"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Loka"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 5a33a38..5633381 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puoi trovarlo in un secondo momento nell\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annulla"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Salta"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa 2 app contemporaneamente e passa dall\'una all\'altra tramite la barra delle applicazioni"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Avanti"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 2677690..e687d88 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ניתן למצוא את המדריך מאוחר יותר באפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ביטול"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"דילוג"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 9c2adef..a0b25a9 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"チュートリアルは後から <xliff:g id="NAME">%1$s</xliff:g> アプリで確認できます"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"キャンセル"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"スキップ"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 つのアプリを同時に使用し、タスクバーでアプリを切り替えます"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"次へ"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
</resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index ab3715a..fec33cf 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ამის მოგვიანებით პოვნა <xliff:g id="NAME">%1$s</xliff:g> აპში შეგიძლიათ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"გაუქმება"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"გამოტოვება"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"გამოიყენეთ ერთდროულად 2 აპი და გადართეთ აპები ამოცანების ზოლის მეშვეობით"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"შემდეგი"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
</resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index d762bd8..dd337fc 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Мұны кейін <xliff:g id="NAME">%1$s</xliff:g> қолданбасынан таба аласыз."</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Бас тарту"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткізіп жіберу"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 қолданбаны қатар қолданыңыз және оларды тапсырмалар тақтасы арқылы ауыстырыңыз."</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Келесі"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 2700b83..9f90d06 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"អ្នកអាចស្វែងរកមេរៀននេះនៅពេលក្រោយក្នុងកម្មវិធី <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"បោះបង់"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"រំលង"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ប្រើកម្មវិធី 2 ក្នុងពេលតែមួយ ហើយប្ដូរកម្មវិធីដោយប្រើរបារកិច្ចការ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"បន្ទាប់"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"បិទ"</string>
</resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 9b981c2..1a83864 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ಆ್ಯಪ್ನಲ್ಲಿ ಇದನ್ನು ನಂತರ ಕಾಣಬಹುದು"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ರದ್ದುಮಾಡಿ"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ಸ್ಕಿಪ್ ಮಾಡಿ"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index ba564a7..e5341f4 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"이 튜토리얼은 <xliff:g id="NAME">%1$s</xliff:g> 앱에서 다시 볼 수 있습니다"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"취소"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"건너뛰기"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"작업 표시줄을 통해 앱 2개를 동시에 사용하고 앱 간에 전환"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"다음"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
</resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 8be5c53..b2e2ec2 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Аны кийин <xliff:g id="NAME">%1$s</xliff:g> колдонмосунан табасыз"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Жокко чыгаруу"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткрп жиберүү"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Бир убакта 2 колдонмону пайдаланып, колдонмолорду тапшырмалар тактасы аркылуу которуштуруу"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Кийинки"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Жабуу"</string>
</resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 915578b..699cafa 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ທ່ານສາມາດຊອກສ່ວນນີ້ພາຍຫຼັງໄດ້ໃນແອັບ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ຍົກເລີກ"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ຂ້າມ"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ໃຊ້ 2 ແອັບພ້ອມກັບ ແລະ ສະຫຼັບແອັບດ້ວຍແຖບໜ້າວຽກ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"ຕໍ່ໄປ"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"ປິດ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index b0c679c..f8c7bc7 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tai galėsite rasti vėliau programoje „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atšaukti"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Praleisti"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Užduočių juostoje vienu metu naudokite dvi programas ir jas perjunkite"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Kitas"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
</resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index df1c3e9..0e44d77 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Varēsiet to vēlāk atrast lietotnē <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atcelt"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Izlaist"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Varat izmantot divas lietotnes reizē un pāriet no vienas uz otru, izmantojot rīkjoslu"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Tālāk"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
</resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 98307da..b3e08f5 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ова може да го најдете подоцна во апликацијата <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескокни"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користете 2 апликации одеднаш и префрлувајте се меѓу нив со лентата за задачи"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Следна"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
</resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 52be3ac..9291259 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ആപ്പിൽ നിങ്ങൾക്ക് ഇത് പിന്നീട് കാണാനാകും"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"റദ്ദാക്കുക"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ഒഴിവാക്കുക"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ടാസ്ക്ബാറിന്റെ സഹായത്തോടെ ഒരേ സമയം 2 ആപ്പുകൾ ഉപയോഗിക്കുകയും ആപ്പുകൾ പരസ്പരം മാറുകയും ചെയ്യൂ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"അടുത്തത്"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"അടയ്ക്കുക"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 79fbca6..65023d6 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Та үүнийг дараа нь <xliff:g id="NAME">%1$s</xliff:g> аппаас олох боломжтой"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Цуцлах"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Алгасах"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 аппыг нэг дор ашиглан талбарын тусламжтайгаар аппуудыг сэлгэнэ үү"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Дараах"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
</resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 8618f85..40c88a4 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तुम्हाला हे नंतर <xliff:g id="NAME">%1$s</xliff:g> ॲपमध्ये मिळेल"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द करा"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"वगळा"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 1e2d43d..886f3b6 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda boleh mendapatkan tutorial ini kemudian dalam apl <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Langkau"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gunakan 2 apl pada satu masa dan tukar apl dengan bar tugas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Seterusnya"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index b07bbfa..0d38c84 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"၎င်းကို နောက်မှ <xliff:g id="NAME">%1$s</xliff:g> အက်ပ်တွင် ရှာနိုင်သည်"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"မလုပ်တော့"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ကျော်ရန်"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"အက်ပ် ၂ ခုကို တစ်ပြိုင်ထဲသုံးပြီး လုပ်ဆောင်စရာဘားဖြင့် အက်ပ်များပြောင်းလိုက်ပါ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"ရှေ့သို့"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 16988c5..8ad72cd 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finne dette i <xliff:g id="NAME">%1$s</xliff:g>-appen senere"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hopp over"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Bruk to apper samtidig og bytt app med oppgavelinjen"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Neste"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 91cae47..89ef427 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तपाईं पछि <xliff:g id="NAME">%1$s</xliff:g> नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द गर्नुहोस्"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नु…"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml
new file mode 100644
index 0000000..c3b2536
--- /dev/null
+++ b/quickstep/res/values-night/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <color name="gesture_tutorial_back_arrow_color">#99000000</color>
+
+ <color name="gesture_tutorial_fake_wallpaper_color">#000000</color> <!-- Black -->
+
+ <color name="mock_webpage_url_bar">#202124</color>
+ <color name="mock_webpage_url_bar_item">#3c4043</color>
+
+</resources>
\ No newline at end of file
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 96da966..faed85b 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Je vindt dit later terug in de app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuleren"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Overslaan"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gebruik 2 apps tegelijk en schakel tussen apps via de taakbalk"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 9488021..b6281c3 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ଆପଣ ପରେ ଏହାକୁ <xliff:g id="NAME">%1$s</xliff:g> ଆପରେ ପାଇପାରିବେ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ବାତିଲ୍ କରନ୍ତୁ"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ବାଦ୍ ଦିଅନ୍ତୁ"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 89b2119..bdfc867 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ <xliff:g id="NAME">%1$s</xliff:g> ਐਪ ਵਿੱਚ ਲੱਭ ਸਕਦੇ ਹੋ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ਰੱਦ ਕਰੋ"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ਛੱਡੋ"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 893db91..57c9e4c 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Znajdziesz to później w aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anuluj"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pomiń"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Używaj 2 aplikacji jednocześnie i przełączaj je za pomocą paska zadań"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalej"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zamknij"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index c1cd2bb..40bb8a1 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pode encontrar isto mais tarde na app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorar"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilize 2 apps em simultâneo e alterne entre as apps com a barra de tarefas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
</resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 422d13a..144bbf6 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Veja o tutorial mais tarde no app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pular"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use dois apps ao mesmo tempo e alterne entre eles usando a barra de tarefas"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Próxima"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
</resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index a5e97e0..2231522 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Îl puteți găsi mai târziu în aplicația <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulați"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omiteți"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Folosiți două aplicații simultan și comutați între aplicații folosind bara de activități"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Înainte"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Închideți"</string>
</resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 7c4d485..9087da9 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Его можно найти в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отмена"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустить"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Пользуйтесь двумя приложениями одновременно и переключайтесь между ними с помощью панели задач"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Далее"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыть"</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 5f322e6..b3d88c0 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ඔබට මෙය පසුව <xliff:g id="NAME">%1$s</xliff:g> යෙදුම තුළ සොයා ගත හැකිය"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"අවලංගු කරන්න"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"මඟ හරින්න"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"එකවර යෙදුම් 2ක් භාවිත කර කාර්ය තීරුව සමඟින් යෙදුම් මාරු කරන්න"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"ඊළඟ"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 799e941..0b0082c 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tento návod nájdete v aplikácii <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušiť"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskočiť"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Používajte dve aplikácie naraz a prepínajte ich pomocou panela úloh"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Ďalej"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
</resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 7e40277..a2b1363 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To lahko pozneje najdete v aplikaciji <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Prekliči"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Sočasno uporabite dve aplikaciji in preklopite med njima z orodno vrstico."</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprej"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Zapri"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 86528d2..f259f3c 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Këtë mund ta gjesh më vonë tek aplikacioni <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulo"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kapërce"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index f2ffa0a..0d6d4d6 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Можете да пронађете ово касније у апликацији <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескочи"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користите 2 апликације одједном и мењајте апликације помоћу траке задатака"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Даље"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 931e458..acb8014 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du hittar det här igen i <xliff:g id="NAME">%1$s</xliff:g>-appen"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hoppa över"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Använd två appar samtidigt och byt mellan appar via aktivitetsfältet"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Nästa"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
</resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index 22aa3ef..f49ef9b 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Utapata mafunzo haya baadaye katika programu ya <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ghairi"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ruka"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Tumia programu mbili kwa wakati mmoja na ubadilishe programu ukitumia upau wa shughuli"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Endelea"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Funga"</string>
</resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index de7c26d..321555f 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ஆப்ஸில் பிறகு இதைக் கண்டறியலாம்"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ரத்துசெய்"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"தவிர்"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ஒரே நேரத்தில் 2 ஆப்ஸைப் பயன்படுத்தலாம், பணிப்பட்டி மூலம் ஆப்ஸுக்கிடையே மாறலாம்"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"அடுத்து"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
</resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index ef8f3ba..b8f3b04 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -84,4 +84,10 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> యాప్లో మీరు తర్వాత కనుగొనవచ్చు"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"రద్దు చేయి"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"స్కిప్ చేయి"</string>
+ <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+ <skip />
</resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 52b2878..6839fef 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"คุณดูบทแนะนำนี้ได้ภายหลังในแอป \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ยกเลิก"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ข้าม"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ใช้แอป 2 แอปพร้อมกันและสลับแอปด้วยแถบงาน"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"ถัดไป"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"ปิด"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 412449b..a7a0d81 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Makikita mo ito sa <xliff:g id="NAME">%1$s</xliff:g> app sa ibang pagkakataon"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselahin"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Laktawan"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gumamit ng 2 app nang sabay at magpalipat-lipat ng app gamit ang taskbar"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Susunod"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Isara"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 58d78e0..7ea58a0 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu daha sonra <xliff:g id="NAME">%1$s</xliff:g> uygulamasında bulabilirsiniz"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"İptal"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Atla"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 uygulamayı aynı anda kullanıp görev çubuğuyla uygulamalar arasında geçiş yapın"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"İleri"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 544cec7..4127b75 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ви знайдете його пізніше в додатку <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасувати"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустити"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користуйтеся двома додатками одночасно й перемикайтеся між ними за допомогою панелі завдань"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Далі"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
</resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 2e8bde9..0af4328 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"آپ اسے بعد میں <xliff:g id="NAME">%1$s</xliff:g> ایپ میں تلاش کر سکتے ہیں"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"منسوخ کریں"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"نظر انداز کریں"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ایک وقت میں 2 ایپس استعمال کریں اور ٹاسک بار کے ساتھ ایپس پر سوئچ کریں"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"آگے"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"بند کریں"</string>
</resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 8b194de..c77a6c7 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bu darslar <xliff:g id="NAME">%1$s</xliff:g> ilovasida chiqadi"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Bekor qilish"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Tashlab ketish"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Vazifalar panelidan almashtirish uchun birdaniga 2 ta ilovadan foydalanish"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Keyingisi"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 7bd0c70..0261368 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bạn có thể tìm lại phần hướng dẫn này trong ứng dụng <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hủy"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Bỏ qua"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Dùng 2 ứng dụng một lúc và chuyển đổi ứng dụng thông qua thanh tác vụ"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Tiếp theo"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 9e641de..8d97e7a 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之后可以在“<xliff:g id="NAME">%1$s</xliff:g>”应用中找到此教程"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"跳过"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"借助任务栏,您可以同时使用 2 个应用,并可以在应用之间切换"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"继续"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index d1e8392..d3cc14c 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"同時使用 2 個應用程式,以及使用工作列切換應用程式"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index db10354..382f725 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"你之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"你可以同時使用 2 個應用程式,只要透過工作列即可切換"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
</resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index bbfb840..1232a82 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -84,4 +84,7 @@
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Lokhu ungakuthola kamuva ku-app ye-<xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Khansela"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Yeqa"</string>
+ <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Sebenzisa ama-app ama-2 ngesikhathi esisodwa bese ushintsha ama-app ngebha yomsebenzi"</string>
+ <string name="taskbar_edu_next" msgid="4007618274426775841">"Okulandelayo"</string>
+ <string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
</resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 2f24441..4755292 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -14,8 +14,6 @@
limitations under the License.
-->
<resources>
- <color name="back_arrow_color_light">#FFFFFFFF</color>
- <color name="back_arrow_color_dark">#99000000</color>
<color name="chip_hint_foreground_color">#fff</color>
<color name="chip_scrim_start_color">#39000000</color>
@@ -28,4 +26,43 @@
<!-- Taskbar -->
<color name="taskbar_background">@color/overview_scrim_dark</color>
<color name="taskbar_icon_selection_ripple">#E0E0E0</color>
+
+ <color name="taskbar_stashed_handle_light_color">#EBffffff</color>
+ <color name="taskbar_stashed_handle_dark_color">#99000000</color>
+
+ <!-- Gesture navigation tutorial -->
+ <color name="gesture_tutorial_back_arrow_color">#FFFFFFFF</color>
+
+ <color name="gesture_tutorial_fake_wallpaper_color">#f9f9f9</color> <!-- White -->
+ <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
+ <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
+ <!-- Must contrast gesture_tutorial_fake_wallpaper_color -->
+ <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
+ <color name="gesture_tutorial_action_button_label_color">#FF000000</color>
+ <color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
+
+ <!-- Mock conversation -->
+ <color name="mock_conversation_background">#f1f3f4</color>
+ <color name="mock_conversation_top_bar">#e8eaed</color>
+ <color name="mock_conversation_top_bar_item">#dadce0</color>
+ <color name="mock_conversation_sent_message">#bdc1c6</color>
+ <color name="mock_conversation_received_message">#e8eaed</color>
+ <color name="mock_conversation_message_input">#dadce0</color>
+ <color name="mock_conversation_profile_icon">#dadce0</color>
+
+ <!-- Mock conversations list -->
+ <color name="mock_list_background">#dadce0</color>
+ <color name="mock_list_top_bar">#e8eaed</color>
+ <color name="mock_list_top_bar_item">#f8f9fa</color>
+ <color name="mock_list_profile_icon">#9aa0a6</color>
+ <color name="mock_list_preview_message">#bdc1c6</color>
+ <color name="mock_list_button">#bdc1c6</color>
+
+ <!-- Mock web page -->
+ <color name="mock_webpage_background">#f1f3f4</color>
+ <color name="mock_webpage_url_bar">#6e7175</color>
+ <color name="mock_webpage_url_bar_item">#9a9a9a</color>
+ <color name="mock_webpage_top_bar">#e8eaed</color>
+ <color name="mock_webpage_top_bar_item">#80868b</color>
+ <color name="mock_webpage_page_text">#bdc1c6</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 80d12aa..1ec5bb8 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -32,7 +32,8 @@
<dimen name="overview_minimum_next_prev_size">50dp</dimen>
<dimen name="overview_task_margin">16dp</dimen>
- <dimen name="overview_task_margin_grid">12dp</dimen>
+ <dimen name="overview_task_margin_focused">12dp</dimen>
+ <dimen name="overview_task_margin_grid">4dp</dimen>
<!-- Overrideable in overlay that provides the Overview Actions. -->
<dimen name="overview_actions_height">48dp</dimen>
@@ -45,8 +46,8 @@
<dimen name="overview_actions_horizontal_margin">16dp</dimen>
<dimen name="overview_grid_side_margin">50dp</dimen>
- <dimen name="overview_grid_row_spacing_portrait">37.13dp</dimen>
- <dimen name="overview_grid_row_spacing_landscape">33.38dp</dimen>
+ <dimen name="overview_grid_row_spacing_portrait">17.13dp</dimen>
+ <dimen name="overview_grid_row_spacing_landscape">13.38dp</dimen>
<dimen name="overview_grid_focus_vertical_margin">0dp</dimen>
<!-- These speeds are in dp/s -->
@@ -165,5 +166,6 @@
<dimen name="taskbar_stashed_size">24dp</dimen>
<dimen name="taskbar_stashed_handle_width">220dp</dimen>
<dimen name="taskbar_stashed_handle_height">6dp</dimen>
- <dimen name="taskbar_edu_bg_corner_radius">28dp</dimen>
+ <dimen name="taskbar_edu_wave_anim_trans_y">25dp</dimen>
+ <dimen name="taskbar_edu_wave_anim_trans_y_return_overshoot">4dp</dimen>
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index da19c95..7158287 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -191,6 +191,8 @@
<string name="action_share">Share</string>
<!-- Label for a button that causes a screen shot of the current app to be taken. [CHAR_LIMIT=40] -->
<string name="action_screenshot">Screenshot</string>
+ <!-- Label for a button that enters split screen selection mode. [CHAR_LIMIT=20] -->
+ <string name="action_split">Split</string>
<!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
<string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
@@ -205,11 +207,25 @@
<string name="gesture_tutorial_action_button_label_skip">Skip</string>
<!-- ******* Taskbar Edu ******* -->
- <!-- Text in dialog that lets a user know how they can use the taskbar on their device.
- [CHAR_LIMIT=NONE] -->
- <string name="taskbar_edu_header_1">Use 2 apps at once and switch apps with the taskbar</string>
- <!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=30] -->
+ <!-- Accessibility text spoken when the taskbar education panel appears [CHAR_LIMIT=NONE] -->
+ <string name="taskbar_edu_opened">Taskbar education appeared</string>
+ <!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
+ <string name="taskbar_edu_closed">Taskbar education closed</string>
+ <!-- Text in dialog that lets a user know how they can use the taskbar to switch apps on their device.
+ [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_switch_apps" translatable="false">Use the taskbar to switch apps</string>
+ <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps at once on their device.
+ [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_splitscreen" translatable="false">Drag to the side to use two apps at once</string>
+ <!-- Text in dialog that lets a user know how they can hide the taskbar on their device.
+ [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_stashing">Touch & hold to hide the taskbar</string>
+ <!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
<string name="taskbar_edu_next">Next</string>
- <!-- Text on button to exit a tutorial [CHAR_LIMIT=30] -->
+ <!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
+ <string name="taskbar_edu_previous">Back</string>
+ <!-- Text on button to exit a tutorial [CHAR_LIMIT=16] -->
<string name="taskbar_edu_close">Close</string>
+ <!-- Text on button to finish a tutorial [CHAR_LIMIT=16] -->
+ <string name="taskbar_edu_done">Done</string>
</resources>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index c23a3a0..b5444b5 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -135,6 +135,13 @@
<item name="android:textAllCaps">false</item>
</style>
+ <style name="OverviewClearAllButton" parent="@android:style/Widget.DeviceDefault.Button">
+ <item name="android:background">@drawable/bg_overview_clear_all_button</item>
+ <item name="android:minWidth">85dp</item>
+ <item name="android:minHeight">36dp</item>
+ <item name="android:stateListAnimator">@null</item>
+ </style>
+
<!-- Icon displayed on the taskbar -->
<style name="BaseIcon.Workspace.Taskbar" >
<item name="iconDisplay">taskbar</item>
@@ -144,11 +151,23 @@
<item name="android:background">@drawable/button_taskbar_edu_bordered</item>
<item name="android:stateListAnimator">@null</item>
<item name="android:textSize">16sp</item>
+ <item name="android:padding">4dp</item>
</style>
<style name="TaskbarEdu.Button.Next" parent="@android:style/Widget.Material.Button">
<item name="android:background">@drawable/button_taskbar_edu_colored</item>
<item name="android:stateListAnimator">@null</item>
<item name="android:textSize">16sp</item>
+ <item name="android:padding">4dp</item>
+ </style>
+
+ <style name="TextAppearance.TaskbarEdu.Title"
+ parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" >
+ <item name="android:layout_marginHorizontal">16dp</item>
+ <item name="android:gravity">center_horizontal</item>
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textSize">24sp</item>
+ <item name="android:lines">2</item>
</style>
</resources>
\ No newline at end of file
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
deleted file mode 100644
index 82e8903..0000000
--- a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import static com.android.launcher3.util.LauncherUIHelper.doLayout;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-
-import com.android.quickstep.fallback.FallbackRecentsView;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
-import org.robolectric.shadows.ShadowLooper;
-import org.robolectric.util.ReflectionHelpers;
-
-
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
-@org.junit.Ignore
-public class RecentsActivityTest {
-
- @Test
- public void testRecentsActivityCreates() {
- ActivityController<RecentsActivity> controller =
- Robolectric.buildActivity(RecentsActivity.class);
-
- RecentsActivity launcher = controller.setup().get();
- doLayout(launcher);
-
- // TODO: Ensure that LauncherAppState is not created
- }
-
- @Test
- public void testRecents_showCurrentTask() {
- ActivityController<RecentsActivity> controller =
- Robolectric.buildActivity(RecentsActivity.class);
-
- RecentsActivity activity = controller.setup().get();
- doLayout(activity);
-
- FallbackRecentsView frv = activity.getOverviewPanel();
-
- RunningTaskInfo placeholderTask = new RunningTaskInfo();
- placeholderTask.taskId = 22;
- frv.showCurrentTask(new RunningTaskInfo[]{placeholderTask});
- doLayout(activity);
-
- ThumbnailData thumbnailData = new ThumbnailData();
- ReflectionHelpers.setField(thumbnailData, "thumbnail",
- Bitmap.createBitmap(300, 500, Config.ARGB_8888));
- frv.switchToScreenshot(thumbnailData, () -> { });
- ShadowLooper.idleMainLooper();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 433ae3c..f06447b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -32,7 +32,6 @@
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
-import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
@@ -71,6 +70,7 @@
import android.view.View;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
+import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -142,21 +142,11 @@
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
"android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
- private static final long APP_LAUNCH_DURATION = 450;
- // Use a shorter duration for x or y translation to create a curve effect
- private static final long APP_LAUNCH_CURVED_DURATION = 250;
+ private static final long APP_LAUNCH_DURATION = 500;
+
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
- // We scale the durations for the downward app launch animations (minus the scale animation).
- private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
- private static final long APP_LAUNCH_DOWN_DURATION =
- (long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
- private static final long APP_LAUNCH_DOWN_CURVED_DURATION =
- (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
- private static final long APP_LAUNCH_ALPHA_DOWN_DURATION =
- (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
-
public static final int ANIMATION_NAV_FADE_IN_DURATION = 266;
public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133;
public static final long ANIMATION_DELAY_NAV_FADE_IN =
@@ -166,9 +156,6 @@
public static final Interpolator NAV_FADE_OUT_INTERPOLATOR =
new PathInterpolator(0.2f, 0f, 1f, 1f);
- private static final long CROP_DURATION = 375;
- private static final long RADIUS_DURATION = 375;
-
public static final int RECENTS_LAUNCH_DURATION = 336;
private static final int LAUNCHER_RESUME_START_DELAY = 100;
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
@@ -222,6 +209,9 @@
// Will never be larger than MAX_NUM_TASKS
private LinkedHashMap<Integer, Pair<Integer, Integer>> mTaskStartParams;
+ private final Interpolator mOpeningXInterpolator;
+ private final Interpolator mOpeningInterpolator;
+
public QuickstepTransitionManager(Context context) {
mLauncher = Launcher.cast(Launcher.getLauncher(context));
mDragLayer = mLauncher.getDragLayer();
@@ -248,6 +238,10 @@
SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
mStartingWindowListener);
}
+
+ mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
+ mOpeningInterpolator = AnimationUtils.loadInterpolator(context,
+ R.interpolator.three_point_fast_out_extra_slow_in);
}
@Override
@@ -686,27 +680,29 @@
final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
- FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
- FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
+ FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION,
+ mOpeningXInterpolator);
+ FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION,
+ mOpeningInterpolator);
FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
- prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+ prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
- APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
+ APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR);
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
- RADIUS_DURATION, EXAGGERATED_EASE);
+ APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0,
- APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+ APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
- 0, CROP_DURATION, EXAGGERATED_EASE);
+ 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
- 0, CROP_DURATION, EXAGGERATED_EASE);
+ 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
- CROP_DURATION, EXAGGERATED_EASE);
+ APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
- CROP_DURATION, EXAGGERATED_EASE);
+ APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
NAV_FADE_OUT_INTERPOLATOR);
@@ -908,22 +904,23 @@
WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* delay */,
WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* duration */, LINEAR);
final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius,
- 0 /* start */, RADIUS_DURATION, LINEAR);
- final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, RADIUS_DURATION, LINEAR);
+ 0 /* start */, APP_LAUNCH_DURATION, mOpeningInterpolator);
+ final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, APP_LAUNCH_DURATION,
+ mOpeningInterpolator);
// Window & widget background positioning bounds
final FloatProp mDx = new FloatProp(widgetBackgroundBounds.centerX(),
- windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_CURVED_DURATION,
- EXAGGERATED_EASE);
+ windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_DURATION,
+ mOpeningXInterpolator);
final FloatProp mDy = new FloatProp(widgetBackgroundBounds.centerY(),
windowTargetBounds.centerY(), 0 /* delay */, APP_LAUNCH_DURATION,
- EXAGGERATED_EASE);
+ mOpeningInterpolator);
final FloatProp mWidth = new FloatProp(widgetBackgroundBounds.width(),
windowTargetBounds.width(), 0 /* delay */, APP_LAUNCH_DURATION,
- EXAGGERATED_EASE);
+ mOpeningInterpolator);
final FloatProp mHeight = new FloatProp(widgetBackgroundBounds.height(),
windowTargetBounds.height(), 0 /* delay */, APP_LAUNCH_DURATION,
- EXAGGERATED_EASE);
+ mOpeningInterpolator);
final FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
NAV_FADE_OUT_INTERPOLATOR);
@@ -1467,10 +1464,6 @@
public final float dX;
public final float dY;
- public final long xDuration;
- public final long yDuration;
- public final long alphaDuration;
-
public final float initialAppIconScale;
public final float finalAppIconScale;
@@ -1502,14 +1495,6 @@
dX = centerX - launcherIconBounds.centerX();
dY = centerY - launcherIconBounds.centerY();
- boolean useUpwardAnimation = launcherIconBounds.top > centerY
- || Math.abs(dY) < dp.cellHeightPx;
- xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION
- : APP_LAUNCH_DOWN_DURATION;
- yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION
- : APP_LAUNCH_DOWN_CURVED_DURATION;
- alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
- : APP_LAUNCH_ALPHA_DOWN_DURATION;
iconAlphaStart = hasSplashScreen && !hasDifferentAppIcon ? 0 : 1f;
final int windowIconSize = ResourceUtils.getDimenByName("starting_surface_icon_size",
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index b40a1d5..13baf56 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -200,6 +200,7 @@
}
int predictionIndex = 0;
+ int numViewsAnimated = 0;
ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>();
// make sure predicted icon removal and filling predictions don't step on each other
if (mIconRemoveAnimators != null && mIconRemoveAnimators.isRunning()) {
@@ -233,7 +234,11 @@
(WorkspaceItemInfo) mPredictedItems.get(predictionIndex++);
if (isPredictedIcon(child) && child.isEnabled()) {
PredictedAppIcon icon = (PredictedAppIcon) child;
- icon.applyFromWorkspaceItem(predictedItem);
+ boolean animateIconChange = icon.shouldAnimateIconChange(predictedItem);
+ icon.applyFromWorkspaceItem(predictedItem, animateIconChange, numViewsAnimated);
+ if (animateIconChange) {
+ numViewsAnimated++;
+ }
icon.finishBinding(mPredictionLongClickListener);
} else {
newItems.add(predictedItem);
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 5777fb9..ab88b2b 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -26,6 +26,7 @@
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.FloatProperty;
+import android.view.AttachedSurfaceControl;
import android.view.CrossWindowBlurListeners;
import android.view.SurfaceControl;
import android.view.View;
@@ -295,13 +296,10 @@
}
if (supportsBlur) {
- // We cannot mark the window as opaque in overview because there will be an app window
- // below the launcher layer, and we need to draw it -- without blurs.
- boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW);
- boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview;
+ boolean opaque = mLauncher.getScrimView().isFullyOpaque();
- int blur = opaque || isOverview || !mCrossWindowBlursEnabled
- || mBlurDisabledForAppLaunch ? 0 : (int) (depth * mMaxBlurRadius);
+ int blur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch
+ ? 0 : (int) (depth * mMaxBlurRadius);
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
.setBackgroundBlurRadius(mSurface, blur)
.setOpaque(mSurface, opaque);
@@ -316,7 +314,12 @@
transaction.setEarlyWakeupEnd();
mInEarlyWakeUp = false;
}
- transaction.apply();
+
+ AttachedSurfaceControl rootSurfaceControl =
+ mLauncher.getRootView().getRootSurfaceControl();
+ if (rootSurfaceControl != null) {
+ rootSurfaceControl.applyTransactionOnDraw(transaction);
+ }
}
return true;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index da10bfb..acabb0d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -34,6 +34,7 @@
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.OnboardingPrefs;
@@ -45,6 +46,9 @@
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
/**
* A data source which integrates with a Launcher instance
*/
@@ -268,6 +272,11 @@
mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1);
}
+ @Override
+ public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
+ return Arrays.stream(mLauncher.getAppsView().getAppsStore().getApps());
+ }
+
/**
* Starts the taskbar education flow, if the user hasn't seen it yet.
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 08300e2..be9368f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -25,8 +25,11 @@
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.animation.ObjectAnimator;
import android.annotation.DrawableRes;
@@ -69,6 +72,9 @@
private static final int FLAG_A11Y_VISIBLE = 1 << 3;
private static final int FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE = 1 << 4;
private static final int FLAG_KEYGUARD_VISIBLE = 1 << 5;
+ private static final int FLAG_DISABLE_HOME = 1 << 6;
+ private static final int FLAG_DISABLE_RECENTS = 1 << 7;
+ private static final int FLAG_DISABLE_BACK = 1 << 8;
private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE;
@@ -169,7 +175,8 @@
mBackButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
mNavButtonContainer, mControllers.navButtonController, R.id.back);
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
- flags -> (flags & FLAG_IME_VISIBLE) == 0));
+ flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
+ (flags & FLAG_DISABLE_BACK) == 0));
// Hide when keyguard is showing, show when bouncer is showing
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 ||
@@ -180,12 +187,14 @@
navButtonController, R.id.home);
mPropertyHolders.add(new StatePropertyHolder(homeButton,
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
- (flags & FLAG_KEYGUARD_VISIBLE) == 0));
+ (flags & FLAG_KEYGUARD_VISIBLE) == 0 &&
+ (flags & FLAG_DISABLE_HOME) == 0));
View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS,
navContainer, navButtonController, R.id.recent_apps);
mPropertyHolders.add(new StatePropertyHolder(recentsButton,
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
- (flags & FLAG_KEYGUARD_VISIBLE) == 0));
+ (flags & FLAG_KEYGUARD_VISIBLE) == 0 &&
+ (flags & FLAG_DISABLE_RECENTS) == 0));
// A11y button
mA11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
@@ -202,6 +211,12 @@
boolean a11yVisible = (systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean a11yLongClickable =
(systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+ boolean isHomeDisabled =
+ (systemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+ boolean isRecentsDisabled =
+ (systemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ boolean isBackDisabled =
+ (systemUiStateFlags & SYSUI_STATE_BACK_DISABLED) != 0;
if (!forceUpdate && systemUiStateFlags == mSysuiStateFlags) {
return;
@@ -211,6 +226,10 @@
updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
updateStateForFlag(FLAG_SWITCHER_SUPPORTED, isImeSwitcherShowing);
updateStateForFlag(FLAG_A11Y_VISIBLE, a11yVisible);
+ updateStateForFlag(FLAG_DISABLE_HOME, isHomeDisabled);
+ updateStateForFlag(FLAG_DISABLE_RECENTS, isRecentsDisabled);
+ updateStateForFlag(FLAG_DISABLE_BACK, isBackDisabled);
+
if (mA11yButton != null) {
// Only used in 3 button
mA11yButton.setLongClickable(a11yLongClickable);
@@ -242,6 +261,13 @@
}
/**
+ * Returns true if the recents (overview) button is disabled
+ */
+ public boolean isRecentsDisabled() {
+ return (mState & FLAG_DISABLE_RECENTS) != 0;
+ }
+
+ /**
* Adds the bounds corresponding to all visible buttons to provided region
*/
public void addVisibleButtonsRegion(TaskbarDragLayer parent, Region outRegion) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
new file mode 100644
index 0000000..0224bc4
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
@@ -0,0 +1,70 @@
+/*
+ * 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.taskbar;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.ColorInt;
+import androidx.core.content.ContextCompat;
+
+import com.android.launcher3.R;
+
+public class StashedHandleView extends View {
+
+ private final @ColorInt int mStashedHandleLightColor;
+ private final @ColorInt int mStashedHandleDarkColor;
+ private final Rect mSampledRegion = new Rect();
+ private final int[] mTmpArr = new int[2];
+
+ public StashedHandleView(Context context) {
+ this(context, null);
+ }
+
+ public StashedHandleView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ mStashedHandleLightColor = ContextCompat.getColor(context,
+ R.color.taskbar_stashed_handle_light_color);
+ mStashedHandleDarkColor = ContextCompat.getColor(context,
+ R.color.taskbar_stashed_handle_dark_color);
+ }
+
+ public void updateSampledRegion() {
+ getLocationOnScreen(mTmpArr);
+ mSampledRegion.set(mTmpArr[0], mTmpArr[1], mTmpArr[0] + getWidth(),
+ mTmpArr[1] + getHeight());
+ }
+
+ public Rect getSampledRegion() {
+ return mSampledRegion;
+ }
+
+ public void updateHandleColor(boolean isRegionDark) {
+ setBackgroundColor(isRegionDark ? mStashedHandleLightColor : mStashedHandleDarkColor);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index df37261..2858d7c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar;
import android.animation.Animator;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -25,19 +26,30 @@
import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.util.Executors;
import com.android.quickstep.AnimatedFloat;
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
/**
* Handles properties/data collection, then passes the results to our stashed handle View to render.
*/
public class StashedHandleViewController {
+ /**
+ * The SharedPreferences key for whether the stashed handle region is dark.
+ */
+ private static final String SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY =
+ "stashed_handle_region_is_dark";
+
private final TaskbarActivityContext mActivity;
- private final View mStashedHandleView;
+ private final SharedPreferences mPrefs;
+ private final StashedHandleView mStashedHandleView;
private final int mStashedHandleWidth;
private final int mStashedHandleHeight;
+ private final RegionSamplingHelper mRegionSamplingHelper;
private final AnimatedFloat mTaskbarStashedHandleAlpha = new AnimatedFloat(
this::updateStashedHandleAlpha);
private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
@@ -52,13 +64,31 @@
private boolean mIsAtStashedRevealBounds = true;
- public StashedHandleViewController(TaskbarActivityContext activity, View stashedHandleView) {
+ public StashedHandleViewController(TaskbarActivityContext activity,
+ StashedHandleView stashedHandleView) {
mActivity = activity;
+ mPrefs = Utilities.getPrefs(mActivity);
mStashedHandleView = stashedHandleView;
+ mStashedHandleView.updateHandleColor(
+ mPrefs.getBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY, false));
final Resources resources = mActivity.getResources();
mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width);
mStashedHandleHeight = resources.getDimensionPixelSize(
R.dimen.taskbar_stashed_handle_height);
+ mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView,
+ new RegionSamplingHelper.SamplingCallback() {
+ @Override
+ public void onRegionDarknessChanged(boolean isRegionDark) {
+ mStashedHandleView.updateHandleColor(isRegionDark);
+ mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY,
+ isRegionDark).apply();
+ }
+
+ @Override
+ public Rect getSampledRegion(View sampledView) {
+ return mStashedHandleView.getSampledRegion();
+ }
+ }, Executors.UI_HELPER_EXECUTOR);
}
public void init(TaskbarControllers controllers) {
@@ -93,6 +123,10 @@
});
}
+ public void onDestroy() {
+ mRegionSamplingHelper.stopAndDestroy();
+ }
+
public AnimatedFloat getStashedHandleAlpha() {
return mTaskbarStashedHandleAlpha;
}
@@ -117,6 +151,16 @@
return handleRevealProvider.createRevealAnimator(mStashedHandleView, !isStashed);
}
+ public void onIsStashed(boolean isStashed) {
+ mRegionSamplingHelper.setWindowVisible(isStashed);
+ if (isStashed) {
+ mStashedHandleView.updateSampledRegion();
+ mRegionSamplingHelper.start(mStashedHandleView.getSampledRegion());
+ } else {
+ mRegionSamplingHelper.stop();
+ }
+ }
+
protected void updateStashedHandleAlpha() {
mStashedHandleView.setAlpha(mTaskbarStashedHandleAlpha.value);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index a90f17d..8c12567 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -43,6 +43,7 @@
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
@@ -84,7 +85,7 @@
private final TaskbarControllers mControllers;
private final WindowManager mWindowManager;
- private final RoundedCorner mLeftCorner, mRightCorner;
+ private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
private WindowManager.LayoutParams mWindowLayoutParams;
private boolean mIsFullscreen;
// The size we should return to when we call setTaskbarWindowFullscreen(false)
@@ -117,7 +118,7 @@
R.layout.taskbar, null, false);
TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
- View stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
+ StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
// Construct controllers.
mControllers = new TaskbarControllers(this,
@@ -173,12 +174,12 @@
return mNavMode == Mode.THREE_BUTTONS;
}
- public RoundedCorner getLeftCorner() {
- return mLeftCorner;
+ public int getLeftCornerRadius() {
+ return mLeftCorner == null ? 0 : mLeftCorner.getRadius();
}
- public RoundedCorner getRightCorner() {
- return mRightCorner;
+ public int getRightCornerRadius() {
+ return mRightCorner == null ? 0 : mRightCorner.getRadius();
}
@Override
@@ -235,6 +236,8 @@
systemUiStateFlags, forceUpdate);
mControllers.taskbarViewController.setImeIsVisible(
mControllers.navbarButtonsViewController.isImeVisible());
+ mControllers.taskbarViewController.setRecentsButtonDisabled(
+ mControllers.navbarButtonsViewController.isRecentsDisabled());
mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
}
@@ -247,7 +250,6 @@
return;
}
mControllers.rotationButtonController.onDisable2FlagChanged(state2);
- mControllers.taskbarKeyguardController.disableNavbarElements(state1, state2);
}
public void onSystemBarAttributesChanged(int displayId, int behavior) {
@@ -291,8 +293,7 @@
* Returns the default height of the window, including the static corner radii above taskbar.
*/
public int getDefaultTaskbarWindowHeight() {
- return mDeviceProfile.taskbarSize
- + Math.max(mLeftCorner.getRadius(), mRightCorner.getRadius());
+ return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
}
protected void onTaskbarIconClicked(View view) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 2927a63..1197543 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -78,6 +78,7 @@
taskbarKeyguardController.init(navbarButtonsViewController);
stashedHandleViewController.init(this);
taskbarStashController.init(this);
+ taskbarEduController.init(this);
}
/**
@@ -89,5 +90,6 @@
taskbarDragLayerController.onDestroy();
taskbarKeyguardController.onDestroy();
taskbarViewController.onDestroy();
+ stashedHandleViewController.onDestroy();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index 0848c35..b42a60c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -82,8 +82,8 @@
// Create the paths for the inverted rounded corners above the taskbar. Start with a filled
// square, and then subtracting out a circle from the appropriate corner.
- mLeftCornerRadius = mActivity.getLeftCorner().getRadius();
- mRightCornerRadius = mActivity.getRightCorner().getRadius();
+ mLeftCornerRadius = mActivity.getLeftCornerRadius();
+ mRightCornerRadius = mActivity.getRightCornerRadius();
Path square = new Path();
square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
Path circle = new Path();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
index c5a0fc1..fd5c2ea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
@@ -15,16 +15,72 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.content.res.Resources;
+import android.text.TextUtils;
+import android.view.View;
+
import com.android.launcher3.R;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.uioverrides.PredictedAppIcon;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
/** Handles the Taskbar Education flow. */
public class TaskbarEduController {
+ private static final long WAVE_ANIM_DELAY = 250;
+ private static final long WAVE_ANIM_STAGGER = 50;
+ private static final long WAVE_ANIM_EACH_ICON_DURATION = 633;
+ private static final long WAVE_ANIM_SLOT_MACHINE_DURATION = 1085;
+ // The fraction of each icon's animation at which we reach the top point of the wave.
+ private static final float WAVE_ANIM_FRACTION_TOP = 0.4f;
+ // The fraction of each icon's animation at which we reach the bottom, before overshooting.
+ private static final float WAVE_ANIM_FRACTION_BOTTOM = 0.9f;
+ private static final TimeInterpolator WAVE_ANIM_TO_TOP_INTERPOLATOR = FAST_OUT_SLOW_IN;
+ private static final TimeInterpolator WAVE_ANIM_TO_BOTTOM_INTERPOLATOR = ACCEL_2;
+ private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_INTERPOLATOR = DEACCEL;
+ private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR = ACCEL_DEACCEL;
+ private static final float WAVE_ANIM_ICON_SCALE = 1.2f;
+ // How many icons to cycle through in the slot machine (+ the original icon at each end).
+ private static final int WAVE_ANIM_SLOT_MACHINE_NUM_ICONS = 3;
+
private final TaskbarActivityContext mActivity;
+ private final float mWaveAnimTranslationY;
+ private final float mWaveAnimTranslationYReturnOvershoot;
+
+ // Initialized in init.
+ TaskbarControllers mControllers;
+
private TaskbarEduView mTaskbarEduView;
+ private Animator mAnim;
public TaskbarEduController(TaskbarActivityContext activity) {
mActivity = activity;
+
+ final Resources resources = activity.getResources();
+ mWaveAnimTranslationY = resources.getDimension(R.dimen.taskbar_edu_wave_anim_trans_y);
+ mWaveAnimTranslationYReturnOvershoot = resources.getDimension(
+ R.dimen.taskbar_edu_wave_anim_trans_y_return_overshoot);
+ }
+
+ public void init(TaskbarControllers controllers) {
+ mControllers = controllers;
}
void showEdu() {
@@ -32,10 +88,10 @@
mActivity.getDragLayer().post(() -> {
mTaskbarEduView = (TaskbarEduView) mActivity.getLayoutInflater().inflate(
R.layout.taskbar_edu, mActivity.getDragLayer(), false);
- mTaskbarEduView.addOnCloseListener(() -> {
- mTaskbarEduView = null;
- });
+ mTaskbarEduView.init(new TaskbarEduCallbacks());
+ mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null);
mTaskbarEduView.show();
+ startAnim(createWaveAnim());
});
}
@@ -44,4 +100,111 @@
mTaskbarEduView.close(true /* animate */);
}
}
+
+ /**
+ * Starts the given animation, ending the previous animation first if it's still playing.
+ */
+ private void startAnim(Animator anim) {
+ if (mAnim != null) {
+ mAnim.end();
+ }
+ mAnim = anim;
+ mAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnim = null;
+ }
+ });
+ mAnim.start();
+ }
+
+ /**
+ * Creates a staggered "wave" animation where each icon translates and scales up in succession.
+ */
+ private Animator createWaveAnim() {
+ AnimatorSet waveAnim = new AnimatorSet();
+ View[] icons = mControllers.taskbarViewController.getIconViews();
+ for (int i = 0; i < icons.length; i++) {
+ View icon = icons[i];
+ AnimatorSet iconAnim = new AnimatorSet();
+
+ Keyframe[] scaleKeyframes = new Keyframe[] {
+ Keyframe.ofFloat(0, 1f),
+ Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, WAVE_ANIM_ICON_SCALE),
+ Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 1f),
+ Keyframe.ofFloat(1f, 1f)
+ };
+ scaleKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
+ scaleKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
+
+ Keyframe[] translationYKeyframes = new Keyframe[] {
+ Keyframe.ofFloat(0, 0f),
+ Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, -mWaveAnimTranslationY),
+ Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 0f),
+ // Half of the remaining fraction overshoots, then the other half returns to 0.
+ Keyframe.ofFloat(
+ WAVE_ANIM_FRACTION_BOTTOM + (1 - WAVE_ANIM_FRACTION_BOTTOM) / 2f,
+ mWaveAnimTranslationYReturnOvershoot),
+ Keyframe.ofFloat(1f, 0f)
+ };
+ translationYKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
+ translationYKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
+ translationYKeyframes[3].setInterpolator(WAVE_ANIM_OVERSHOOT_INTERPOLATOR);
+ translationYKeyframes[4].setInterpolator(WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR);
+
+ iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
+ PropertyValuesHolder.ofKeyframe(SCALE_PROPERTY, scaleKeyframes))
+ .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
+ iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
+ PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y, translationYKeyframes))
+ .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
+
+ if (icon instanceof PredictedAppIcon) {
+ // Play slot machine animation through random icons from AllAppsList.
+ PredictedAppIcon predictedAppIcon = (PredictedAppIcon) icon;
+ ItemInfo itemInfo = (ItemInfo) icon.getTag();
+ List<BitmapInfo> iconsToAnimate = mControllers.uiController.getAppIconsForEdu()
+ .filter(appInfo -> !TextUtils.equals(appInfo.title, itemInfo.title))
+ .map(appInfo -> appInfo.bitmap)
+ .filter(bitmap -> !bitmap.isNullOrLowRes())
+ .collect(Collectors.toList());
+ // Pick n icons at random.
+ Collections.shuffle(iconsToAnimate);
+ if (iconsToAnimate.size() > WAVE_ANIM_SLOT_MACHINE_NUM_ICONS) {
+ iconsToAnimate = iconsToAnimate.subList(0, WAVE_ANIM_SLOT_MACHINE_NUM_ICONS);
+ }
+ Animator slotMachineAnim = predictedAppIcon.createSlotMachineAnim(iconsToAnimate);
+ if (slotMachineAnim != null) {
+ iconAnim.play(slotMachineAnim.setDuration(WAVE_ANIM_SLOT_MACHINE_DURATION));
+ }
+ }
+
+ iconAnim.setStartDelay(WAVE_ANIM_STAGGER * i);
+ waveAnim.play(iconAnim);
+ }
+ waveAnim.setStartDelay(WAVE_ANIM_DELAY);
+ return waveAnim;
+ }
+
+ /**
+ * Callbacks for {@link TaskbarEduView} to interact with its controller.
+ */
+ class TaskbarEduCallbacks {
+ void onPageChanged(int currentPage, int pageCount) {
+ if (currentPage == 0) {
+ mTaskbarEduView.updateStartButton(R.string.taskbar_edu_close,
+ v -> mTaskbarEduView.close(true /* animate */));
+ } else {
+ mTaskbarEduView.updateStartButton(R.string.taskbar_edu_previous,
+ v -> mTaskbarEduView.snapToPage(currentPage - 1));
+ }
+ if (currentPage == pageCount - 1) {
+ mTaskbarEduView.updateEndButton(R.string.taskbar_edu_done,
+ v -> mTaskbarEduView.close(true /* animate */));
+ } else {
+ mTaskbarEduView.updateEndButton(R.string.taskbar_edu_next,
+ v -> mTaskbarEduView.snapToPage(currentPage + 1));
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
new file mode 100644
index 0000000..5efcc4d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
@@ -0,0 +1,79 @@
+/*
+ * 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.taskbar;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_EDUCATION_DIALOG;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.PagedView;
+import com.android.launcher3.R;
+import com.android.launcher3.pageindicators.PageIndicatorDots;
+import com.android.launcher3.taskbar.TaskbarEduController.TaskbarEduCallbacks;
+import com.android.launcher3.views.ActivityContext;
+
+/** Horizontal carousel of tutorial screens for Taskbar Edu. */
+public class TaskbarEduPagedView extends PagedView<PageIndicatorDots> {
+
+ private TaskbarEduView mTaskbarEduView;
+ private TaskbarEduCallbacks mControllerCallbacks;
+
+ public TaskbarEduPagedView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+ }
+
+ void setTaskbarEduView(TaskbarEduView taskbarEduView) {
+ mTaskbarEduView = taskbarEduView;
+ mPageIndicator = taskbarEduView.findViewById(R.id.content_page_indicator);
+ initParentViews(taskbarEduView);
+ }
+
+ void setControllerCallbacks(TaskbarEduCallbacks controllerCallbacks) {
+ mControllerCallbacks = controllerCallbacks;
+ mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
+ }
+
+ @Override
+ protected int getChildGap() {
+ return mTaskbarEduView.getPaddingLeft() + mTaskbarEduView.getPaddingRight();
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ if (mMaxScroll > 0) {
+ mPageIndicator.setScroll(l, mMaxScroll);
+ }
+ }
+
+ @Override
+ protected void notifyPageSwitchListener(int prevPage) {
+ super.notifyPageSwitchListener(prevPage);
+ mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
+ }
+
+ @Override
+ protected boolean canScroll(float absVScroll, float absHScroll) {
+ return AbstractFloatingView.getTopOpenViewWithType(
+ ActivityContext.lookupContext(getContext()),
+ TYPE_ALL & ~TYPE_TASKBAR_EDUCATION_DIALOG) == null;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
index b5dab7e..8525427 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
@@ -15,12 +15,15 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Pair;
+import android.view.View;
+import android.widget.Button;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
@@ -30,10 +33,15 @@
public class TaskbarEduView extends AbstractSlideInView<TaskbarActivityContext>
implements Insettable {
+ private static final int DEFAULT_OPEN_DURATION = 500;
private static final int DEFAULT_CLOSE_DURATION = 200;
private final Rect mInsets = new Rect();
+ private Button mStartButton;
+ private Button mEndButton;
+ private TaskbarEduPagedView mPagedView;
+
public TaskbarEduView(Context context, AttributeSet attr) {
this(context, attr, 0);
}
@@ -43,6 +51,12 @@
super(context, attrs, defStyleAttr);
}
+ protected void init(TaskbarEduController.TaskbarEduCallbacks callbacks) {
+ if (mPagedView != null) {
+ mPagedView.setControllerCallbacks(callbacks);
+ }
+ }
+
@Override
protected void handleClose(boolean animate) {
handleClose(animate, DEFAULT_CLOSE_DURATION);
@@ -57,7 +71,10 @@
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findViewById(R.id.edu_view);
- findViewById(R.id.edu_close_button).setOnClickListener(v -> close(true /* animate */));
+ mStartButton = findViewById(R.id.edu_start_button);
+ mEndButton = findViewById(R.id.edu_end_button);
+ mPagedView = findViewById(R.id.content);
+ mPagedView.setTaskbarEduView(this);
}
@Override
@@ -82,6 +99,12 @@
}
@Override
+ protected Pair<View, String> getAccessibilityTarget() {
+ return Pair.create(mContent, mIsOpen ? getContext().getString(R.string.taskbar_edu_opened)
+ : getContext().getString(R.string.taskbar_edu_closed));
+ }
+
+ @Override
protected int getScrimColor(Context context) {
return context.getResources().getColor(R.color.widgets_picker_scrim);
}
@@ -107,7 +130,21 @@
mIsOpen = true;
mOpenCloseAnimator.setValues(
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
- mOpenCloseAnimator.setInterpolator(FAST_OUT_SLOW_IN);
- mOpenCloseAnimator.start();
+ mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
+ mOpenCloseAnimator.setDuration(DEFAULT_OPEN_DURATION).start();
+ }
+
+ void snapToPage(int page) {
+ mPagedView.snapToPage(page);
+ }
+
+ void updateStartButton(int textResId, OnClickListener onClickListener) {
+ mStartButton.setText(textResId);
+ mStartButton.setOnClickListener(onClickListener);
+ }
+
+ void updateEndButton(int textResId, OnClickListener onClickListener) {
+ mEndButton.setText(textResId);
+ mEndButton.setOnClickListener(onClickListener);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index a2039b6..834cd9c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -1,7 +1,10 @@
package com.android.launcher3.taskbar;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import android.app.KeyguardManager;
@@ -9,7 +12,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.view.View;
/**
* Controller for managing keyguard state for taskbar
@@ -17,10 +19,11 @@
public class TaskbarKeyguardController {
private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING |
- SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING;
+ SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING |
+ SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
+ SYSUI_STATE_BACK_DISABLED;
private final TaskbarActivityContext mContext;
- private int mDisabledNavIcons;
private int mKeyguardSysuiFlags;
private boolean mBouncerShowing;
private NavbarButtonsViewController mNavbarButtonsViewController;
@@ -70,22 +73,13 @@
mIsScreenOff = false;
}
- public void disableNavbarElements(int state1, int state2) {
- if (mDisabledNavIcons == state1) {
- // no change
- return;
- }
- mDisabledNavIcons = state1;
- updateIconsForBouncer();
- }
-
/**
* Hides/shows taskbar when keyguard is up
*/
private void updateIconsForBouncer() {
- boolean disableBack = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_BACK) != 0;
- boolean disableRecent = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_RECENT) != 0;
- boolean disableHome = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_HOME) != 0;
+ boolean disableBack = (mKeyguardSysuiFlags & SYSUI_STATE_BACK_DISABLED) != 0;
+ boolean disableRecent = (mKeyguardSysuiFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ boolean disableHome = (mKeyguardSysuiFlags & SYSUI_STATE_HOME_DISABLED) != 0;
boolean onlyBackEnabled = !disableBack && disableRecent && disableHome;
boolean showBackForBouncer = onlyBackEnabled &&
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 949df82..1f5ff02 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -285,6 +285,7 @@
@Override
public void onAnimationStart(Animator animation) {
mIsStashed = isStashed;
+ onIsStashed(mIsStashed);
}
@Override
@@ -326,4 +327,8 @@
animateForward ? UNSTASHED_TASKBAR_HANDLE_HINT_SCALE : 1)
.setDuration(TASKBAR_HINT_STASH_DURATION).start();
}
+
+ private void onIsStashed(boolean isStashed) {
+ mControllers.stashedHandleViewController.onIsStashed(isStashed);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index df88e02..c0312a0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -17,6 +17,10 @@
import android.graphics.Rect;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
+
+import java.util.stream.Stream;
+
/**
* Base class for providing different taskbar UI
*/
@@ -35,4 +39,8 @@
protected void updateContentInsets(Rect outContentInsets) { }
protected void onStashedInAppChanged() { }
+
+ public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
+ return Stream.empty();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index a4a92f7..5144d9a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -90,6 +90,9 @@
// We layout the icons to be of mIconTouchSize in width and height
mItemMarginLeftRight = actualMargin - (mIconTouchSize - actualIconSize) / 2;
mItemPadding = (mIconTouchSize - actualIconSize) / 2;
+
+ // Needed to draw folder leave-behind when opening one.
+ setWillNotDraw(false);
}
protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) {
@@ -115,6 +118,7 @@
*/
protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
int nextViewIndex = 0;
+ int numViewsAnimated = 0;
for (int i = 0; i < hotseatItemInfos.length; i++) {
ItemInfo hotseatItemInfo = hotseatItemInfos[i];
@@ -170,8 +174,14 @@
// Apply the Hotseat ItemInfos, or hide the view if there is none for a given index.
if (hotseatView instanceof BubbleTextView
&& hotseatItemInfo instanceof WorkspaceItemInfo) {
- ((BubbleTextView) hotseatView).applyFromWorkspaceItem(
- (WorkspaceItemInfo) hotseatItemInfo);
+ BubbleTextView btv = (BubbleTextView) hotseatView;
+ WorkspaceItemInfo workspaceInfo = (WorkspaceItemInfo) hotseatItemInfo;
+
+ boolean animate = btv.shouldAnimateIconChange((WorkspaceItemInfo) hotseatItemInfo);
+ btv.applyFromWorkspaceItem(workspaceInfo, animate, numViewsAnimated);
+ if (animate) {
+ numViewsAnimated++;
+ }
}
setClickAndLongClickListenersForIcon(hotseatView);
nextViewIndex++;
@@ -256,6 +266,18 @@
return mIconLayoutBounds;
}
+ /**
+ * Returns the app icons currently shown in the taskbar.
+ */
+ public View[] getIconViews() {
+ final int count = getChildCount();
+ View[] icons = new View[count];
+ for (int i = 0; i < count; i++) {
+ icons[i] = getChildAt(i);
+ }
+ return icons;
+ }
+
// FolderIconParent implemented methods.
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 1882762..40b0e18 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -44,6 +44,8 @@
public static final int ALPHA_INDEX_IME = 1;
public static final int ALPHA_INDEX_KEYGUARD = 2;
public static final int ALPHA_INDEX_STASH = 3;
+ public static final int ALPHA_INDEX_RECENTS_DISABLED = 4;
+ private static final int NUM_ALPHA_CHANNELS = 5;
private final TaskbarActivityContext mActivity;
private final TaskbarView mTaskbarView;
@@ -67,7 +69,7 @@
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
mActivity = activity;
mTaskbarView = taskbarView;
- mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, 4);
+ mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, NUM_ALPHA_CHANNELS);
mTaskbarIconAlpha.setUpdateVisibility(true);
mModelCallbacks = new TaskbarModelCallbacks(activity, mTaskbarView);
}
@@ -101,6 +103,14 @@
}
/**
+ * Should be called when the recents button is disabled, so we can hide taskbar icons as well.
+ */
+ public void setRecentsButtonDisabled(boolean isDisabled) {
+ // TODO: check TaskbarStashController#supportsStashing(), to stash instead of setting alpha.
+ mTaskbarIconAlpha.getProperty(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1);
+ }
+
+ /**
* Sets OnClickListener and OnLongClickListener for the given view.
*/
public void setClickAndLongClickListenersForIcon(View icon) {
@@ -111,6 +121,10 @@
return mTaskbarView.getIconLayoutBounds();
}
+ public View[] getIconViews() {
+ return mTaskbarView.getIconViews();
+ }
+
public AnimatedFloat getTaskbarIconScaleForStash() {
return mTaskbarIconScaleForStash;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index d839a36..ee6e8ce 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -15,6 +15,16 @@
*/
package com.android.launcher3.uioverrides;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
@@ -23,8 +33,10 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Process;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -35,6 +47,8 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.icons.LauncherIcons;
@@ -45,6 +59,10 @@
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.DoubleShadowBubbleTextView;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
* A BubbleTextView with a ring around it's drawable
*/
@@ -53,6 +71,9 @@
private static final int RING_SHADOW_COLOR = 0x99000000;
private static final float RING_EFFECT_RATIO = 0.095f;
+ private static final long ICON_CHANGE_ANIM_DURATION = 360;
+ private static final long ICON_CHANGE_ANIM_STAGGER = 50;
+
boolean mIsDrawingDot = false;
private final DeviceProfile mDeviceProfile;
private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -67,6 +88,25 @@
private int mPlateColor;
boolean mDrawForDrag = false;
+ // Used for the "slot-machine" education animation.
+ private List<Drawable> mSlotMachineIcons;
+ private Animator mSlotMachineAnim;
+ private float mSlotMachineIconTranslationY;
+
+ private static final FloatProperty<PredictedAppIcon> SLOT_MACHINE_TRANSLATION_Y =
+ new FloatProperty<PredictedAppIcon>("slotMachineTranslationY") {
+ @Override
+ public void setValue(PredictedAppIcon predictedAppIcon, float transY) {
+ predictedAppIcon.mSlotMachineIconTranslationY = transY;
+ predictedAppIcon.invalidate();
+ }
+
+ @Override
+ public Float get(PredictedAppIcon predictedAppIcon) {
+ return predictedAppIcon.mSlotMachineIconTranslationY;
+ }
+ };
+
public PredictedAppIcon(Context context) {
this(context, null, 0);
}
@@ -88,15 +128,38 @@
@Override
public void onDraw(Canvas canvas) {
int count = canvas.save();
+ boolean isSlotMachineAnimRunning = mSlotMachineAnim != null;
if (!mIsPinned) {
drawEffect(canvas);
+ if (isSlotMachineAnimRunning) {
+ // Clip to to outside of the ring during the slot machine animation.
+ canvas.clipPath(mRingPath);
+ }
canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
}
- super.onDraw(canvas);
+ if (isSlotMachineAnimRunning) {
+ drawSlotMachineIcons(canvas);
+ } else {
+ super.onDraw(canvas);
+ }
canvas.restoreToCount(count);
}
+ private void drawSlotMachineIcons(Canvas canvas) {
+ canvas.translate((getWidth() - getIconSize()) / 2f,
+ (getHeight() - getIconSize()) / 2f + mSlotMachineIconTranslationY);
+ for (Drawable icon : mSlotMachineIcons) {
+ icon.setBounds(0, 0, getIconSize(), getIconSize());
+ icon.draw(canvas);
+ canvas.translate(0, getSlotMachineIconPlusSpacingSize());
+ }
+ }
+
+ private float getSlotMachineIconPlusSpacingSize() {
+ return getIconSize() + getOutlineOffsetY();
+ }
+
@Override
protected void drawDotIfNecessary(Canvas canvas) {
mIsDrawingDot = true;
@@ -109,9 +172,17 @@
}
@Override
- public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
- super.applyFromWorkspaceItem(info);
- mPlateColor = ColorUtils.setAlphaComponent(mDotParams.color, 200);
+ public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
+ // Create the slot machine animation first, since it uses the current icon to start.
+ Animator slotMachineAnim = animate
+ ? createSlotMachineAnim(Collections.singletonList(info.bitmap), false)
+ : null;
+ super.applyFromWorkspaceItem(info, animate, staggerIndex);
+ int oldPlateColor = mPlateColor;
+ int newPlateColor = ColorUtils.setAlphaComponent(mDotParams.color, 200);
+ if (!animate) {
+ mPlateColor = newPlateColor;
+ }
if (mIsPinned) {
setContentDescription(info.contentDescription);
} else {
@@ -119,6 +190,76 @@
getContext().getString(R.string.hotseat_prediction_content_description,
info.contentDescription));
}
+
+ if (animate) {
+ ValueAnimator plateColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(),
+ oldPlateColor, newPlateColor);
+ plateColorAnim.addUpdateListener(valueAnimator -> {
+ mPlateColor = (int) valueAnimator.getAnimatedValue();
+ invalidate();
+ });
+ AnimatorSet changeIconAnim = new AnimatorSet();
+ if (slotMachineAnim != null) {
+ changeIconAnim.play(slotMachineAnim);
+ }
+ changeIconAnim.play(plateColorAnim);
+ changeIconAnim.setStartDelay(staggerIndex * ICON_CHANGE_ANIM_STAGGER);
+ changeIconAnim.setDuration(ICON_CHANGE_ANIM_DURATION).start();
+ }
+ }
+
+ /**
+ * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
+ * and ending with the original icon.
+ */
+ public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate) {
+ return createSlotMachineAnim(iconsToAnimate, true);
+ }
+
+ /**
+ * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
+ * with the original icon, then cycling through the given icons, optionally ending back with
+ * the original icon.
+ * @param endWithOriginalIcon Whether we should land back on the icon we started with, rather
+ * than the last item in iconsToAnimate.
+ */
+ public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate,
+ boolean endWithOriginalIcon) {
+ if (mIsPinned || iconsToAnimate == null || iconsToAnimate.isEmpty()) {
+ return null;
+ }
+ if (mSlotMachineAnim != null) {
+ mSlotMachineAnim.end();
+ }
+
+ // Bookend the other animating icons with the original icon on both ends.
+ mSlotMachineIcons = new ArrayList<>(iconsToAnimate.size() + 2);
+ mSlotMachineIcons.add(getIcon());
+ iconsToAnimate.stream()
+ .map(iconInfo -> iconInfo.newThemedIcon(mContext))
+ .forEach(mSlotMachineIcons::add);
+ if (endWithOriginalIcon) {
+ mSlotMachineIcons.add(getIcon());
+ }
+
+ float finalTrans = -getSlotMachineIconPlusSpacingSize() * (mSlotMachineIcons.size() - 1);
+ Keyframe[] keyframes = new Keyframe[] {
+ Keyframe.ofFloat(0f, 0f),
+ Keyframe.ofFloat(0.82f, finalTrans - getOutlineOffsetY() / 2f), // Overshoot
+ Keyframe.ofFloat(1f, finalTrans) // Ease back into the final position
+ };
+ keyframes[1].setInterpolator(ACCEL_DEACCEL);
+ keyframes[2].setInterpolator(ACCEL_DEACCEL);
+
+ mSlotMachineAnim = ObjectAnimator.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofKeyframe(SLOT_MACHINE_TRANSLATION_Y, keyframes));
+ mSlotMachineAnim.addListener(AnimatorListeners.forEndCallback(() -> {
+ mSlotMachineIcons = null;
+ mSlotMachineAnim = null;
+ mSlotMachineIconTranslationY = 0;
+ invalidate();
+ }));
+ return mSlotMachineAnim;
}
/**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 069af96..14bc380 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -84,9 +84,9 @@
import com.android.quickstep.util.QuickstepOnboardingPrefs;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.unfold.UnfoldTransitionFactory;
-import com.android.unfold.UnfoldTransitionProgressProvider;
-import com.android.unfold.config.UnfoldTransitionConfig;
+import com.android.systemui.unfold.UnfoldTransitionFactory;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.config.UnfoldTransitionConfig;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index 1882a0c..9fc0450 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -43,8 +43,12 @@
@Override
public float getSplitSelectTranslation(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
- int splitPosition = recentsView.getSplitPlaceholder()
- .getActiveSplitPositionOption().mStagePosition;
+//<<<<<<< HEAD
+// int splitPosition = recentsView.getSplitPlaceholder()
+// .getActiveSplitPositionOption().stagePosition;
+//=======
+ int splitPosition = recentsView.getSplitPlaceholder().getActiveSplitStagePosition();
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
if (!recentsView.shouldShiftThumbnailsForSplitSelect(splitPosition)) {
return 0f;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index fe16b33..6e90a3a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -65,6 +65,7 @@
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
@@ -87,6 +88,7 @@
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.tracing.InputConsumerProto;
import com.android.launcher3.tracing.SwipeHandlerProto;
import com.android.launcher3.util.TraceHelper;
@@ -876,6 +878,9 @@
*/
@UiThread
public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "3");
+ }
float flingThreshold = mContext.getResources()
.getDimension(R.dimen.quickstep_fling_threshold_speed);
boolean isFling = mGestureStarted && !mIsMotionPaused
@@ -1037,6 +1042,9 @@
@UiThread
private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
boolean isCancel) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "4");
+ }
long duration = MAX_SWIPE_DURATION;
float currentShift = mCurrentShift.value;
final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
@@ -1155,6 +1163,9 @@
@UiThread
private void animateToProgress(float start, float end, long duration, Interpolator interpolator,
GestureEndTarget target, PointF velocityPxPerMs) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "5");
+ }
runOnRecentsAnimationStart(() -> animateToProgressInternal(start, end, duration,
interpolator, target, velocityPxPerMs));
}
@@ -1205,6 +1216,9 @@
}
}
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "7, end target=" + mGestureState.getEndTarget());
+ }
if (mGestureState.getEndTarget() == HOME) {
getOrientationHandler().adjustFloatingIconStartVelocity(velocityPxPerMs);
final RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets != null
@@ -1219,6 +1233,9 @@
&& runningTaskTarget.allowEnterPip
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
&& runningTaskTarget.taskInfo.pictureInPictureParams.isAutoEnterEnabled();
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "8, class=" + getClass().getSimpleName());
+ }
HomeAnimationFactory homeAnimFactory =
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
@@ -1812,6 +1829,9 @@
* be run when it is next started.
*/
protected void runOnRecentsAnimationStart(Runnable action) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "6");
+ }
if (mRecentsAnimationTargets == null) {
mRecentsAnimationStartCallbacks.add(action);
} else {
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index e781160..6298bb8 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -53,7 +53,6 @@
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -203,33 +202,6 @@
}
/**
- * Sets the task size in {@param outRect} taking split screened windows into account.
- * We assume combined height of both tasks will be same as one normal task, then we'll modify
- * the task height/width based on the ratio of task screen space bounds from
- * {@param splitInfo}
- *
- * @param desiredStageBounds whether task size for top/left or bottom/right needs to be computed
- */
- public final void calculateStagedSplitTaskSize(Context context, DeviceProfile dp, Rect outRect,
- SplitConfigurationOptions.StagedSplitBounds splitInfo,
- @SplitConfigurationOptions.StagePosition int desiredStageBounds) {
- calculateTaskSize(context, dp, outRect);
-
- // TODO(b/181705607) Change for landscape vs portrait
- float totalHeight = splitInfo.mLeftTopBounds.height()
- + splitInfo.mRightBottomBounds.height()
- + splitInfo.mDividerBounds.height() / 2f;
- float topTaskPercent = splitInfo.mLeftTopBounds.height() / totalHeight;
- if (desiredStageBounds == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- float diff = outRect.height() * (1f - topTaskPercent);
- outRect.bottom -= diff;
- } else {
- float diff = outRect.height() * topTaskPercent;
- outRect.top += diff;
- }
- }
-
- /**
* Calculates the taskView size for the provided device configuration.
*/
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
@@ -290,19 +262,35 @@
public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
if (dp.isMultiWindowMode) {
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
- if (TaskView.clipStatusAndNavBars(dp)) {
- out.x = bounds.availableSize.x;
- out.y = bounds.availableSize.y;
- } else {
- out.x = bounds.availableSize.x + bounds.insets.left + bounds.insets.right;
- out.y = bounds.availableSize.y + bounds.insets.top + bounds.insets.bottom;
+ out.x = bounds.availableSize.x;
+ out.y = bounds.availableSize.y;
+ if (!TaskView.clipLeft(dp)) {
+ out.x += bounds.insets.left;
}
- } else if (TaskView.clipStatusAndNavBars(dp)) {
- out.x = dp.availableWidthPx;
- out.y = dp.availableHeightPx;
+ if (!TaskView.clipRight(dp)) {
+ out.x += bounds.insets.right;
+ }
+ if (!TaskView.clipTop(dp)) {
+ out.y += bounds.insets.top;
+ }
+ if (!TaskView.clipBottom(dp)) {
+ out.y += bounds.insets.bottom;
+ }
} else {
out.x = dp.widthPx;
out.y = dp.heightPx;
+ if (TaskView.clipLeft(dp)) {
+ out.x -= dp.getInsets().left;
+ }
+ if (TaskView.clipRight(dp)) {
+ out.x -= dp.getInsets().right;
+ }
+ if (TaskView.clipTop(dp)) {
+ out.y -= dp.getInsets().top;
+ }
+ if (TaskView.clipBottom(dp)) {
+ out.y -= Math.max(dp.getInsets().bottom, dp.taskbarSize);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index ec6032d..773817f 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -45,6 +45,7 @@
import android.os.Messenger;
import android.os.ParcelUuid;
import android.os.UserHandle;
+import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -57,6 +58,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.testing.TestProtocol;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.AppCloseConfig;
@@ -138,6 +140,10 @@
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
Intent intent = new Intent(mGestureState.getHomeIntent());
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME,
+ "createHomeAnimationFactory: " + intent.toShortString(true, true, true, false));
+ }
mActiveAnimationFactory.addGestureContract(intent);
try {
mContext.startActivity(intent, options.toBundle());
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 35a851a..81e6917 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -462,7 +462,7 @@
+ "mRotation: " + mRotation
+ " this: " + this);
}
- event.transform(mTmpMatrix);
+ event.applyTransform(mTmpMatrix);
return true;
}
mTmpPoint[0] = event.getX();
@@ -478,7 +478,7 @@
}
if (contains(mTmpPoint[0], mTmpPoint[1])) {
- event.transform(mTmpMatrix);
+ event.applyTransform(mTmpMatrix);
return true;
}
return false;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index e948221..3c05a3e 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -20,12 +20,14 @@
import android.graphics.Rect;
import android.util.ArraySet;
+import android.util.Log;
import android.view.RemoteAnimationTarget;
import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -95,6 +97,9 @@
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
Rect homeContentInsets, Rect minimizedHomeBounds) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "RecentsAnimationCallbacks.onAnimationStart");
+ }
// Convert appTargets to type RemoteAnimationTarget for all apps except Home app
RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
.filter(remoteAnimationTarget ->
@@ -116,6 +121,10 @@
mController::finishAnimationToApp);
} else {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME,
+ "RecentsAnimationCallbacks.onAnimationStart callback");
+ }
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(mController, targets);
}
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index ec51599..1f57e99 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -278,6 +278,8 @@
RemoteAnimationTargetCompat primaryTaskTarget;
RemoteAnimationTargetCompat secondaryTaskTarget;
+ // TODO(b/197568823) Determine if we need to exclude assistant as one of the targets we
+ // animate
if (!mIsSwipeForStagedSplit) {
primaryTaskTarget = targets.findTask(mGestureState.getRunningTaskId());
mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index f49c9b0..eb5c43f 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -218,6 +218,11 @@
}
}
+ private void enterSplitSelect() {
+ RecentsView overviewPanel = mThumbnailView.getTaskView().getRecentsView();
+ overviewPanel.initiateSplitSelect(mThumbnailView.getTaskView());
+ }
+
/**
* Called when the overlay is no longer used.
*/
@@ -323,6 +328,10 @@
public void onScreenshot() {
endLiveTileMode(() -> saveScreenshot(mTask));
}
+
+ public void onSplit() {
+ endLiveTileMode(TaskOverlay.this::enterSplitSelect);
+ }
}
}
@@ -336,5 +345,8 @@
/** User has indicated they want to screenshot the current task. */
void onScreenshot();
+
+ /** User wants to start split screen with current app. */
+ void onSplit();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index a078bf3..559125e 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -100,7 +100,7 @@
private SplitPositionOption mSplitPositionOption;
public SplitSelectSystemShortcut(BaseDraggingActivity target, TaskView taskView,
SplitPositionOption option) {
- super(option.mIconResId, option.mTextResId, target, taskView.getItemInfo());
+ super(option.iconResId, option.textResId, target, taskView.getItemInfo());
mTaskView = taskView;
mSplitPositionOption = option;
setEnabled(taskView.getRecentsView().getTaskViewCount() > 1);
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 20eff34..2e42392 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -146,7 +146,7 @@
private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
public static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
- SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);
+ SystemProperties.getBoolean("persist.debug.per_window_input_rotation", true);
private int mBackGestureNotificationCounter = -1;
@Nullable
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 725c7c4..e6285f2 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -50,6 +50,7 @@
import androidx.annotation.UiThread;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.tracing.InputConsumerProto;
@@ -356,6 +357,9 @@
}
case ACTION_CANCEL:
case ACTION_UP: {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "1");
+ }
if (DEBUG_FAILED_QUICKSWITCH && !mPassedWindowMoveSlop) {
float displacementX = mLastPos.x - mDownPos.x;
float displacementY = mLastPos.y - mDownPos.y;
@@ -409,6 +413,9 @@
* the animation can still be running.
*/
private void finishTouchTracking(MotionEvent ev) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "2");
+ }
Object traceToken = TraceHelper.INSTANCE.beginSection(UP_EVT,
FLAG_CHECK_FOR_RACE_CONDITIONS);
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 957f776..2f3a912 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -68,7 +68,6 @@
showFeedback(R.string.assistant_gesture_feedback_swipe_too_far_from_corner);
break;
case ASSISTANT_COMPLETED:
- hideFeedback(true);
showRippleEffect(null);
showFeedback(R.string.assistant_gesture_tutorial_playground_subtitle);
break;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 3cb22f4..f2402e3 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -18,10 +18,9 @@
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
+import android.annotation.LayoutRes;
import android.graphics.PointF;
-import androidx.appcompat.content.res.AppCompatResources;
-
import com.android.launcher3.R;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
@@ -44,8 +43,18 @@
}
@Override
- protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
- return R.drawable.mock_conversation;
+ protected int getMockAppTaskLayoutResId() {
+ return getMockAppTaskCurrentPageLayoutResId();
+ }
+
+ @LayoutRes
+ int getMockAppTaskCurrentPageLayoutResId() {
+ return R.layout.gesture_tutorial_mock_conversation;
+ }
+
+ @LayoutRes
+ int getMockAppTaskPreviousPageLayoutResId() {
+ return R.layout.gesture_tutorial_mock_conversation_list;
}
@Override
@@ -70,10 +79,8 @@
switch (result) {
case BACK_COMPLETED_FROM_LEFT:
case BACK_COMPLETED_FROM_RIGHT:
- mTutorialFragment.releaseGestureVideoView();
- hideFeedback(true);
- mFakeTaskView.setBackground(AppCompatResources.getDrawable(mContext,
- R.drawable.mock_conversations_list));
+ mTutorialFragment.releaseFeedbackAnimation();
+ updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
int subtitleResId = mTutorialFragment.isAtFinalStep()
? R.string.back_gesture_feedback_complete_without_follow_up
: R.string.back_gesture_feedback_complete_with_overview_follow_up;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 1740f68..f54734d 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -15,6 +15,10 @@
*/
package com.android.quickstep.interaction;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.view.MotionEvent;
import android.view.View;
@@ -23,18 +27,76 @@
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
+import java.util.ArrayList;
+
/** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment {
+
@Nullable
@Override
- Integer getFeedbackVideoResId(boolean forDarkMode) {
- return R.drawable.gesture_tutorial_motion_back;
+ Integer getEdgeAnimationResId() {
+ return R.drawable.gesture_tutorial_loop_back;
}
@Nullable
@Override
- Integer getGestureVideoResId() {
- return R.drawable.gesture_tutorial_loop_back;
+ protected Animator createGestureAnimation() {
+ if (!(mTutorialController instanceof BackGestureTutorialController)) {
+ return null;
+ }
+ BackGestureTutorialController controller =
+ (BackGestureTutorialController) mTutorialController;
+ float fingerDotStartTranslationX = (float) -(mRootView.getWidth() / 2);
+
+ AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+ fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mFingerDotView.setTranslationX(fingerDotStartTranslationX);
+ }
+ });
+
+ ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.TRANSLATION_X, fingerDotStartTranslationX, 0);
+ translationAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ controller.updateFakeAppTaskViewLayout(
+ controller.getMockAppTaskPreviousPageLayoutResId());
+ }
+ });
+ translationAnimator.setDuration(1000);
+
+ Animator animationPause = controller.createAnimationPause();
+ animationPause.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ controller.updateFakeAppTaskViewLayout(
+ controller.getMockAppTaskCurrentPageLayoutResId());
+ }
+ });
+ ArrayList<Animator> animators = new ArrayList<>();
+
+ animators.add(fingerDotAppearanceAnimator);
+ animators.add(translationAnimator);
+ animators.add(controller.createFingerDotDisappearanceAnimatorSet());
+ animators.add(animationPause);
+
+ AnimatorSet finalAnimation = new AnimatorSet();
+ finalAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ controller.updateFakeAppTaskViewLayout(
+ controller.getMockAppTaskCurrentPageLayoutResId());
+ }
+ });
+ finalAnimation.playSequentially(animators);
+
+ return finalAnimation;
}
@Override
@@ -49,6 +111,7 @@
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
+ releaseFeedbackAnimation();
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
index 0521db4..7465db3 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
@@ -282,9 +282,7 @@
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
int currentNightMode =
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
- mPaint.setColor(context.getColor(currentNightMode == Configuration.UI_MODE_NIGHT_YES
- ? R.color.back_arrow_color_light
- : R.color.back_arrow_color_dark));
+ mPaint.setColor(context.getColor(R.color.gesture_tutorial_back_arrow_color));
loadDimens();
updateArrowDirection();
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 819c91c..307a8fd 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -42,8 +42,8 @@
}
@Override
- protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
- return forDarkMode ? R.drawable.mock_webpage_dark_mode : R.drawable.mock_webpage_light_mode;
+ protected int getMockAppTaskLayoutResId() {
+ return R.layout.gesture_tutorial_mock_webpage;
}
@Override
@@ -80,7 +80,7 @@
case HOME_NAVIGATION:
switch (result) {
case HOME_GESTURE_COMPLETED: {
- mTutorialFragment.releaseGestureVideoView();
+ mTutorialFragment.releaseFeedbackAnimation();
animateFakeTaskViewHome(finalVelocity, null);
int subtitleResId = mTutorialFragment.isAtFinalStep()
? R.string.home_gesture_feedback_complete_without_follow_up
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 9572637..dcae07d 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -15,25 +15,73 @@
*/
package com.android.quickstep.interaction;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.view.MotionEvent;
+import android.view.View;
+
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
+import java.util.ArrayList;
+
/** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment {
+
@Nullable
@Override
- Integer getFeedbackVideoResId(boolean forDarkMode) {
- return forDarkMode
- ? R.drawable.gesture_tutorial_motion_home_dark_mode
- : R.drawable.gesture_tutorial_motion_home_light_mode;
+ Integer getEdgeAnimationResId() {
+ return R.drawable.gesture_tutorial_loop_home;
}
@Nullable
@Override
- Integer getGestureVideoResId() {
- return R.drawable.gesture_tutorial_loop_home;
+ protected Animator createGestureAnimation() {
+ if (!(mTutorialController instanceof HomeGestureTutorialController)) {
+ return null;
+ }
+ float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
+ HomeGestureTutorialController controller =
+ (HomeGestureTutorialController) mTutorialController;
+
+ AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+ fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mFingerDotView.setTranslationY(fingerDotStartTranslationY);
+ }
+ });
+
+ Animator animationPause = controller.createAnimationPause();
+ animationPause.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ controller.resetFakeTaskView();
+ }
+ });
+ ArrayList<Animator> animators = new ArrayList<>();
+
+ animators.add(fingerDotAppearanceAnimator);
+ animators.add(controller.createFingerDotHomeSwipeAnimator(fingerDotStartTranslationY));
+ animators.add(controller.createFingerDotDisappearanceAnimatorSet());
+ animators.add(animationPause);
+
+ AnimatorSet finalAnimation = new AnimatorSet();
+ finalAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ controller.resetFakeTaskView();
+ }
+ });
+ finalAnimation.playSequentially(animators);
+
+ return finalAnimation;
}
@Override
@@ -45,4 +93,10 @@
Class<? extends TutorialController> getControllerClass() {
return HomeGestureTutorialController.class;
}
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ releaseFeedbackAnimation();
+ return super.onTouch(view, motionEvent);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 77ddb2b..b38a641 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -49,8 +49,8 @@
}
@Override
- protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
- return R.drawable.mock_conversations_list;
+ protected int getMockAppTaskLayoutResId() {
+ return R.layout.gesture_tutorial_mock_conversation_list;
}
@Override
@@ -98,13 +98,8 @@
showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
break;
case OVERVIEW_GESTURE_COMPLETED:
- mTutorialFragment.releaseGestureVideoView();
- PendingAnimation anim = new PendingAnimation(300);
- anim.setFloat(mTaskViewSwipeUpAnimation
- .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
- AnimatorSet animset = anim.buildAnim();
- animset.start();
- mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
+ mTutorialFragment.releaseFeedbackAnimation();
+ animateTaskViewToOverview();
onMotionPaused(true /*arbitrary value*/);
int subtitleResId = mTutorialFragment.getNumSteps() > 1
&& mTutorialFragment.isAtFinalStep()
@@ -126,4 +121,13 @@
break;
}
}
+
+ public void animateTaskViewToOverview() {
+ PendingAnimation anim = new PendingAnimation(300);
+ anim.setFloat(mTaskViewSwipeUpAnimation
+ .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
+ AnimatorSet animset = anim.buildAnim();
+ animset.start();
+ mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index d2ec327..968412b 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -15,25 +15,96 @@
*/
package com.android.quickstep.interaction;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.view.MotionEvent;
+import android.view.View;
+
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
+import java.util.ArrayList;
+
/** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment {
+
@Nullable
@Override
- Integer getFeedbackVideoResId(boolean forDarkMode) {
- return forDarkMode
- ? R.drawable.gesture_tutorial_motion_overview_dark_mode
- : R.drawable.gesture_tutorial_motion_overview_light_mode;
+ Integer getEdgeAnimationResId() {
+ return R.drawable.gesture_tutorial_loop_overview;
}
@Nullable
@Override
- Integer getGestureVideoResId() {
- return R.drawable.gesture_tutorial_loop_overview;
+ protected Animator createGestureAnimation() {
+ if (!(mTutorialController instanceof OverviewGestureTutorialController)) {
+ return null;
+ }
+ float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
+ OverviewGestureTutorialController controller =
+ (OverviewGestureTutorialController) mTutorialController;
+
+ AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+ fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+
+ mFingerDotView.setTranslationY(fingerDotStartTranslationY);
+ }
+ });
+
+ Animator swipeAnimator =
+ controller.createFingerDotOverviewSwipeAnimator(fingerDotStartTranslationY);
+ swipeAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mFakePreviousTaskView.setVisibility(View.VISIBLE);
+ controller.onMotionPaused(true /*arbitrary value*/);
+ }
+ });
+
+ AnimatorSet fingerDotDisappearanceAnimator =
+ controller.createFingerDotDisappearanceAnimatorSet();
+ fingerDotDisappearanceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ controller.animateTaskViewToOverview();
+ }
+ });
+
+ Animator animationPause = controller.createAnimationPause();
+ animationPause.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ controller.resetFakeTaskView();
+ }
+ });
+ ArrayList<Animator> animators = new ArrayList<>();
+
+ animators.add(fingerDotAppearanceAnimator);
+ animators.add(swipeAnimator);
+ animators.add(controller.createAnimationPause());
+ animators.add(fingerDotDisappearanceAnimator);
+ animators.add(animationPause);
+
+ AnimatorSet finalAnimation = new AnimatorSet();
+ finalAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ controller.resetFakeTaskView();
+ }
+ });
+ finalAnimation.playSequentially(animators);
+
+ return finalAnimation;
}
@Override
@@ -45,4 +116,10 @@
Class<? extends TutorialController> getControllerClass() {
return OverviewGestureTutorialController.class;
}
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ releaseFeedbackAnimation();
+ return super.onTouch(view, motionEvent);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index db1afc2..ac0c17d 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -16,8 +16,10 @@
package com.android.quickstep.interaction;
import android.content.Context;
+import android.graphics.Insets;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.WindowInsets;
import android.widget.RelativeLayout;
import androidx.fragment.app.FragmentManager;
@@ -41,4 +43,13 @@
return ((TutorialFragment) FragmentManager.findFragment(this))
.onInterceptTouch(motionEvent);
}
+
+ /**
+ * Returns this view's fullscreen height. This method is agnostic of this view's actual height.
+ */
+ public int getFullscreenHeight() {
+ Insets insets = getRootWindowInsets().getInsets(WindowInsets.Type.systemBars());
+
+ return getHeight() + insets.top + insets.bottom;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 04b147c..c2c8f61 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -25,6 +25,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Outline;
@@ -32,7 +33,6 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
-import android.util.DisplayMetrics;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -63,23 +63,24 @@
private static final int FAKE_PREVIOUS_TASK_MARGIN = Utilities.dpToPx(12);
+ private static final long HOME_SWIPE_ANIMATION_DURATION_MILLIS = 625;
+ private static final long OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS = 1000;
+
final ViewSwipeUpAnimation mTaskViewSwipeUpAnimation;
private float mFakeTaskViewRadius;
- private Rect mFakeTaskViewRect = new Rect();
+ private final Rect mFakeTaskViewRect = new Rect();
RunningWindowAnim mRunningWindowAnim;
private boolean mShowTasks = false;
private boolean mShowPreviousTasks = false;
- private AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
+ private final AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mFakeHotseatView.setVisibility(View.INVISIBLE);
mFakeIconView.setVisibility(View.INVISIBLE);
if (mTutorialFragment.getActivity() != null) {
- DisplayMetrics displayMetrics =
- mTutorialFragment.getResources().getDisplayMetrics();
- int height = displayMetrics.heightPixels;
- int width = displayMetrics.widthPixels;
+ int height = mTutorialFragment.getRootView().getFullscreenHeight();
+ int width = mTutorialFragment.getRootView().getWidth();
mFakeTaskViewRect.set(0, 0, width, height);
}
mFakeTaskViewRadius = 0;
@@ -108,9 +109,8 @@
.copy(mContext);
mTaskViewSwipeUpAnimation.initDp(dp);
- DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- int height = displayMetrics.heightPixels;
- int width = displayMetrics.widthPixels;
+ int height = mTutorialFragment.getRootView().getFullscreenHeight();
+ int width = mTutorialFragment.getRootView().getWidth();
mFakeTaskViewRect.set(0, 0, width, height);
mFakeTaskViewRadius = 0;
@@ -138,7 +138,6 @@
/** Fades the task view, optionally after animating to a fake Overview. */
void fadeOutFakeTaskView(boolean toOverviewFirst, boolean reset,
@Nullable Runnable onEndRunnable) {
- hideFeedback(true);
cancelRunningAnimation();
PendingAnimation anim = new PendingAnimation(300);
if (toOverviewFirst) {
@@ -184,6 +183,7 @@
}
void resetFakeTaskView() {
+ mFakeTaskView.setVisibility(View.VISIBLE);
PendingAnimation anim = new PendingAnimation(300);
anim.setFloat(mTaskViewSwipeUpAnimation
.getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
@@ -195,7 +195,6 @@
}
void animateFakeTaskViewHome(PointF finalVelocity, @Nullable Runnable onEndRunnable) {
- hideFeedback(true);
cancelRunningAnimation();
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakeHotseatView.setVisibility(View.VISIBLE);
@@ -218,9 +217,6 @@
if (mGestureCompleted) {
return;
}
- if (displacement != null) {
- hideFeedback(true);
- }
if (mTutorialType == HOME_NAVIGATION_COMPLETE
|| mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
mFakeTaskView.setVisibility(View.INVISIBLE);
@@ -336,6 +332,44 @@
}
}
+ protected Animator createFingerDotHomeSwipeAnimator(float fingerDotStartTranslationY) {
+ Animator homeSwipeAnimator = createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
+ .setDuration(HOME_SWIPE_ANIMATION_DURATION_MILLIS);
+
+ homeSwipeAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ animateFakeTaskViewHome(
+ new PointF(
+ 0f,
+ fingerDotStartTranslationY / HOME_SWIPE_ANIMATION_DURATION_MILLIS),
+ null);
+ }
+ });
+
+ return homeSwipeAnimator;
+ }
+
+ protected Animator createFingerDotOverviewSwipeAnimator(float fingerDotStartTranslationY) {
+ return createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
+ .setDuration(OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS);
+ }
+
+
+ private Animator createFingerDotSwipeUpAnimator(float fingerDotStartTranslationY) {
+ ValueAnimator swipeAnimator = ValueAnimator.ofFloat(0f, 1f);
+
+ swipeAnimator.addUpdateListener(valueAnimator -> {
+ float gestureProgress =
+ -fingerDotStartTranslationY * valueAnimator.getAnimatedFraction();
+ setNavBarGestureProgress(gestureProgress);
+ mFingerDotView.setTranslationY(fingerDotStartTranslationY + gestureProgress);
+ });
+
+ return swipeAnimator;
+ }
+
private class FakeTransformParams extends TransformParams {
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 4b4e7e6..77bfc31 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -16,25 +16,32 @@
package com.android.quickstep.interaction;
import static android.view.View.GONE;
+import static android.view.View.NO_ID;
+import static android.view.View.inflate;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
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.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes;
+import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
@@ -48,18 +55,25 @@
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
+import java.util.ArrayList;
+
abstract class TutorialController implements BackGestureAttemptCallback,
NavBarGestureAttemptCallback {
private static final String TAG = "TutorialController";
+ private static final float FINGER_DOT_VISIBLE_ALPHA = 0.6f;
+ private static final float FINGER_DOT_SMALL_SCALE = 0.7f;
+ private static final int FINGER_DOT_ANIMATION_DURATION_MILLIS = 500;
+
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_ANIMATION_MS = 250;
+ private static final int FEEDBACK_ANIMATION_MS = 133;
private static final int RIPPLE_VISIBLE_MS = 300;
private static final int GESTURE_ANIMATION_DELAY_MS = 1500;
private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 4000;
+ private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000;
final TutorialFragment mTutorialFragment;
TutorialType mTutorialType;
@@ -68,17 +82,17 @@
final TextView mCloseButton;
final ViewGroup mFeedbackView;
final TextView mFeedbackTitleView;
- final ImageView mFeedbackVideoView;
- final ImageView mGestureVideoView;
+ final ImageView mEdgeGestureVideoView;
final RelativeLayout mFakeLauncherView;
final ImageView mFakeHotseatView;
final ClipIconView mFakeIconView;
- final View mFakeTaskView;
+ final FrameLayout mFakeTaskView;
final View mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
final Button mActionButton;
final TutorialStepIndicator mTutorialStepView;
+ final ImageView mFingerDotView;
private final AlertDialog mSkipTutorialDialog;
protected boolean mGestureCompleted = false;
@@ -87,7 +101,8 @@
// views before posting new callbacks.
private final Runnable mTitleViewCallback;
@Nullable private Runnable mFeedbackViewCallback;
- @Nullable private Runnable mFeedbackVideoViewCallback;
+ @Nullable private Runnable mFakeTaskViewCallback;
+ private final Runnable mShowFeedbackRunnable;
TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
mTutorialFragment = tutorialFragment;
@@ -100,8 +115,7 @@
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
mFeedbackTitleView = mFeedbackView.findViewById(
R.id.gesture_tutorial_fragment_feedback_title);
- mFeedbackVideoView = rootView.findViewById(R.id.gesture_tutorial_feedback_video);
- mGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_gesture_video);
+ mEdgeGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
mFakeLauncherView = rootView.findViewById(R.id.gesture_tutorial_fake_launcher_view);
mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
@@ -113,10 +127,34 @@
mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
mTutorialStepView =
rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
+ mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
mSkipTutorialDialog = createSkipTutorialDialog();
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ mShowFeedbackRunnable = () -> {
+ mFeedbackView.setAlpha(0f);
+ mFeedbackView.setScaleX(0.95f);
+ mFeedbackView.setScaleY(0.95f);
+ mFeedbackView.setVisibility(View.VISIBLE);
+ mFeedbackView.animate()
+ .setDuration(FEEDBACK_ANIMATION_MS)
+ .alpha(1f)
+ .scaleX(1f)
+ .scaleY(1f)
+ .withEndAction(() -> {
+ if (mGestureCompleted && !mTutorialFragment.isAtFinalStep()) {
+ if (mFeedbackViewCallback != null) {
+ mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+ }
+ mFeedbackViewCallback = mTutorialFragment::continueTutorial;
+ mFeedbackView.postDelayed(mFeedbackViewCallback,
+ ADVANCE_TUTORIAL_TIMEOUT_MS);
+ }
+ })
+ .start();
+ mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
+ };
}
private void showSkipTutorialDialog() {
@@ -134,9 +172,9 @@
return R.drawable.default_sandbox_mock_launcher;
}
- @DrawableRes
- protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
- return R.drawable.default_sandbox_app_task_thumbnail;
+ @LayoutRes
+ protected int getMockAppTaskLayoutResId() {
+ return View.NO_ID;
}
@DrawableRes
@@ -173,17 +211,10 @@
mFeedbackView.setTranslationY(0);
return;
}
- AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
- AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
-
- if (tutorialAnimation != null && gestureAnimation != null) {
- TextView title = mFeedbackView.findViewById(
- R.id.gesture_tutorial_fragment_feedback_title);
-
- playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
- mFeedbackView.setTranslationY(0);
- title.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- }, true);
+ Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
+ AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
+ if (gestureAnimation != null && edgeAnimation != null) {
+ playFeedbackAnimation(gestureAnimation, edgeAnimation, mShowFeedbackRunnable, true);
}
}
@@ -215,8 +246,13 @@
int subtitleResId,
boolean isGestureSuccessful,
boolean useGestureAnimationDelay) {
- mFeedbackTitleView.setText(titleResId);
mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
+ if (mFeedbackViewCallback != null) {
+ mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+ mFeedbackViewCallback = null;
+ }
+
+ mFeedbackTitleView.setText(titleResId);
TextView subtitle =
mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
subtitle.setText(subtitleResId);
@@ -226,77 +262,68 @@
showActionButton();
}
- if (mFeedbackVideoViewCallback != null) {
- mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
- mFeedbackVideoViewCallback = null;
+ if (mFakeTaskViewCallback != null) {
+ mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
+ mFakeTaskViewCallback = null;
}
}
mGestureCompleted = isGestureSuccessful;
- AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
- AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
- if (tutorialAnimation != null && gestureAnimation != null) {
- if (!isGestureSuccessful) {
- playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
- mFeedbackView.setTranslationY(
- -mFeedbackView.getHeight() - mFeedbackView.getTop());
- mFeedbackView.setVisibility(View.VISIBLE);
- mFeedbackView.animate()
- .setDuration(FEEDBACK_ANIMATION_MS)
- .translationY(0)
- .start();
- mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
- }, useGestureAnimationDelay);
- return;
- } else {
- mTutorialFragment.releaseFeedbackVideoView();
- }
+ Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
+ AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
+ if (!isGestureSuccessful && gestureAnimation != null && edgeAnimation != null) {
+ playFeedbackAnimation(
+ gestureAnimation,
+ edgeAnimation,
+ mShowFeedbackRunnable,
+ useGestureAnimationDelay);
+ return;
+ } else {
+ mTutorialFragment.releaseFeedbackAnimation();
}
- mFeedbackView.setTranslationY(-mFeedbackView.getHeight() - mFeedbackView.getTop());
- mFeedbackView.setVisibility(View.VISIBLE);
- mFeedbackView.animate()
- .setDuration(FEEDBACK_ANIMATION_MS)
- .translationY(0)
- .withEndAction(() -> {
- if (isGestureSuccessful && !mTutorialFragment.isAtFinalStep()) {
- if (mFeedbackViewCallback != null) {
- mFeedbackView.removeCallbacks(mFeedbackViewCallback);
- }
- mFeedbackViewCallback = mTutorialFragment::continueTutorial;
- mFeedbackView.postDelayed(mFeedbackViewCallback,
- ADVANCE_TUTORIAL_TIMEOUT_MS);
- }
- })
- .start();
- mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
+ mFeedbackViewCallback = mShowFeedbackRunnable;
+
+ mFeedbackView.post(mFeedbackViewCallback);
}
- void hideFeedback(boolean releaseFeedbackVideo) {
+ void hideFeedback() {
+ cancelQueuedGestureAnimation();
mFeedbackView.clearAnimation();
mFeedbackView.setVisibility(View.INVISIBLE);
- if (releaseFeedbackVideo) {
- mTutorialFragment.releaseFeedbackVideoView();
- }
}
- private void playFeedbackVideo(
- @NonNull AnimatedVectorDrawable tutorialAnimation,
- @NonNull AnimatedVectorDrawable gestureAnimation,
+ void cancelQueuedGestureAnimation() {
+ if (mFeedbackViewCallback != null) {
+ mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+ mFeedbackViewCallback = null;
+ }
+ if (mFakeTaskViewCallback != null) {
+ mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
+ mFakeTaskViewCallback = null;
+ }
+ mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
+ }
+
+ private void playFeedbackAnimation(
+ @NonNull Animator gestureAnimation,
+ @NonNull AnimatedVectorDrawable edgeAnimation,
@NonNull Runnable onStartRunnable,
boolean useGestureAnimationDelay) {
- if (tutorialAnimation.isRunning()) {
- tutorialAnimation.reset();
+ if (gestureAnimation.isRunning()) {
+ gestureAnimation.cancel();
}
- tutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
-
+ if (edgeAnimation.isRunning()) {
+ edgeAnimation.reset();
+ }
+ gestureAnimation.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationStart(Drawable drawable) {
- super.onAnimationStart(drawable);
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
- mGestureVideoView.setVisibility(GONE);
- if (gestureAnimation.isRunning()) {
- gestureAnimation.stop();
+ mEdgeGestureVideoView.setVisibility(GONE);
+ if (edgeAnimation.isRunning()) {
+ edgeAnimation.stop();
}
if (!useGestureAnimationDelay) {
@@ -305,37 +332,25 @@
}
@Override
- public void onAnimationEnd(Drawable drawable) {
- super.onAnimationEnd(drawable);
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
- mGestureVideoView.setVisibility(View.VISIBLE);
- gestureAnimation.start();
+ mEdgeGestureVideoView.setVisibility(View.VISIBLE);
+ edgeAnimation.start();
- tutorialAnimation.unregisterAnimationCallback(this);
+ gestureAnimation.removeListener(this);
}
});
- if (mFeedbackViewCallback != null) {
- mFeedbackVideoView.removeCallbacks(mFeedbackViewCallback);
- mFeedbackViewCallback = null;
- }
- if (mFeedbackVideoViewCallback != null) {
- mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
- mFeedbackVideoViewCallback = null;
- }
+ cancelQueuedGestureAnimation();
if (useGestureAnimationDelay) {
mFeedbackViewCallback = onStartRunnable;
- mFeedbackVideoViewCallback = () -> {
- mFeedbackVideoView.setVisibility(View.VISIBLE);
- tutorialAnimation.start();
- };
+ mFakeTaskViewCallback = gestureAnimation::start;
- mFeedbackVideoView.setVisibility(View.GONE);
mFeedbackView.post(mFeedbackViewCallback);
- mFeedbackVideoView.postDelayed(mFeedbackVideoViewCallback, GESTURE_ANIMATION_DELAY_MS);
+ mFakeTaskView.postDelayed(mFakeTaskViewCallback, GESTURE_ANIMATION_DELAY_MS);
} else {
- mFeedbackVideoView.setVisibility(View.VISIBLE);
- tutorialAnimation.start();
+ gestureAnimation.start();
}
}
@@ -360,7 +375,7 @@
@CallSuper
void transitToController() {
- hideFeedback(false);
+ hideFeedback();
hideActionButton();
updateSubtext();
updateDrawables();
@@ -395,6 +410,17 @@
mActionButton.setOnClickListener(this::onActionButtonClicked);
}
+ void updateFakeAppTaskViewLayout(@LayoutRes int mockAppTaskLayoutResId) {
+ mFakeTaskView.removeAllViews();
+ if (mockAppTaskLayoutResId != NO_ID) {
+ mFakeTaskView.addView(
+ inflate(mContext, mockAppTaskLayoutResId, null),
+ new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ }
+ }
+
private void updateSubtext() {
mTutorialStepView.setTutorialProgress(
mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
@@ -404,15 +430,12 @@
if (mContext != null) {
mTutorialFragment.getRootView().setBackground(AppCompatResources.getDrawable(
mContext, getMockWallpaperResId()));
- mTutorialFragment.updateFeedbackVideo();
+ mTutorialFragment.updateFeedbackAnimation();
mFakeLauncherView.setBackgroundColor(
- mContext.getColor(Utilities.isDarkTheme(mContext)
- ? R.color.fake_wallpaper_color_dark_mode
- : R.color.fake_wallpaper_color_light_mode));
+ mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color));
mFakeHotseatView.setImageDrawable(AppCompatResources.getDrawable(
mContext, getMockHotseatResId()));
- mFakeTaskView.setBackground(AppCompatResources.getDrawable(
- mContext, getMockAppTaskThumbnailResId(Utilities.isDarkTheme(mContext))));
+ updateFakeAppTaskViewLayout(getMockAppTaskLayoutResId());
mFakeTaskView.animate().alpha(1).setListener(
AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel()));
mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable(
@@ -485,6 +508,52 @@
return null;
}
+ protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
+ ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.ALPHA, 0f, FINGER_DOT_VISIBLE_ALPHA);
+ ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.SCALE_Y, FINGER_DOT_SMALL_SCALE, 1f);
+ ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.SCALE_X, FINGER_DOT_SMALL_SCALE, 1f);
+ ArrayList<Animator> animators = new ArrayList<>();
+
+ animators.add(alphaAnimator);
+ animators.add(xScaleAnimator);
+ animators.add(yScaleAnimator);
+
+ AnimatorSet appearanceAnimatorSet = new AnimatorSet();
+
+ appearanceAnimatorSet.playTogether(animators);
+ appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
+
+ return appearanceAnimatorSet;
+ }
+
+ protected AnimatorSet createFingerDotDisappearanceAnimatorSet() {
+ ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.ALPHA, FINGER_DOT_VISIBLE_ALPHA, 0f);
+ ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.SCALE_Y, 1f, FINGER_DOT_SMALL_SCALE);
+ ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
+ mFingerDotView, View.SCALE_X, 1f, FINGER_DOT_SMALL_SCALE);
+ ArrayList<Animator> animators = new ArrayList<>();
+
+ animators.add(alphaAnimator);
+ animators.add(xScaleAnimator);
+ animators.add(yScaleAnimator);
+
+ AnimatorSet appearanceAnimatorSet = new AnimatorSet();
+
+ appearanceAnimatorSet.playTogether(animators);
+ appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
+
+ return appearanceAnimatorSet;
+ }
+
+ protected Animator createAnimationPause() {
+ return ValueAnimator.ofFloat(0f, 1f).setDuration(GESTURE_ANIMATION_PAUSE_DURATION_MILLIS);
+ }
+
/** Denotes the type of the tutorial. */
enum TutorialType {
BACK_NAVIGATION,
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 7637450..52ec9b3 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.interaction;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -29,6 +31,7 @@
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.widget.ImageView;
@@ -38,7 +41,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 {
@@ -49,13 +51,14 @@
TutorialType mTutorialType;
@Nullable TutorialController mTutorialController = null;
RootSandboxLayout mRootView;
+ View mFingerDotView;
+ View mFakePreviousTaskView;
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarGestureHandler mNavBarGestureHandler;
- private ImageView mFeedbackVideoView;
- private ImageView mGestureVideoView;
+ private ImageView mEdgeGestureVideoView;
- @Nullable private AnimatedVectorDrawable mTutorialAnimation = null;
- @Nullable private AnimatedVectorDrawable mGestureAnimation = null;
+ @Nullable private Animator mGestureAnimation = null;
+ @Nullable private AnimatedVectorDrawable mEdgeAnimation = null;
private boolean mIntroductionShown = false;
private boolean mFragmentStopped = false;
@@ -96,24 +99,26 @@
return null;
}
- @Nullable Integer getFeedbackVideoResId(boolean forDarkMode) {
- return null;
- }
-
- @Nullable Integer getGestureVideoResId() {
+ @Nullable Integer getEdgeAnimationResId() {
return null;
}
@Nullable
- AnimatedVectorDrawable getTutorialAnimation() {
- return mTutorialAnimation;
- }
-
- @Nullable
- AnimatedVectorDrawable getGestureAnimation() {
+ Animator getGestureAnimation() {
return mGestureAnimation;
}
+ @Nullable
+ AnimatedVectorDrawable getEdgeAnimation() {
+ return mEdgeAnimation;
+ }
+
+
+ @Nullable
+ protected Animator createGestureAnimation() {
+ return null;
+ }
+
abstract TutorialController createController(TutorialType type);
abstract Class<? extends TutorialController> getControllerClass();
@@ -147,21 +152,22 @@
return insets;
});
mRootView.setOnTouchListener(this);
- mFeedbackVideoView = mRootView.findViewById(R.id.gesture_tutorial_feedback_video);
- mGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_gesture_video);
+ mEdgeGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
+ mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
+ mFakePreviousTaskView = mRootView.findViewById(
+ R.id.gesture_tutorial_fake_previous_task_view);
return mRootView;
}
@Override
public void onStop() {
super.onStop();
- releaseFeedbackVideoView();
- releaseGestureVideoView();
+ releaseFeedbackAnimation();
mFragmentStopped = true;
}
void initializeFeedbackVideoView() {
- if (!updateFeedbackVideo()) {
+ if (!updateFeedbackAnimation()) {
return;
}
@@ -176,87 +182,90 @@
}
}
- boolean updateFeedbackVideo() {
- if (getContext() == null) {
+ boolean updateFeedbackAnimation() {
+ if (!updateEdgeAnimation()) {
return false;
}
- Integer feedbackVideoResId = getFeedbackVideoResId(Utilities.isDarkTheme(getContext()));
-
- if (feedbackVideoResId == null || !updateGestureVideo()) {
- return false;
- }
- 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;
- }
-
- boolean updateGestureVideo() {
- Integer gestureVideoResId = getGestureVideoResId();
- if (gestureVideoResId == null || getContext() == null) {
- return false;
- }
- mGestureAnimation = (AnimatedVectorDrawable) getContext().getDrawable(gestureVideoResId);
+ mGestureAnimation = createGestureAnimation();
if (mGestureAnimation != null) {
- mGestureAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+ mGestureAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mFingerDotView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ mFingerDotView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mFingerDotView.setVisibility(View.GONE);
+ }
+ });
+ }
+
+ return mGestureAnimation != null;
+ }
+
+ boolean updateEdgeAnimation() {
+ Integer edgeAnimationResId = getEdgeAnimationResId();
+ if (edgeAnimationResId == null || getContext() == null) {
+ return false;
+ }
+ mEdgeAnimation = (AnimatedVectorDrawable) getContext().getDrawable(edgeAnimationResId);
+
+ if (mEdgeAnimation != null) {
+ mEdgeAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
- mGestureAnimation.start();
+ mEdgeAnimation.start();
}
});
}
- mGestureVideoView.setImageDrawable(mGestureAnimation);
+ mEdgeGestureVideoView.setImageDrawable(mEdgeAnimation);
- return true;
+ return mEdgeAnimation != null;
}
- void releaseFeedbackVideoView() {
- if (mTutorialAnimation != null && mTutorialAnimation.isRunning()) {
- mTutorialAnimation.stop();
+ void releaseFeedbackAnimation() {
+ if (mTutorialController != null) {
+ mTutorialController.cancelQueuedGestureAnimation();
}
-
- mFeedbackVideoView.setVisibility(View.GONE);
- }
-
- void releaseGestureVideoView() {
if (mGestureAnimation != null && mGestureAnimation.isRunning()) {
- mGestureAnimation.stop();
+ mGestureAnimation.cancel();
+ }
+ if (mEdgeAnimation != null && mEdgeAnimation.isRunning()) {
+ mEdgeAnimation.stop();
}
- mGestureVideoView.setVisibility(View.GONE);
+ mEdgeGestureVideoView.setVisibility(View.GONE);
}
@Override
public void onResume() {
super.onResume();
+ releaseFeedbackAnimation();
if (mFragmentStopped && mTutorialController != null) {
mTutorialController.showFeedback();
mFragmentStopped = false;
} else {
- changeController(mTutorialType);
+ mRootView.getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ changeController(mTutorialType);
+ mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ }
+ });
}
}
@@ -292,6 +301,7 @@
mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);
mNavBarGestureHandler.registerNavBarGestureAttemptCallback(mTutorialController);
mTutorialType = tutorialType;
+
initializeFeedbackVideoView();
}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index d0fb9e5..c5ab84d 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -24,8 +24,8 @@
import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.util.HorizontalInsettableView;
-import com.android.unfold.UnfoldTransitionProgressProvider;
-import com.android.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
/**
* Controls animations that are happening during unfolding foldable devices
diff --git a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
index 9eda8f4..3777c65 100644
--- a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
+++ b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
@@ -17,7 +17,7 @@
import androidx.annotation.NonNull;
-import com.android.unfold.updates.screen.ScreenStatusProvider;
+import com.android.systemui.unfold.updates.screen.ScreenStatusProvider;
import java.util.ArrayList;
import java.util.List;
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 21e0ae8..841e578 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -396,9 +396,17 @@
Rect insets = dp.getInsets();
float fullWidth = dp.widthPx;
float fullHeight = dp.heightPx;
- if (TaskView.clipStatusAndNavBars(dp)) {
- fullWidth -= insets.left + insets.right;
- fullHeight -= insets.top + insets.bottom;
+ if (TaskView.clipLeft(dp)) {
+ fullWidth -= insets.left;
+ }
+ if (TaskView.clipRight(dp)) {
+ fullWidth -= insets.right;
+ }
+ if (TaskView.clipTop(dp)) {
+ fullHeight -= insets.top;
+ }
+ if (TaskView.clipBottom(dp)) {
+ fullHeight -= insets.bottom;
}
getTaskDimension(mContext, dp, outPivot);
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 16c925a..eb77ac0 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -32,12 +32,11 @@
import android.view.SurfaceControl;
import android.window.TransitionInfo;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
@@ -57,7 +56,7 @@
private final SystemUiProxy mSystemUiProxy;
private TaskView mInitialTaskView;
private TaskView mSecondTaskView;
- private SplitPositionOption mInitialPosition;
+ private @StagePosition int mStagePosition;
private Rect mInitialBounds;
private final Handler mHandler;
@@ -69,10 +68,10 @@
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
+ public void setInitialTaskSelect(TaskView taskView, @StagePosition int stagePosition,
Rect initialBounds) {
mInitialTaskView = taskView;
- mInitialPosition = positionOption;
+ mStagePosition = stagePosition;
mInitialBounds = initialBounds;
}
@@ -83,7 +82,11 @@
mSecondTaskView = taskView;
// Assume initial task is for top/left part of screen
- final int[] taskIds = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+//<<<<<<< HEAD
+// final int[] taskIds = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT
+//=======
+ final int[] taskIds = mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
: new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
@@ -113,7 +116,11 @@
DeviceProfile deviceProfile) {
InsettableFrameLayout.LayoutParams params =
new InsettableFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- boolean topLeftPosition = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//<<<<<<< HEAD
+// boolean topLeftPosition = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//=======
+ boolean topLeftPosition = mStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
if (deviceProfile.isLandscape) {
params.width = (int) resources.getDimension(R.dimen.split_placeholder_size);
params.gravity = topLeftPosition ? Gravity.START : Gravity.END;
@@ -125,9 +132,8 @@
return params;
}
- @Nullable
- public SplitPositionOption getActiveSplitPositionOption() {
- return mInitialPosition;
+ public @StagePosition int getActiveSplitStagePosition() {
+ return mStagePosition;
}
/**
@@ -189,7 +195,7 @@
public void resetState() {
mInitialTaskView = null;
mSecondTaskView = null;
- mInitialPosition = null;
+ mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
mInitialBounds = null;
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 7b1c62e..9960fd3 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -145,8 +145,9 @@
// The task rect changes according to the staged split task sizes, but recents
// fullscreen scale and pivot remains the same since the task fits into the existing
// sized task space bounds
- mSizeStrategy.calculateStagedSplitTaskSize(mContext, mDp, mTaskRect, mStagedSplitBounds,
- mStagePosition);
+ mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect);
+ mOrientationState.getOrientationHandler()
+ .setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
} else {
mTaskRect.set(fullTaskSize);
}
@@ -175,7 +176,7 @@
mStagePosition = STAGE_POSITION_UNDEFINED;
return;
}
- mStagePosition = mThumbnailPosition.equals(splitInfo.mLeftTopBounds) ?
+ mStagePosition = mThumbnailPosition.equals(splitInfo.leftTopBounds) ?
STAGE_POSITION_TOP_OR_LEFT :
STAGE_POSITION_BOTTOM_OR_RIGHT;
}
@@ -277,13 +278,9 @@
getFullScreenScale();
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
- // TODO(b/195145340) handle non 50-50 split scenarios
if (mStagedSplitBounds != null) {
- if (mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
- // The preview set is for the bottom/right, inset by top/left task
- mSplitOffset.y = mStagedSplitBounds.mLeftTopBounds.height() +
- mStagedSplitBounds.mDividerBounds.height() / 2;
- }
+ mOrientationState.getOrientationHandler().setLeashSplitOffset(mSplitOffset, mDp,
+ mStagedSplitBounds, mStagePosition);
}
// mIsRecentsRtl is the inverse of TaskView RTL.
@@ -331,7 +328,7 @@
applyWindowToHomeRotation(mMatrix);
// Move lower/right split window into correct position
- mMatrix.postTranslate(0, mSplitOffset.y);
+ mMatrix.postTranslate(mSplitOffset.x, mSplitOffset.y);
// Crop rect is the inverse of thumbnail matrix
mTempRectF.set(-insets.left, -insets.top,
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
index 126e044..482092d 100644
--- a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
@@ -29,7 +29,7 @@
import com.android.launcher3.widget.NavigableAppWidgetHostView;
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.TranslationApplier;
-import com.android.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import java.util.HashMap;
import java.util.Map;
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index cd20f4b..1bc7c75 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -1,13 +1,10 @@
package com.android.quickstep.views;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
import android.content.Context;
import android.util.AttributeSet;
-import android.view.ViewGroup;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.util.CancellableTask;
@@ -48,13 +45,14 @@
mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
}
- public void bind(Task primary, Task secondary, RecentsOrientedState orientedState) {
+ public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
+ SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig) {
super.bind(primary, orientedState);
mSecondaryTask = secondary;
mTaskIdContainer[1] = secondary.key.id;
mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2);
mSnapshotView2.bind(secondary);
- adjustThumbnailBoundsForSplit();
+ adjustThumbnailBoundsForSplit(splitBoundsConfig, orientedState);
}
@Override
@@ -108,30 +106,15 @@
mSnapshotView2.setOverlayEnabled(overlayEnabled);
}
- private void adjustThumbnailBoundsForSplit() {
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
- primaryLp.width = mSecondaryTask == null ?
- MATCH_PARENT :
- getWidth();
- int spaceAboveSnapshot = deviceProfile.overviewTaskThumbnailTopMarginPx;
- // TODO get divider height
- int dividerBar = 20;
- primaryLp.height = mSecondaryTask == null ?
- MATCH_PARENT :
- (getHeight() - spaceAboveSnapshot - dividerBar) / 2;
- mSnapshotView.setLayoutParams(primaryLp);
-
- if (mSecondaryTask == null) {
- mSnapshotView2.setVisibility(GONE);
+ private void adjustThumbnailBoundsForSplit(
+ SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+ RecentsOrientedState orientedState) {
+ if (splitBoundsConfig == null) {
return;
}
- mSnapshotView2.setVisibility(VISIBLE);
- ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
- secondaryLp.width = getWidth();
- secondaryLp.height = primaryLp.height;
- mSnapshotView2.setLayoutParams(secondaryLp);
- mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+ orientedState.getOrientationHandler().setGroupedTaskViewThumbnailBounds(
+ mSnapshotView, mSnapshotView2, this, splitBoundsConfig,
+ mActivity.getDeviceProfile());
}
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6b2d19c..ddb1fca 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -245,8 +245,8 @@
@Override
public void initiateSplitSelect(TaskView taskView,
- SplitConfigurationOptions.SplitPositionOption splitPositionOption) {
- super.initiateSplitSelect(taskView, splitPositionOption);
+ @SplitConfigurationOptions.StagePosition int stagePosition) {
+ super.initiateSplitSelect(taskView, stagePosition);
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
}
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index a2d2179..5d1c202 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -79,6 +79,7 @@
private static final int INDEX_SCROLL_ALPHA = 4;
private final MultiValueAlpha mMultiValueAlpha;
+ private View mSplitButton;
@ActionsHiddenFlags
private int mHiddenFlags;
@@ -110,6 +111,8 @@
View share = findViewById(R.id.action_share);
share.setOnClickListener(this);
findViewById(R.id.action_screenshot).setOnClickListener(this);
+ mSplitButton = findViewById(R.id.action_split);
+ mSplitButton.setOnClickListener(this);
if (ENABLE_OVERVIEW_SHARE.get()) {
share.setVisibility(VISIBLE);
findViewById(R.id.oav_three_button_space).setVisibility(VISIBLE);
@@ -135,6 +138,8 @@
mCallbacks.onShare();
} else if (id == R.id.action_screenshot) {
mCallbacks.onScreenshot();
+ } else if (id == R.id.action_split) {
+ mCallbacks.onSplit();
}
}
@@ -218,6 +223,16 @@
mDp = dp;
updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
requestLayout();
+ setSplitButtonVisible(mDp.isTablet);
+ }
+
+ public void setSplitButtonVisible(boolean visible) {
+ if (mSplitButton == null) {
+ return;
+ }
+
+ mSplitButton.setVisibility(visible ? VISIBLE : GONE);
+ findViewById(R.id.action_split_space).setVisibility(visible ? VISIBLE : GONE);
}
/** Get the top margin associated with the action buttons in Overview. */
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 9eecae6..646312e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -133,7 +133,7 @@
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TranslateEdgeEffect;
import com.android.launcher3.util.ViewPool;
@@ -575,6 +575,7 @@
*/
private TaskView mSplitHiddenTaskView;
private TaskView mSecondSplitHiddenTaskView;
+ private SplitConfigurationOptions.StagedSplitBounds mSplitBoundsConfig;
/**
* Keeps track of the index of the TaskView that split screen was initialized with so we know
@@ -1314,7 +1315,8 @@
taskDataIndex--;
leftTop = tasks.get(taskDataIndex);
}
- ((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState);
+ ((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
+ mSplitBoundsConfig);
} else {
taskView.bind(task, mOrientationState);
}
@@ -1329,6 +1331,7 @@
mFocusedTaskViewId = newFocusedTaskView != null ?
newFocusedTaskView.getTaskViewId() : -1;
updateTaskSize();
+ updateChildTaskOrientations();
TaskView newRunningTaskView = null;
if (runningTaskId != -1) {
@@ -1977,7 +1980,6 @@
return as;
}
-
private void updateChildTaskOrientations() {
for (int i = 0; i < getTaskViewCount(); i++) {
getTaskViewAt(i).setOrientationState(mOrientationState);
@@ -1996,7 +1998,6 @@
TaskViewSimulator[] taskViewSimulators) {
mCurrentGestureEndTarget = endTarget;
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
- setEnableFreeScroll(true);
updateGridProperties();
}
@@ -2088,8 +2089,11 @@
Task.from(new TaskKey(secondaryTaskInfo), secondaryTaskInfo, false)
};
addView(taskView, mTaskViewStartIndex);
+ // When we create a placeholder task view mSplitBoundsConfig will be null, but with
+ // the actual app running we won't need to show the thumbnail until all the tasks
+ // load later anyways
((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
- mOrientationState);
+ mOrientationState, mSplitBoundsConfig);
} else {
taskView = getTaskViewFromPool(false);
addView(taskView, mTaskViewStartIndex);
@@ -2120,6 +2124,7 @@
setRunningTaskHidden(runningTaskTileHidden);
// Update task size after setting current task.
updateTaskSize();
+ updateChildTaskOrientations();
// Reload the task list
mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
@@ -2567,8 +2572,8 @@
private void createInitialSplitSelectAnimation(PendingAnimation anim) {
float placeholderHeight = getResources().getDimension(R.dimen.split_placeholder_size);
mOrientationHandler.getInitialSplitPlaceholderBounds((int) placeholderHeight,
- mActivity.getDeviceProfile(),
- mSplitSelectStateController.getActiveSplitPositionOption(), mTempRect);
+ mActivity.getDeviceProfile(),
+ mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
RectF startingTaskRect = new RectF();
mSplitHiddenTaskView.setVisibility(INVISIBLE);
@@ -2577,6 +2582,7 @@
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
mTempRect, mSplitHiddenTaskView, true /*fadeWithThumbnail*/);
+ anim.addEndListener(aBoolean -> mActionsView.setSplitButtonVisible(false));
}
/**
@@ -2806,14 +2812,49 @@
resetTaskVisuals();
int pageToSnapTo = mCurrentPage;
- if ((dismissedIndex < pageToSnapTo && !showAsGrid)
- || pageToSnapTo == taskCount - 1) {
- pageToSnapTo -= 1;
- }
+ int taskViewIdToSnapTo = -1;
if (showAsGrid) {
+ // Get the id of the task view we will snap to based on the current
+ // page's relative position as the order of indices change over time due
+ // to dismissals.
+ TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(mCurrentPage);
+ if (snappedTaskView != null) {
+ if (snappedTaskView.getTaskViewId() == mFocusedTaskViewId) {
+ if (finalNextFocusedTaskView != null) {
+ taskViewIdToSnapTo = finalNextFocusedTaskView.getTaskViewId();
+ } else {
+ taskViewIdToSnapTo = mFocusedTaskViewId;
+ }
+ } else {
+ int snappedTaskViewId = snappedTaskView.getTaskViewId();
+ boolean isSnappedTaskInTopRow = mTopRowIdSet.contains(
+ snappedTaskViewId);
+ IntArray taskViewIdArray =
+ isSnappedTaskInTopRow ? getTopRowIdArray()
+ : getBottomRowIdArray();
+ int snappedIndex = taskViewIdArray.indexOf(snappedTaskViewId);
+ taskViewIdArray.removeValue(dismissedTaskViewId);
+ if (snappedIndex < taskViewIdArray.size()) {
+ taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
+ } else if (snappedIndex == taskViewIdArray.size()) {
+ // If the snapped task is the last item from the dismissed row,
+ // snap to the same column in the other grid row
+ IntArray inverseRowTaskViewIdArray =
+ isSnappedTaskInTopRow ? getBottomRowIdArray()
+ : getTopRowIdArray();
+ if (snappedIndex < inverseRowTaskViewIdArray.size()) {
+ taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
+ snappedIndex);
+ }
+ }
+ }
+ }
+
int primaryScroll = mOrientationHandler.getPrimaryScroll(RecentsView.this);
int currentPageScroll = getScrollForPage(pageToSnapTo);
mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
+ } else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) {
+ pageToSnapTo -= 1;
}
removeViewInLayout(dismissedTaskView);
mTopRowIdSet.remove(dismissedTaskViewId);
@@ -2829,43 +2870,54 @@
finalNextFocusedTaskView.animateIconScaleAndDimIntoView();
}
updateTaskSize(/*isTaskDismissal=*/ true);
+ updateChildTaskOrientations();
// Update scroll and snap to page.
updateScrollSynchronously();
- int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
- if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
- TaskView taskView = getTaskViewAt(highestVisibleTaskIndex);
+ if (showAsGrid) {
+ // Rebalance tasks in the grid
+ int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
+ if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
+ TaskView taskView = getTaskViewAt(highestVisibleTaskIndex);
- boolean shouldRebalance = false;
- int screenStart = mOrientationHandler.getPrimaryScroll(
- RecentsView.this);
- int taskStart = mOrientationHandler.getChildStart(taskView)
- + (int) taskView.getOffsetAdjustment(
- /*fullscreenEnabled=*/ false,
- /*gridEnabled=*/ true);
-
- // Rebalance only if there is a maximum gap between the task and the
- // screen's edge; this ensures that rebalanced tasks are outside the
- // visible screen.
- if (mIsRtl) {
- shouldRebalance = taskStart <= screenStart + mPageSpacing;
- } else {
- int screenEnd = screenStart + mOrientationHandler.getMeasuredSize(
+ boolean shouldRebalance = false;
+ int screenStart = mOrientationHandler.getPrimaryScroll(
RecentsView.this);
- int taskSize = (int) (mOrientationHandler.getMeasuredSize(taskView)
- * taskView.getSizeAdjustment(/*fullscreenEnabled=*/ false));
- int taskEnd = taskStart + taskSize;
+ int taskStart = mOrientationHandler.getChildStart(taskView)
+ + (int) taskView.getOffsetAdjustment(/*fullscreenEnabled=*/
+ false, /*gridEnabled=*/ true);
- shouldRebalance = taskEnd >= screenEnd - mPageSpacing;
+ // Rebalance only if there is a maximum gap between the task and the
+ // screen's edge; this ensures that rebalanced tasks are outside the
+ // visible screen.
+ if (mIsRtl) {
+ shouldRebalance = taskStart <= screenStart + mPageSpacing;
+ } else {
+ int screenEnd =
+ screenStart + mOrientationHandler.getMeasuredSize(
+ RecentsView.this);
+ int taskSize = (int) (mOrientationHandler.getMeasuredSize(
+ taskView) * taskView
+ .getSizeAdjustment(/*fullscreenEnabled=*/false));
+ int taskEnd = taskStart + taskSize;
+
+ shouldRebalance = taskEnd >= screenEnd - mPageSpacing;
+ }
+
+ if (shouldRebalance) {
+ updateGridProperties(/*isTaskDismissal=*/ true,
+ highestVisibleTaskIndex);
+ updateScrollSynchronously();
+ }
}
- if (shouldRebalance) {
- updateGridProperties(/*isTaskDismissal=*/ true,
- highestVisibleTaskIndex);
- updateScrollSynchronously();
+ // If snapping to another page due to indices rearranging, find the new
+ // index after dismissal & rearrange using the task view id.
+ if (taskViewIdToSnapTo != -1) {
+ pageToSnapTo = indexOfChild(
+ getTaskViewFromTaskViewId(taskViewIdToSnapTo));
}
}
-
setCurrentPage(pageToSnapTo);
dispatchScrollChanged();
}
@@ -2878,10 +2930,32 @@
}
/**
+ * Returns all the tasks in the top row, without the focused task
+ */
+ private IntArray getTopRowIdArray() {
+ if (mTopRowIdSet.isEmpty()) {
+ return new IntArray(0);
+ }
+ IntArray topArray = new IntArray(mTopRowIdSet.size());
+ int taskViewCount = getTaskViewCount();
+ for (int i = 0; i < taskViewCount; i++) {
+ int taskViewId = getTaskViewAt(i).getTaskViewId();
+ if (mTopRowIdSet.contains(taskViewId)) {
+ topArray.add(taskViewId);
+ }
+ }
+ return topArray;
+ }
+
+ /**
* Returns all the tasks in the bottom row, without the focused task
*/
private IntArray getBottomRowIdArray() {
- IntArray bottomArray = new IntArray();
+ int bottomRowIdArraySize = getTaskViewCount() - mTopRowIdSet.size() - 1;
+ if (bottomRowIdArraySize <= 0) {
+ return new IntArray(0);
+ }
+ IntArray bottomArray = new IntArray(bottomRowIdArraySize);
int taskViewCount = getTaskViewCount();
for (int i = 0; i < taskViewCount; i++) {
int taskViewId = getTaskViewAt(i).getTaskViewId();
@@ -2902,7 +2976,7 @@
if (mTopRowIdSet.isEmpty()) return Integer.MAX_VALUE; // return earlier
int lastVisibleIndex = Integer.MAX_VALUE;
- IntArray topRowIdArray = mTopRowIdSet.getArray();
+ IntArray topRowIdArray = getTopRowIdArray();
IntArray bottomRowIdArray = getBottomRowIdArray();
int balancedColumns = Math.min(bottomRowIdArray.size(), topRowIdArray.size());
@@ -2941,8 +3015,7 @@
* @return {@code true} if one of the task thumbnails would intersect/overlap with the
* {@link #mFirstFloatingTaskView}
*/
- public boolean shouldShiftThumbnailsForSplitSelect(@SplitConfigurationOptions.StagePosition
- int stagePosition) {
+ public boolean shouldShiftThumbnailsForSplitSelect(@StagePosition int stagePosition) {
if (!mActivity.getDeviceProfile().isTablet) {
// Never enough space on phones
return true;
@@ -3246,9 +3319,9 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- // If we're going to HOME, avoid unnecessary onLayout that cause TaskViews to re-arrange
- // during animation to HOME.
- if (mCurrentGestureEndTarget == GestureState.GestureEndTarget.HOME) {
+ // If we're going to a state without overview panel, avoid unnecessary onLayout that
+ // cause TaskViews to re-arrange during animation to that state.
+ if (!mOverviewStateEnabled && !mFirstLayout) {
return;
}
@@ -3383,8 +3456,11 @@
boolean isStartShift;
if (midpointIndex > -1) {
// When there is a midpoint reference task, adjacent tasks have less distance to travel
- // to reach offscreen. Offset the task position to the task's starting point.
- int midpointScroll = getScrollForPage(midpointIndex);
+ // to reach offscreen. Offset the task position to the task's starting point, and offset
+ // by current page's scroll diff.
+ int midpointScroll = getScrollForPage(midpointIndex)
+ + mOrientationHandler.getPrimaryScroll(this) - getScrollForPage(mCurrentPage);
+
getPersistentChildPosition(midpointIndex, midpointScroll, taskPosition);
float midpointStart = mOrientationHandler.getStart(taskPosition);
@@ -3471,12 +3547,17 @@
}
}
- public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
+ public void initiateSplitSelect(TaskView taskView) {
+ int defaultSplitPosition = mOrientationHandler
+ .getDefaultSplitPosition(mActivity.getDeviceProfile());
+ initiateSplitSelect(taskView, defaultSplitPosition);
+ }
+
+ public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition) {
mSplitHiddenTaskView = taskView;
Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
taskView.getBottom());
- mSplitSelectStateController.setInitialTaskSelect(taskView,
- splitPositionOption, initialBounds);
+ mSplitSelectStateController.setInitialTaskSelect(taskView, stagePosition, initialBounds);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
finishRecentsAnimation(true, null);
@@ -3502,7 +3583,7 @@
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
mOrientationHandler.getFinalSplitPlaceholderBounds(halfDividerSize,
mActivity.getDeviceProfile(),
- mSplitSelectStateController.getActiveSplitPositionOption(), firstTaskEndingBounds,
+ mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
secondTaskEndingBounds);
mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
@@ -3527,7 +3608,7 @@
public PendingAnimation cancelSplitSelect(boolean animate) {
SplitSelectStateController splitController = mSplitSelectStateController;
- SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
+ @StagePosition int stagePosition = splitController.getActiveSplitStagePosition();
Rect initialBounds = splitController.getInitialBounds();
splitController.resetState();
int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
@@ -3553,7 +3634,7 @@
if (child == mSplitHiddenTaskView) {
TaskView taskView = (TaskView) child;
- int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(stagePosition,
mActivity.getDeviceProfile());
FloatProperty<TaskView> dismissingTaskViewTranslate;
Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
@@ -3625,10 +3706,10 @@
return pendingAnim;
}
+ /** TODO(b/181707736) More gracefully handle exiting split selection state */
private void resetFromSplitSelectionState() {
mSplitHiddenTaskView.setTranslationY(0);
if (!showAsGrid()) {
- // TODO(b/186800707)
int pageToSnapTo = mCurrentPage;
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
pageToSnapTo += 1;
@@ -3652,6 +3733,7 @@
mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
mSecondSplitHiddenTaskView = null;
}
+ mActionsView.setSplitButtonVisible(true);
}
private void updateDeadZoneRects() {
@@ -3948,12 +4030,14 @@
recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
}
- // TODO Consolidate this shared code with SwipeUpAnimationLogic (or mabe just reuse
- // what that class has and pass it into here
- mRemoteTargetHandles = new RemoteTargetHandle[recentsAnimationTargets.apps.length];
+ RemoteAnimationTargetCompat dividerTarget =
+ recentsAnimationTargets.getNonAppTargetOfType(TYPE_DOCK_DIVIDER);
+ // TODO Consolidate this shared code with SwipeUpAnimationLogic (or maybe just reuse
+ // what that class has and pass it into here)
+ mRemoteTargetHandles = new RemoteTargetHandle[dividerTarget == null ? 1 : 2];
TaskViewSimulator primaryTvs = createTaskViewSimulator();
mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTvs, new TransformParams());
- if (recentsAnimationTargets.apps.length == 1) {
+ if (dividerTarget == null) {
mRemoteTargetHandles[0].mTaskViewSimulator
.setPreview(recentsAnimationTargets.apps[0], null);
mRemoteTargetHandles[0].mTransformParams.setTargetSet(recentsAnimationTargets);
@@ -3963,16 +4047,15 @@
secondaryTvs.recentsViewScale.value = 1;
mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTvs, new TransformParams());
- RemoteAnimationTargetCompat dividerTarget =
- recentsAnimationTargets.getNonAppTargetOfType(TYPE_DOCK_DIVIDER);
RemoteAnimationTargetCompat primaryTaskTarget = recentsAnimationTargets.apps[0];
RemoteAnimationTargetCompat secondaryTaskTarget = recentsAnimationTargets.apps[1];
- SplitConfigurationOptions.StagedSplitBounds
- info = new SplitConfigurationOptions.StagedSplitBounds(
+ mSplitBoundsConfig = new SplitConfigurationOptions.StagedSplitBounds(
primaryTaskTarget.screenSpaceBounds,
secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
- mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget, info);
- mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget, info);
+ mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
+ mSplitBoundsConfig);
+ mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
+ mSplitBoundsConfig);
RemoteAnimationTargets rats = new RemoteAnimationTargets(
new RemoteAnimationTargetCompat[]{primaryTaskTarget},
recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
@@ -4013,6 +4096,8 @@
public void finishRecentsAnimation(boolean toRecents, boolean shouldPip,
Runnable onFinishComplete) {
+ // TODO(b/197232424#comment#10) Move this back into onRecentsAnimationComplete(). Maybe?
+ mRemoteTargetHandles = null;
if (!toRecents && ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// Reset the minimized state since we force-toggled the minimized state when entering
// overview, but never actually finished the recents animation. This is a catch all for
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 0577cce..28044e4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -211,10 +211,6 @@
return Insets.NONE;
}
- if (!TaskView.clipStatusAndNavBars(mActivity.getDeviceProfile())) {
- return Insets.NONE;
- }
-
RectF bitmapRect = new RectF(
0, 0,
mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
@@ -228,11 +224,14 @@
RectF boundsInBitmapSpace = new RectF();
boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
- return Insets.of(
- Math.round(boundsInBitmapSpace.left),
- Math.round(boundsInBitmapSpace.top),
- Math.round(bitmapRect.right - boundsInBitmapSpace.right),
- Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom));
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ int leftInset = TaskView.clipLeft(dp) ? Math.round(boundsInBitmapSpace.left) : 0;
+ int topInset = TaskView.clipTop(dp) ? Math.round(boundsInBitmapSpace.top) : 0;
+ int rightInset = TaskView.clipRight(dp) ? Math.round(
+ bitmapRect.right - boundsInBitmapSpace.right) : 0;
+ int bottomInset = TaskView.clipBottom(dp)
+ ? Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom) : 0;
+ return Insets.of(leftInset, topInset, rightInset, bottomInset);
}
@@ -440,8 +439,19 @@
int thumbnailRotation = thumbnailData.rotation;
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
- RectF thumbnailClipHint = TaskView.clipStatusAndNavBars(dp)
- ? new RectF(thumbnailData.insets) : new RectF();
+ RectF thumbnailClipHint = new RectF();
+ if (TaskView.clipLeft(dp)) {
+ thumbnailClipHint.left = thumbnailData.insets.left;
+ }
+ if (TaskView.clipRight(dp)) {
+ thumbnailClipHint.right = thumbnailData.insets.right;
+ }
+ if (TaskView.clipTop(dp)) {
+ thumbnailClipHint.top = thumbnailData.insets.top;
+ }
+ if (TaskView.clipBottom(dp)) {
+ thumbnailClipHint.bottom = thumbnailData.insets.bottom;
+ }
float scale = thumbnailData.scale;
final float thumbnailScale;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index a3b9c6f..bfe6ca4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -146,19 +146,39 @@
public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
/**
- * Should the TaskView display clip off the status and navigation bars in recents. When this
- * is false the overview shows the whole screen scaled down instead.
+ * Should the TaskView display clip off the left inset in RecentsView.
*/
- public static boolean clipStatusAndNavBars(DeviceProfile deviceProfile) {
- return deviceProfile.isTaskbarPresentInApps;
+ public static boolean clipLeft(DeviceProfile deviceProfile) {
+ return false;
+ }
+
+ /**
+ * Should the TaskView display clip off the top inset in RecentsView.
+ */
+ public static boolean clipTop(DeviceProfile deviceProfile) {
+ return false;
+ }
+
+ /**
+ * Should the TaskView display clip off the right inset in RecentsView.
+ */
+ public static boolean clipRight(DeviceProfile deviceProfile) {
+ return false;
+ }
+
+ /**
+ * Should the TaskView display clip off the bottom inset in RecentsView.
+ */
+ public static boolean clipBottom(DeviceProfile deviceProfile) {
+ return deviceProfile.isTablet;
}
/**
* Should the TaskView scale down to fit whole thumbnail in fullscreen.
*/
public static boolean useFullThumbnail(DeviceProfile deviceProfile) {
- return deviceProfile.isTaskbarPresentInApps;
- };
+ return deviceProfile.isTablet && !deviceProfile.isTaskbarPresentInApps;
+ }
private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
@@ -825,8 +845,11 @@
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
- int taskIconMargin = deviceProfile.overviewTaskMarginPx;
+ boolean isGridTask = deviceProfile.overviewShowAsGrid && !isFocusedTask();
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
+ int taskMargin = isGridTask ? deviceProfile.overviewTaskMarginGridPx
+ : deviceProfile.overviewTaskMarginPx;
+ int taskIconMargin = snapshotParams.topMargin - taskIconHeight - taskMargin;
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
switch (orientationHandler.getRotation()) {
case ROTATION_90:
@@ -858,6 +881,9 @@
iconParams.width = iconParams.height = taskIconHeight;
mIconView.setLayoutParams(iconParams);
mIconView.setRotation(orientationHandler.getDegreesRotated());
+ int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
+ : deviceProfile.overviewTaskIconDrawableSizePx;
+ mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
mSnapshotView.setLayoutParams(snapshotParams);
mSnapshotView.getTaskOverlay().updateOrientationState(orientationState);
@@ -1401,7 +1427,6 @@
float boxTranslationY;
int expectedWidth;
int expectedHeight;
- int iconDrawableSize;
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
if (deviceProfile.overviewShowAsGrid) {
final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
@@ -1417,13 +1442,11 @@
// that is associated with the original orientation of the focused task.
boxWidth = taskWidth;
boxHeight = taskHeight;
- iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizePx;
} else {
// Otherwise task is in grid, and should use lastComputedGridTaskSize.
Rect lastComputedGridTaskSize = getRecentsView().getLastComputedGridTaskSize();
boxWidth = lastComputedGridTaskSize.width();
boxHeight = lastComputedGridTaskSize.height();
- iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizeGridPx;
}
// Bound width/height to the box size.
@@ -1440,7 +1463,6 @@
boxTranslationY = 0f;
expectedWidth = ViewGroup.LayoutParams.MATCH_PARENT;
expectedHeight = ViewGroup.LayoutParams.MATCH_PARENT;
- iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizePx;
}
setNonGridScale(nonGridScale);
@@ -1450,7 +1472,6 @@
params.height = expectedHeight;
setLayoutParams(params);
}
- mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
}
private float getGridTrans(float endTranslation) {
@@ -1493,7 +1514,7 @@
public void initiateSplitSelect(SplitPositionOption splitPositionOption) {
AbstractFloatingView.closeOpenViews(mActivity, false, TYPE_TASK_MENU);
- getRecentsView().initiateSplitSelect(this, splitPositionOption);
+ getRecentsView().initiateSplitSelect(this, splitPositionOption.stagePosition);
}
/**
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index bc8602c..416c193 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -30,7 +30,6 @@
import android.content.pm.PackageManager;
import android.util.Log;
-import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import com.android.launcher3.tapl.LauncherInstrumentation;
@@ -217,12 +216,7 @@
private static void assertTrue(LauncherInstrumentation launcher, String message,
boolean condition, Description description) {
- if (launcher.getDevice().hasObject(By.textStartsWith(""))) {
- // The condition above is "screen is not empty". We are not treating
- // "Screen is empty" as an anomaly here. It's an acceptable state when
- // Launcher just starts under instrumentation.
- launcher.checkForAnomaly();
- }
+ launcher.checkForAnomaly(true);
if (!condition) {
final AssertionError assertionError = new AssertionError(message);
if (description != null) {
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
similarity index 98%
rename from quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
rename to quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 2b1b57c..159a51f 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -19,6 +19,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static org.junit.Assert.assertFalse;
@@ -40,6 +42,9 @@
import android.view.MotionEvent;
import android.view.Surface;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.util.DisplayController;
@@ -47,10 +52,9 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class OrientationTouchTransformerTest {
static class ScreenSize {
int mHeight;
@@ -293,7 +297,7 @@
}
private DisplayController.Info createDisplayInfo(ScreenSize screenSize, int rotation) {
- Context context = RuntimeEnvironment.application;
+ Context context = getApplicationContext();
Display display = spy(context.getSystemService(DisplayManager.class)
.getDisplay(DEFAULT_DISPLAY));
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index f33abb0..0f5a1c8 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -19,9 +19,9 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.InstrumentationRegistry.getTargetContext;
-import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
import static com.android.launcher3.testcomponent.TestCommandReceiver.EXTRA_VALUE;
import static com.android.launcher3.testcomponent.TestCommandReceiver.SET_LIST_VIEW_SERVICE_BINDER;
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
import static org.junit.Assert.assertEquals;
diff --git a/res/color-v31/overview_scrim_dark.xml b/res/color-v31/overview_scrim_dark.xml
index b8ed774..85ede9a 100644
--- a/res/color-v31/overview_scrim_dark.xml
+++ b/res/color-v31/overview_scrim_dark.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_800" />
+ <item android:color="@android:color/system_neutral2_500" android:lStar="35" />
</selector>
diff --git a/res/drawable/gesture_tutorial_motion_overview_light_mode.xml b/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
deleted file mode 100644
index 75887c9..0000000
--- a/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
+++ /dev/null
@@ -1,1587 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <target android:name="_R_G_L_4_G_N_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="1050"
- android:pathData="M 206,446C 206,446 206,395 206,395"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="217">
- <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_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="1050"
- android:propertyName="scaleX"
- android:startOffset="217"
- 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:duration="1050"
- android:propertyName="scaleY"
- android:startOffset="217"
- 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_3_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- 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_0_G_L_27_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_26_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_25_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_24_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_23_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_22_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_21_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_20_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_19_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_18_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_17_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_16_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_15_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_14_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_13_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_12_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_11_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_10_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_9_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_8_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_7_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_6_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_5_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_4_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_N_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2083"
- android:valueFrom="0"
- android:valueTo="0.6"
- 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:duration="167"
- android:propertyName="scaleX"
- android:startOffset="2567"
- android:valueFrom="0"
- 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:duration="167"
- android:propertyName="scaleY"
- android:startOffset="2567"
- android:valueFrom="0"
- 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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_N_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="2567"
- 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:duration="250"
- android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="1350">
- <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:duration="417"
- android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="1600">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="2083">
- <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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="350"
- android:propertyName="scaleX"
- android:startOffset="2083"
- 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:duration="350"
- android:propertyName="scaleY"
- android:startOffset="2083"
- 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:duration="217"
- android:propertyName="scaleX"
- android:startOffset="2433"
- 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:duration="217"
- android:propertyName="scaleY"
- android:startOffset="2433"
- 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_2_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="1350"
- android:valueFrom="0"
- android:valueTo="0.6"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.75"
- 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:duration="1833"
- android:propertyName="fillAlpha"
- android:startOffset="217"
- android:valueFrom="0.75"
- android:valueTo="0.75"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="167"
- android:propertyName="fillAlpha"
- android:startOffset="2050"
- android:valueFrom="0.75"
- android:valueTo="0"
- 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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="217"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
- android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
- android:valueType="pathType">
- <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:duration="1050"
- android:propertyName="pathData"
- android:startOffset="217"
- android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
- android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- 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:duration="783"
- android:propertyName="pathData"
- android:startOffset="1267"
- android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueType="pathType">
- <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:duration="167"
- android:propertyName="pathData"
- android:startOffset="2050"
- android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
- android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
- android:valueType="pathType">
- <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>
- </set>
- </aapt:attr>
- </target>
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="2750"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <aapt:attr name="android:drawable">
- <vector
- android:width="412dp"
- android:height="892dp"
- android:viewportHeight="892"
- android:viewportWidth="412">
- <group android:name="_R_G">
- <group
- android:name="_R_G_L_5_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/fake_wallpaper_color_light_mode"
- 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_4_G_N_3_T_0"
- android:scaleX="1"
- android:scaleY="1"
- android:translateX="206"
- android:translateY="446">
- <group
- android:name="_R_G_L_4_G"
- android:translateX="-206"
- android:translateY="-446">
- <group android:name="_R_G_L_4_G_L_0_G">
- <group
- android:name="_R_G_L_4_G_L_0_G_L_27_G"
- android:translateX="206"
- android:translateY="422.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_26_G"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_25_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_24_G"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_23_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_22_G"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_21_G"
- android:translateX="148.5"
- android:translateY="148">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_20_G"
- android:translateX="186"
- android:translateY="169">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_19_G"
- android:translateX="54"
- android:translateY="245">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_18_G"
- android:translateX="162"
- android:translateY="236">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_17_G"
- android:translateX="171.5"
- android:translateY="257">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_16_G"
- android:translateX="54"
- android:translateY="333">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_15_G"
- android:translateX="158"
- android:translateY="324">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_14_G"
- android:translateX="217.5"
- android:translateY="345">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_13_G"
- android:translateX="54"
- android:translateY="421">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_12_G"
- android:translateX="170"
- android:translateY="412">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_11_G"
- android:translateX="198.5"
- android:translateY="433">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_10_G"
- android:translateX="54"
- android:translateY="509">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_9_G"
- android:translateX="135"
- android:translateY="500">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_8_G"
- android:translateX="185.5"
- android:translateY="521">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_7_G"
- android:translateX="54"
- android:translateY="597">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_6_G"
- android:translateX="168.5"
- android:translateY="588">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_5_G"
- android:translateX="198.5"
- android:translateY="609">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_4_G"
- android:translateX="54"
- android:translateY="685">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_3_G"
- android:translateX="162.5"
- android:translateY="676">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_2_G"
- android:translateX="174"
- android:translateY="697">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_1_G"
- android:translateX="313.5"
- android:translateY="798">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
- </group>
- <group
- android:name="_R_G_L_4_G_L_0_G_L_0_G"
- android:translateX="205.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
- </group>
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_3_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_3_G"
- android:translateX="-206"
- android:translateY="-446">
- <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_27_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="422.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_26_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="496.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#dadce0"
- android:fillType="nonZero"
- android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_25_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- android:fillType="nonZero"
- android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_24_G"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="50.5">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#e8eaed"
- 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_23_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_22_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="157">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_21_G"
- android:scaleY="0"
- android:translateX="148.5"
- android:translateY="148">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_20_G"
- android:scaleY="0"
- android:translateX="186"
- android:translateY="169">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_19_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="245">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_18_G"
- android:scaleY="0"
- android:translateX="162"
- android:translateY="236">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_17_G"
- android:scaleY="0"
- android:translateX="171.5"
- android:translateY="257">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_16_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="333">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_15_G"
- android:scaleY="0"
- android:translateX="158"
- android:translateY="324">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_14_G"
- android:scaleY="0"
- android:translateX="217.5"
- android:translateY="345">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_13_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="421">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_12_G"
- android:scaleY="0"
- android:translateX="170"
- android:translateY="412">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_11_G"
- android:scaleY="0"
- android:translateX="198.5"
- android:translateY="433">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_10_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="509">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_9_G"
- android:scaleY="0"
- android:translateX="135"
- android:translateY="500">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_8_G"
- android:scaleY="0"
- android:translateX="185.5"
- android:translateY="521">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_7_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="597">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_6_G"
- android:scaleY="0"
- android:translateX="168.5"
- android:translateY="588">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_5_G"
- android:scaleY="0"
- android:translateX="198.5"
- android:translateY="609">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_4_G"
- android:scaleY="0"
- android:translateX="54"
- android:translateY="685">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- android:fillType="nonZero"
- android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_3_G"
- android:scaleY="0"
- android:translateX="162.5"
- android:translateY="676">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_2_G"
- android:scaleY="0"
- android:translateX="174"
- android:translateY="697">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_1_G"
- android:scaleY="0"
- android:translateX="313.5"
- android:translateY="798">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#bdc1c6"
- android:fillType="nonZero"
- android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
- </group>
- <group
- android:name="_R_G_L_3_G_L_0_G_L_0_G"
- android:scaleY="0"
- android:translateX="205.5"
- android:translateY="61">
- <path
- android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#f8f9fa"
- android:fillType="nonZero"
- android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
- </group>
- </group>
- </group>
- </group>
- <group
- android:name="_R_G_L_2_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_2_G"
- android:scaleX="1.3767699999999998"
- android:scaleY="1.3767699999999998"
- android:translateY="-508.163">
- <group
- android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
- android:scaleX="0"
- android:scaleY="0">
- <path
- android:name="_R_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="#9aa0a6"
- 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>
- <group
- android:name="_R_G_L_1_G_N_2_T_0"
- android:scaleX="0.6"
- android:scaleY="0"
- android:translateX="206"
- android:translateY="395">
- <group
- android:name="_R_G_L_1_G"
- android:scaleX="1.39"
- android:scaleY="1.39"
- android:translateX="-556.176"
- android:translateY="-7.307">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
- android:fillType="nonZero"
- android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
- </group>
- </group>
- <group
- android:name="_R_G_L_0_G"
- android:translateX="206"
- android:translateY="446">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#84ba69"
- android:fillType="nonZero"
- android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
- </group>
- </group>
- <group android:name="time_group" />
- </vector>
- </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index cc5c5a3..5020127 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,15 +36,6 @@
<color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
- <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
- <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
- <color name="fake_wallpaper_color_dark_mode">#000000</color> <!-- Black -->
- <color name="fake_wallpaper_color_light_mode">#f9f9f9</color> <!-- White -->
- <!-- Must contrast fake_wallpaper_color_dark_mode and fake_wallpaper_color_light_mode -->
- <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
- <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>
<color name="popup_color_tertiary_light">#E0E0E0</color> <!-- Gray 300 -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8457bd8..86b4e71 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -324,6 +324,7 @@
<dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
<dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
<dimen name="overview_task_margin">0dp</dimen>
+ <dimen name="overview_task_margin_focused">0dp</dimen>
<dimen name="overview_task_margin_grid">0dp</dimen>
<dimen name="overview_actions_margin_gesture">0dp</dimen>
<dimen name="overview_actions_top_margin_gesture_grid_portrait">0dp</dimen>
diff --git a/robolectric_tests/Android.bp b/robolectric_tests/Android.bp
index 9ed26ff..6473d00 100644
--- a/robolectric_tests/Android.bp
+++ b/robolectric_tests/Android.bp
@@ -40,7 +40,6 @@
name: "LauncherRoboTests",
srcs: [
":launcher3-robolectric-src",
- ":launcher3-test-src-common",
],
java_resources: [":launcher3-robolectric-resources"],
static_libs: [
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
deleted file mode 100644
index ea75548..0000000
--- a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2020 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.ui;
-
-import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
-import static com.android.launcher3.util.LauncherUIHelper.buildAndBindLauncher;
-import static com.android.launcher3.util.LauncherUIHelper.doLayout;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerProperties;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.folder.FolderPagedView;
-import com.android.launcher3.util.LauncherLayoutBuilder;
-import com.android.launcher3.util.LauncherLayoutBuilder.FolderBuilder;
-import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.widget.picker.WidgetsFullSheet;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
-import org.robolectric.shadows.ShadowLooper;
-
-/**
- * Tests scroll behavior at various Launcher UI components
- */
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
-@org.junit.Ignore
-public class LauncherUIScrollTest {
-
- private Context mTargetContext;
- private InvariantDeviceProfile mIdp;
- private LauncherModelHelper mModelHelper;
-
- private LauncherLayoutBuilder mLayoutBuilder;
-
- @Before
- public void setup() throws Exception {
- mModelHelper = new LauncherModelHelper();
- mTargetContext = RuntimeEnvironment.application;
- mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
-
- Settings.Global.putFloat(mTargetContext.getContentResolver(),
- Settings.Global.WINDOW_ANIMATION_SCALE, 0);
-
- mModelHelper.installApp(TEST_PACKAGE);
- // LayoutBuilder with 3 workspace pages
- mLayoutBuilder = new LauncherLayoutBuilder()
- .atWorkspace(0, mIdp.numRows - 1, 0).putApp(TEST_PACKAGE, TEST_PACKAGE)
- .atWorkspace(0, mIdp.numRows - 1, 1).putApp(TEST_PACKAGE, TEST_PACKAGE)
- .atWorkspace(0, mIdp.numRows - 1, 2).putApp(TEST_PACKAGE, TEST_PACKAGE);
- }
-
- @Test
- public void testWorkspacePagesBound() throws Exception {
- // Verify that the workspace if bound synchronously
- Launcher launcher = loadLauncher();
- assertEquals(3, launcher.getWorkspace().getPageCount());
- assertEquals(0, launcher.getWorkspace().getCurrentPage());
-
- launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
- assertNotEquals("Workspace was not scrolled",
- 0, launcher.getWorkspace().getNextPage());
- }
-
- @Test
- public void testAllAppsScroll() throws Exception {
- // Install 100 apps
- for (int i = 0; i < 100; i++) {
- mModelHelper.installApp(TEST_PACKAGE + i);
- }
-
- // Bind and open all-apps
- Launcher launcher = loadLauncher();
- launcher.getStateManager().goToState(LauncherState.ALL_APPS, false);
- doLayout(launcher);
-
- int currentScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
- launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
- int newScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
-
- assertNotEquals("All Apps was not scrolled", currentScroll, newScroll);
- assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
- }
-
- @Test
- public void testWidgetsListScroll() throws Exception {
- // Install 100 widgets
- for (int i = 0; i < 100; i++) {
- mModelHelper.installCustomShortcut(TEST_PACKAGE + i, "shortcutProvider");
- }
-
- // Bind and open widgets
- Launcher launcher = loadLauncher();
- WidgetsFullSheet widgets = WidgetsFullSheet.show(launcher, false);
- doLayout(launcher);
-
- int currentScroll = widgets.getRecyclerView().getCurrentScrollY();
- launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
- int newScroll = widgets.getRecyclerView().getCurrentScrollY();
- assertNotEquals("Widgets was not scrolled", currentScroll, newScroll);
- assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
- }
-
- @Test
- public void testFolderPageScroll() throws Exception {
- // Add a folder with multiple icons
- FolderBuilder fb = mLayoutBuilder.atWorkspace(mIdp.numColumns / 2, mIdp.numRows / 2, 0)
- .putFolder(0);
- for (int i = 0; i < 100; i++) {
- fb.addApp(TEST_PACKAGE, TEST_PACKAGE);
- }
-
- // Bind and open folder
- Launcher launcher = loadLauncher();
- doLayout(launcher);
- launcher.getWorkspace().getFirstMatch((i, v) -> v instanceof FolderIcon).performClick();
- ShadowLooper.idleMainLooper();
- doLayout(launcher);
- FolderPagedView folderPages = Folder.getOpen(launcher).getContent();
-
- assertEquals(0, folderPages.getNextPage());
- launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
- assertNotEquals("Folder page was not scrolled", 0, folderPages.getNextPage());
- assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
- }
-
- private Launcher loadLauncher() throws Exception {
- mModelHelper.setupDefaultLayoutProvider(mLayoutBuilder).loadModelSync();
- return buildAndBindLauncher();
- }
-
- private static MotionEvent createScrollEvent(int scroll) {
- DeviceProfile dp = InvariantDeviceProfile.INSTANCE
- .get(RuntimeEnvironment.application).supportedProfiles.get(0);
-
- final PointerProperties[] pointerProperties = new PointerProperties[1];
- pointerProperties[0] = new PointerProperties();
- pointerProperties[0].id = 0;
- final MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[1];
- coords[0] = new MotionEvent.PointerCoords();
- coords[0].setAxisValue(MotionEvent.AXIS_VSCROLL, scroll);
- coords[0].x = dp.widthPx / 2;
- coords[0].y = dp.heightPx / 2;
-
- final long time = SystemClock.uptimeMillis();
- return MotionEvent.obtain(time, time, MotionEvent.ACTION_SCROLL, 1,
- pointerProperties, coords, 0, 0, 1.0f, 1.0f, 0, 0,
- InputDevice.SOURCE_CLASS_POINTER, 0);
- }
-
-}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
deleted file mode 100644
index 1090d1e..0000000
--- a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * 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.widget;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.os.UserHandle;
-import android.util.Size;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.testing.TestActivity;
-import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-@RunWith(RobolectricTestRunner.class)
-public class CachingWidgetPreviewLoaderTest {
- private final Size SIZE_10_10 = new Size(10, 10);
- private final Size SIZE_20_20 = new Size(20, 20);
- private static final String TEST_PACKAGE = "com.example.test";
- private final ComponentName TEST_PROVIDER =
- new ComponentName(TEST_PACKAGE, ".WidgetProvider");
- private final ComponentName TEST_PROVIDER2 =
- new ComponentName(TEST_PACKAGE, ".WidgetProvider2");
- private final Bitmap BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
- private final Bitmap BITMAP2 = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
-
-
- @Mock private CancellationSignal mCancellationSignal;
- @Mock private WidgetPreviewLoader mDelegate;
- @Mock private IconCache mIconCache;
- @Mock private DeviceProfile mDeviceProfile;
- @Mock private LauncherAppWidgetProviderInfo mProviderInfo;
- @Mock private LauncherAppWidgetProviderInfo mProviderInfo2;
- @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback;
- @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback2;
- @Captor private ArgumentCaptor<WidgetPreviewLoadedCallback> mCallbackCaptor;
-
- private TestActivity mTestActivity;
- private CachingWidgetPreviewLoader mLoader;
- private WidgetItem mWidgetItem;
- private WidgetItem mWidgetItem2;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mLoader = new CachingWidgetPreviewLoader(mDelegate);
-
- mTestActivity = Robolectric.buildActivity(TestActivity.class).setup().get();
- mTestActivity.setDeviceProfile(mDeviceProfile);
-
- when(mDelegate.loadPreview(any(), any(), any(), any())).thenReturn(mCancellationSignal);
-
- mProviderInfo.provider = TEST_PROVIDER;
- when(mProviderInfo.getProfile()).thenReturn(new UserHandle(0));
-
- mProviderInfo2.provider = TEST_PROVIDER2;
- when(mProviderInfo2.getProfile()).thenReturn(new UserHandle(0));
-
- InvariantDeviceProfile testProfile = new InvariantDeviceProfile();
- testProfile.numRows = 5;
- testProfile.numColumns = 5;
-
- mWidgetItem = new WidgetItem(mProviderInfo, testProfile, mIconCache);
- mWidgetItem2 = new WidgetItem(mProviderInfo2, testProfile, mIconCache);
- }
-
- @Test
- public void getPreview_notInCache_shouldReturnNull() {
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
- }
-
- @Test
- public void getPreview_notInCache_shouldNotCallDelegate() {
- mLoader.getPreview(mWidgetItem, SIZE_10_10);
-
- verifyZeroInteractions(mDelegate);
- }
-
- @Test
- public void getPreview_inCache_shouldReturnCachedBitmap() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
- }
-
- @Test
- public void getPreview_otherSizeInCache_shouldReturnNull() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isNull();
- }
-
- @Test
- public void getPreview_otherItemInCache_shouldReturnNull() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- assertThat(mLoader.getPreview(mWidgetItem2, SIZE_10_10)).isNull();
- }
-
- @Test
- public void getPreview_shouldStoreMultipleSizesPerItem() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP2);
-
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isEqualTo(BITMAP2);
- }
-
- @Test
- public void loadPreview_notInCache_shouldStartLoading() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
- verify(mDelegate).loadPreview(eq(mTestActivity), eq(mWidgetItem), eq(SIZE_10_10), any());
- verifyZeroInteractions(mPreviewLoadedCallback);
- }
-
- @Test
- public void loadPreview_thenLoaded_shouldCallBack() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
- WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
- loaderCallback.onPreviewLoaded(BITMAP);
-
- verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
- }
-
- @Test
- public void loadPreview_thenCancelled_shouldCancelDelegateRequest() {
- CancellationSignal cancellationSignal =
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
- cancellationSignal.cancel();
-
- verify(mCancellationSignal).cancel();
- verifyZeroInteractions(mPreviewLoadedCallback);
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
- }
-
- @Test
- public void loadPreview_thenCancelled_otherCallListening_shouldNotCancelDelegateRequest() {
- CancellationSignal cancellationSignal1 =
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
- cancellationSignal1.cancel();
-
- verifyZeroInteractions(mCancellationSignal);
- }
-
- @Test
- public void loadPreview_thenCancelled_otherCallListening_loaded_shouldCallBackToNonCancelled() {
- CancellationSignal cancellationSignal1 =
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
- verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
- WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
- cancellationSignal1.cancel();
- loaderCallback.onPreviewLoaded(BITMAP);
-
- verifyZeroInteractions(mPreviewLoadedCallback);
- verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
- }
-
- @Test
- public void loadPreview_thenCancelled_bothCallsCancelled_shouldCancelDelegateRequest() {
- CancellationSignal cancellationSignal1 =
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- CancellationSignal cancellationSignal2 =
- mLoader.loadPreview(
- mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
- cancellationSignal1.cancel();
- cancellationSignal2.cancel();
-
- verify(mCancellationSignal).cancel();
- verifyZeroInteractions(mPreviewLoadedCallback);
- verifyZeroInteractions(mPreviewLoadedCallback2);
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
- }
-
- @Test
- public void loadPreview_multipleCallbacks_shouldOnlyCallDelegateOnce() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
- verify(mDelegate).loadPreview(any(), any(), any(), any());
- }
-
- @Test
- public void loadPreview_multipleCallbacks_shouldForwardResultToEachCallback() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
- verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
- WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
- loaderCallback.onPreviewLoaded(BITMAP);
-
- verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
- verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
- }
-
- @Test
- public void loadPreview_inCache_shouldCallBackImmediately() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- reset(mDelegate);
-
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
- verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
- verifyZeroInteractions(mDelegate);
- }
-
- @Test
- public void loadPreview_thenLoaded_thenCancelled_shouldNotRemovePreviewFromCache() {
- CancellationSignal cancellationSignal =
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
- verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
- WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
- loaderCallback.onPreviewLoaded(BITMAP);
-
- cancellationSignal.cancel();
-
- assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
- }
-
- @Test
- public void isPreviewLoaded_notLoaded_shouldReturnFalse() {
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void isPreviewLoaded_otherSizeLoaded_shouldReturnFalse() {
- loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void isPreviewLoaded_otherItemLoaded_shouldReturnFalse() {
- loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void isPreviewLoaded_loaded_shouldReturnTrue() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isTrue();
- }
-
- @Test
- public void clearPreviews_notInCache_shouldBeNoOp() {
- mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void clearPreviews_inCache_shouldRemovePreview() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void clearPreviews_inCache_multipleSizes_shouldRemoveAllSizes() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
- mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
- }
-
- @Test
- public void clearPreviews_inCache_otherItems_shouldOnlyRemoveSpecifiedItems() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
- mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isTrue();
- }
-
- @Test
- public void clearPreviews_inCache_otherItems_shouldRemoveAllSpecifiedItems() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
- mLoader.clearPreviews(Arrays.asList(mWidgetItem, mWidgetItem2));
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void clearPreviews_loading_shouldCancelLoad() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
- mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
- verify(mCancellationSignal).cancel();
- }
-
- @Test
- public void clearAll_cacheEmpty_shouldBeNoOp() {
- mLoader.clearAll();
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void clearAll_inCache_shouldRemovePreview() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
- mLoader.clearAll();
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- }
-
- @Test
- public void clearAll_inCache_multipleSizes_shouldRemoveAllSizes() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
- mLoader.clearAll();
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
- }
-
- @Test
- public void clearAll_inCache_multipleItems_shouldRemoveAll() {
- loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
- loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
- loadPreviewIntoCache(mWidgetItem2, SIZE_20_20, BITMAP);
-
- mLoader.clearAll();
-
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
- assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_20_20)).isFalse();
- }
-
- @Test
- public void clearAll_loading_shouldCancelLoad() {
- mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
- mLoader.clearAll();
-
- verify(mCancellationSignal).cancel();
- }
-
- private void loadPreviewIntoCache(WidgetItem widgetItem, Size size, Bitmap bitmap) {
- reset(mDelegate);
- mLoader.loadPreview(mTestActivity, widgetItem, size, ignored -> {});
- verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
- WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
- loaderCallback.onPreviewLoaded(bitmap);
- }
-}
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 9778b61..ec96c6d 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -145,6 +145,7 @@
/**
* Returns {@link StatsLogManager} for user event logging.
*/
+ @Override
public StatsLogManager getStatsLogManager() {
if (mStatsLogManager == null) {
mStatsLogManager = StatsLogManager.newInstance(this);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 353e52b..02ec5e8 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -256,9 +256,27 @@
@UiThread
public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
+ applyFromWorkspaceItem(info, /* animate = */ false, /* staggerIndex = */ 0);
+ }
+
+ @UiThread
+ public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
applyFromWorkspaceItem(info, false);
}
+ /**
+ * Returns whether the newInfo differs from the current getTag().
+ */
+ public boolean shouldAnimateIconChange(WorkspaceItemInfo newInfo) {
+ WorkspaceItemInfo oldInfo = getTag() instanceof WorkspaceItemInfo
+ ? (WorkspaceItemInfo) getTag()
+ : null;
+ boolean changedIcons = oldInfo != null && oldInfo.getTargetComponent() != null
+ && newInfo.getTargetComponent() != null
+ && !oldInfo.getTargetComponent().equals(newInfo.getTargetComponent());
+ return changedIcons && isShown();
+ }
+
@Override
public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
if (delegate instanceof LauncherAccessibilityDelegate) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 2b1d8f6..b7d0481 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -179,6 +179,7 @@
// Overview
public final boolean overviewShowAsGrid;
public int overviewTaskMarginPx;
+ public int overviewTaskMarginGridPx;
public int overviewTaskIconSizePx;
public int overviewTaskIconDrawableSizePx;
public int overviewTaskIconDrawableSizeGridPx;
@@ -247,7 +248,8 @@
// Tablet UI does not support emulated landscape.
isTablet = allowRotation && info.isTablet(windowBounds);
isPhone = !isTablet;
- isTwoPanels = isTablet && useTwoPanels;
+ isTwoPanels = isTablet && useTwoPanels
+ && (isLandscape || FeatureFlags.ENABLE_TWO_PANEL_HOME_IN_PORTRAIT.get());
aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx);
boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0;
@@ -354,8 +356,9 @@
overviewShowAsGrid = isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
overviewTaskMarginPx = overviewShowAsGrid
- ? res.getDimensionPixelSize(R.dimen.overview_task_margin_grid)
+ ? res.getDimensionPixelSize(R.dimen.overview_task_margin_focused)
: res.getDimensionPixelSize(R.dimen.overview_task_margin);
+ overviewTaskMarginGridPx = res.getDimensionPixelSize(R.dimen.overview_task_margin_grid);
overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
overviewTaskIconDrawableSizePx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4d5cc5e..6ea7b17 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2186,6 +2186,24 @@
}
private void bindAddScreens(IntArray orderedScreenIds) {
+ if (mDeviceProfile.isTwoPanels) {
+ // Some empty pages might have been removed while the phone was in a single panel
+ // mode, so we want to add those empty pages back.
+ IntSet screenIds = IntSet.wrap(orderedScreenIds);
+ for (int i = 0; i < orderedScreenIds.size(); i++) {
+ int screenId = orderedScreenIds.get(i);
+ // Don't add the page pair if the page is the last one and if the pair is on the
+ // right, because that would cause a bug when adding new pages.
+ // TODO: (b/196376162) remove this when the new screen id logic is fixed for two
+ // panel in Workspace::commitExtraEmptyScreen
+ if (i == orderedScreenIds.size() - 1 && screenId % 2 == 0) {
+ continue;
+ }
+ screenIds.add(mWorkspace.getPagePair(screenId));
+ }
+ orderedScreenIds = screenIds.getArray();
+ }
+
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
int screenId = orderedScreenIds.get(i);
@@ -2193,7 +2211,6 @@
// No need to bind the first screen, as its always bound.
continue;
}
-
mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(screenId);
}
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 3d6be69..702b73a 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -48,7 +48,6 @@
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.custom.CustomWidgetManager;
public class LauncherAppState {
@@ -64,7 +63,6 @@
private final LauncherModel mModel;
private final IconProvider mIconProvider;
private final IconCache mIconCache;
- private final DatabaseWidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
private final RunnableList mOnTerminateCallback = new RunnableList();
@@ -139,7 +137,6 @@
mIconProvider = new IconProvider(context, Themes.isThemedIconEnabled(context));
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
iconCacheFileName, mIconProvider);
- mWidgetCache = new DatabaseWidgetPreviewLoader(mContext, mIconCache);
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
mOnTerminateCallback.add(mIconCache::close);
}
@@ -155,7 +152,6 @@
LauncherIcons.clearPool();
mIconCache.updateIconParams(
mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
- mWidgetCache.refresh();
mModel.forceReload();
}
@@ -181,10 +177,6 @@
return mModel;
}
- public DatabaseWidgetPreviewLoader getWidgetCache() {
- return mWidgetCache;
- }
-
public InvariantDeviceProfile getInvariantDeviceProfile() {
return mInvariantDeviceProfile;
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 6966abf..7b6a5bf 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -72,6 +72,7 @@
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -383,7 +384,13 @@
loaderResults.bindWidgets();
return true;
} else {
- startLoaderForResults(loaderResults);
+ stopLoader();
+ mLoaderTask = new LoaderTask(
+ mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);
+
+ // Always post the loader task, instead of running directly
+ // (even on same thread) so that we exit any nested synchronized blocks
+ MODEL_EXECUTOR.post(mLoaderTask);
}
}
}
@@ -406,25 +413,17 @@
}
}
- public void startLoaderForResults(LoaderResults results) {
+ /**
+ * Loads the model if not loaded
+ * @param callback called with the data model upon successful load or null on model thread.
+ */
+ public void loadAsync(Consumer<BgDataModel> callback) {
synchronized (mLock) {
- stopLoader();
- mLoaderTask = new LoaderTask(
- mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results);
-
- // Always post the loader task, instead of running directly (even on same thread) so
- // that we exit any nested synchronized blocks
- MODEL_EXECUTOR.post(mLoaderTask);
- }
- }
-
- public void startLoaderForResultsIfNotLoaded(LoaderResults results) {
- synchronized (mLock) {
- if (!isModelLoaded()) {
- Log.d(TAG, "Workspace not loaded, loading now");
- startLoaderForResults(results);
+ if (!mModelLoaded && !mIsLoaderTaskRunning) {
+ startLoader();
}
}
+ MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null));
}
@Override
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index d162abd..94ec903 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -123,6 +123,7 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -333,7 +334,8 @@
int paddingBottom = grid.cellLayoutBottomPaddingPx;
int panelCount = getPanelCount();
- for (int i = mWorkspaceScreens.size() - 1; i >= 0; i--) {
+ int numberOfScreens = mScreenOrder.size();
+ for (int i = 0; i < numberOfScreens; i++) {
int paddingLeft = paddingLeftRight;
int paddingRight = paddingLeftRight;
if (panelCount > 1) {
@@ -348,7 +350,9 @@
paddingRight = 0;
}
}
- mWorkspaceScreens.valueAt(i).setPadding(paddingLeft, 0, paddingRight, paddingBottom);
+ // SparseArrayMap doesn't keep the order
+ mWorkspaceScreens.get(mScreenOrder.get(i))
+ .setPadding(paddingLeft, 0, paddingRight, paddingBottom);
}
}
@@ -683,8 +687,9 @@
CellLayout finalScreen = mWorkspaceScreens.get(finalScreenId);
// If the final screen is empty, convert it to the extra empty screen
- if (finalScreen.getShortcutsAndWidgets().getChildCount() == 0 &&
- !finalScreen.isDropPending()) {
+ if (finalScreen != null
+ && finalScreen.getShortcutsAndWidgets().getChildCount() == 0
+ && !finalScreen.isDropPending()) {
mWorkspaceScreens.remove(finalScreenId);
mScreenOrder.removeValue(finalScreenId);
@@ -796,6 +801,21 @@
return mScreenOrder;
}
+ /**
+ * Returns the page that is shown together with the given page when two panel is enabled.
+ * @throws IllegalStateException if called while two panel home isn't enabled.
+ */
+ public int getPagePair(int page) {
+ if (!isTwoPanelEnabled()) {
+ throw new IllegalStateException("Two panel home isn't enabled.");
+ }
+ if (page % 2 == 0) {
+ return page + 1;
+ } else {
+ return page - 1;
+ }
+ }
+
public void stripEmptyScreens() {
if (mLauncher.isWorkspaceLoading()) {
// Don't strip empty screens if the workspace is still loading.
@@ -821,6 +841,22 @@
}
}
+ // When two panel home is enabled we only remove an empty page if both visible pages are
+ // empty.
+ if (isTwoPanelEnabled()) {
+ // We go through all the pages that were marked as removable and check their page pair
+ Iterator<Integer> removeScreensIterator = removeScreens.iterator();
+ while (removeScreensIterator.hasNext()) {
+ int pageToRemove = removeScreensIterator.next();
+ int pagePair = getPagePair(pageToRemove);
+ if (!removeScreens.contains(pagePair)) {
+ // The page pair isn't empty so we want to remove the current page from the
+ // removable pages' collection
+ removeScreensIterator.remove();
+ }
+ }
+ }
+
// We enforce at least one page to add new items to. In the case that we remove the last
// such screen, we convert the last screen to the empty screen
int minScreens = 1;
diff --git a/src/com/android/launcher3/WorkspaceLayoutManager.java b/src/com/android/launcher3/WorkspaceLayoutManager.java
index d6302ce..44a5536 100644
--- a/src/com/android/launcher3/WorkspaceLayoutManager.java
+++ b/src/com/android/launcher3/WorkspaceLayoutManager.java
@@ -32,6 +32,8 @@
int EXTRA_EMPTY_SCREEN_ID = -201;
// The is the first screen. It is always present, even if its empty.
int FIRST_SCREEN_ID = 0;
+ // This is the second page. On two panel home it is always present, even if its empty.
+ int SECOND_SCREEN_ID = 1;
/**
* At bind time, we use the rank (screenId) to compute x and y for hotseat items.
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index d2c71b2..f420ec2 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -499,8 +499,10 @@
private void replaceRVContainer(boolean showTabs) {
for (int i = 0; i < mAH.length; i++) {
- if (mAH[i].recyclerView != null) {
- mAH[i].recyclerView.setLayoutManager(null);
+ AllAppsRecyclerView rv = mAH[i].recyclerView;
+ if (rv != null) {
+ rv.setLayoutManager(null);
+ rv.setAdapter(null);
}
}
View oldView = getRecyclerViewContainer();
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 2c84a3d..bddbbd0 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -63,6 +63,13 @@
private final SparseIntArray mCachedScrollPositions = new SparseIntArray();
private final AllAppsFastScrollHelper mFastScrollHelper;
+
+ private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {
+ public void onChanged() {
+ mCachedScrollPositions.clear();
+ }
+ };
+
// The empty-search result background
private AllAppsBackgroundDrawable mEmptySearchBackground;
private int mEmptySearchBackgroundTopOffset;
@@ -247,12 +254,13 @@
@Override
public void setAdapter(Adapter adapter) {
+ if (getAdapter() != null) {
+ getAdapter().unregisterAdapterDataObserver(mObserver);
+ }
super.setAdapter(adapter);
- adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- public void onChanged() {
- mCachedScrollPositions.clear();
- }
- });
+ if (adapter != null) {
+ adapter.registerAdapterDataObserver(mObserver);
+ }
}
@Override
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 38a957d..74c7310 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -230,6 +230,10 @@
"ENABLE_TWO_PANEL_HOME", true,
"Uses two panel on home screen. Only applicable on large screen devices.");
+ public static final BooleanFlag ENABLE_TWO_PANEL_HOME_IN_PORTRAIT = getDebugFlag(
+ "ENABLE_TWO_PANEL_HOME_IN_PORTRAIT", true,
+ "Uses two panel on home screen in portrait if ENABLE_TWO_PANEL_HOME is enabled.");
+
public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(
"ENABLE_SCRIM_FOR_APP_LAUNCH", false,
"Enables scrim during app launch animation.");
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 92ed18a..466b268 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -286,9 +286,7 @@
@Override
protected void onPostExecute(WidgetItem item) {
- mWidgetCell.setPreviewSize(item);
- mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
- mWidgetCell.ensurePreview();
+ mWidgetCell.applyFromCellItem(item);
}
}.executeOnExecutor(MODEL_EXECUTOR);
// TODO: Create a worker looper executor and reuse that everywhere.
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index a96de31..94c578e 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -65,6 +65,7 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
import com.android.launcher3.WorkspaceLayoutManager;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
@@ -279,7 +280,7 @@
mDp.workspacePadding.top,
mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
mDp.workspacePadding.bottom);
- mWorkspaceScreens.put(PreviewSurfaceRenderer.SECOND_SCREEN_ID, rightPanel);
+ mWorkspaceScreens.put(Workspace.SECOND_SCREEN_ID, rightPanel);
}
if (Utilities.ATLEAST_S) {
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index f7dd6b2..f4d1e61 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -49,7 +49,6 @@
import com.android.launcher3.model.GridSizeMigrationTaskV2;
import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelDelegate;
-import com.android.launcher3.model.ModelPreload;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
@@ -67,9 +66,6 @@
private static final int FADE_IN_ANIMATION_DURATION = 200;
- // The is the second screen. It is always present in two panel, even if its empty.
- static final int SECOND_SCREEN_ID = 1;
-
private static final String KEY_HOST_TOKEN = "host_token";
private static final String KEY_VIEW_WIDTH = "width";
private static final String KEY_VIEW_HEIGHT = "height";
@@ -173,7 +169,7 @@
+ LauncherSettings.Favorites.CONTAINER_HOTSEAT;
if (deviceProfile.isTwoPanels) {
query += " or " + LauncherSettings.Favorites.SCREEN + " = "
- + SECOND_SCREEN_ID;
+ + Workspace.SECOND_SCREEN_ID;
}
loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI,
query);
@@ -185,18 +181,13 @@
}
}.run();
} else {
- new ModelPreload() {
-
- @Override
- public void onComplete(boolean isSuccess) {
- if (isSuccess) {
- MAIN_EXECUTOR.execute(() ->
- renderView(inflationContext, getBgDataModel(), null));
- } else {
- Log.e(TAG, "Model loading failed");
- }
+ LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> {
+ if (dataModel != null) {
+ MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null));
+ } else {
+ Log.e(TAG, "Model loading failed");
}
- }.start(inflationContext);
+ });
}
}
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index a13fa55..fea15c4 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
+import static com.android.launcher3.WorkspaceLayoutManager.SECOND_SCREEN_ID;
import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
@@ -299,6 +300,11 @@
IntSet screensToExclude = new IntSet();
if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
screensToExclude.add(FIRST_SCREEN_ID);
+
+ // On split display we don't want to add the new items onto the second screen.
+ if (app.getInvariantDeviceProfile().isSplitDisplay) {
+ screensToExclude.add(SECOND_SCREEN_ID);
+ }
}
for (int screen = 0; screen < screenCount; screen++) {
diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java
deleted file mode 100644
index 756b7da..0000000
--- a/src/com/android/launcher3/model/ModelPreload.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 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.model;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherModel.ModelUpdateTask;
-import com.android.launcher3.model.BgDataModel.Callbacks;
-
-import java.util.concurrent.Executor;
-
-/**
- * Utility class to preload LauncherModel
- */
-public class ModelPreload implements ModelUpdateTask {
-
- private static final String TAG = "ModelPreload";
-
- private LauncherAppState mApp;
- private LauncherModel mModel;
- private BgDataModel mBgDataModel;
- private AllAppsList mAllAppsList;
-
- @Override
- public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel,
- AllAppsList allAppsList, Executor uiExecutor) {
- mApp = app;
- mModel = model;
- mBgDataModel = dataModel;
- mAllAppsList = allAppsList;
- }
-
- @Override
- public final void run() {
- mModel.startLoaderForResultsIfNotLoaded(
- new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0]));
- MODEL_EXECUTOR.post(() -> {
- Log.d(TAG, "Preload completed : " + mModel.isModelLoaded());
- onComplete(mModel.isModelLoaded());
- });
- }
-
- public BgDataModel getBgDataModel() {
- return mBgDataModel;
- }
-
- /**
- * Called when the task is complete
- */
- @WorkerThread
- public void onComplete(boolean isSuccess) { }
-
- public void start(Context context) {
- LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this);
- }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 82b0f7c..83fb3d1 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -123,7 +123,6 @@
iconCache.updateIconsForPkg(packages[i], mUser);
activitiesLists.put(
packages[i], appsList.updatePackage(context, packages[i], mUser));
- app.getWidgetCache().removePackage(packages[i], mUser);
// The update may have changed which shortcuts/widgets are available.
// Refresh the widgets for the package if we have an activity running.
@@ -148,7 +147,6 @@
for (int i = 0; i < N; i++) {
if (DEBUG) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
appsList.removePackage(packages[i], mUser);
- app.getWidgetCache().removePackage(packages[i], mUser);
}
flagOp = FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
break;
diff --git a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
index 6215827..31436c4 100644
--- a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
+++ b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
@@ -22,6 +22,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
/**
* Creates and populates views with data
@@ -46,7 +47,7 @@
V newViewHolder(ViewGroup parent);
/** Populate UI references in {@link ViewHolder} with data. */
- void bindViewHolder(V viewHolder, T data, @ListPosition int position);
+ void bindViewHolder(V viewHolder, T data, @ListPosition int position, List<Object> payloads);
/**
* Called when the view is recycled. Views are recycled in batches once they are sufficiently
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index b34af97..24d3fd4 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -18,6 +18,7 @@
import static android.animation.ValueAnimator.areAnimatorsEnabled;
+import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.AnimatorPlaybackController.callListenerCommandRecursively;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
@@ -27,12 +28,14 @@
import android.animation.AnimatorSet;
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
+import com.android.launcher3.testing.TestProtocol;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -253,6 +256,9 @@
if (listener != null) {
animation.addListener(listener);
}
+ if (TestProtocol.sDebugTracing && state == NORMAL) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "goToStateAnimated: " + state);
+ }
mUiHandler.post(new StartAnimRunnable(animation));
}
@@ -328,11 +334,17 @@
@Override
public void onAnimationStart(Animator animation) {
// Change the internal state only when the transition actually starts
+ if (TestProtocol.sDebugTracing && state == NORMAL) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "onAnimationStart: " + state);
+ }
onStateTransitionStart(state);
}
@Override
public void onAnimationSuccess(Animator animator) {
+ if (TestProtocol.sDebugTracing && state == NORMAL) {
+ Log.d(TestProtocol.L3_SWIPE_TO_HOME, "onAnimationEnd: " + state);
+ }
onStateTransitionEnd(state);
}
};
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 1c5b31b..c484811 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -119,4 +119,5 @@
public static final String FALLBACK_ACTIVITY_NO_SET = "b/181019015";
public static final String THIRD_PARTY_LAUNCHER_NOT_SET = "b/187080582";
public static final String TASK_VIEW_ID_CRASH = "b/195430732";
+ public static final String L3_SWIPE_TO_HOME = "b/192018189";
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 816e5dc..17a00e2 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -35,13 +36,16 @@
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.launcher3.views.BaseDragLayer;
import java.util.Collections;
@@ -162,16 +166,24 @@
}
@Override
- public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
DeviceProfile dp) {
// Don't use device profile here because we know we're in fake landscape, only split option
// available is top/left
- if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//<<<<<<< HEAD
+// if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+// // Top (visually left) side
+// return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+// }
+// throw new IllegalStateException("Invalid split stage position: " +
+// splitPosition.stagePosition);
+//=======
+ if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
// Top (visually left) side
return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
}
- throw new IllegalStateException("Invalid split stage position: " +
- splitPosition.mStagePosition);
+ throw new IllegalStateException("Invalid split stage position: " + stagePosition);
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
}
@Override
@@ -364,7 +376,7 @@
@Override
public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
- SplitPositionOption splitPositionOption, Rect out) {
+ @StagePosition int stagePosition, Rect out) {
// In fake land/seascape, the placeholder always needs to go to the "top" of the device,
// which is the same bounds as 0 rotation.
int width = dp.widthPx;
@@ -373,7 +385,7 @@
@Override
public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- SplitPositionOption initialSplitOption, Rect out1, Rect out2) {
+ @StagePosition int stagePosition, Rect out1, Rect out2) {
// In fake land/seascape, the window bounds are always top and bottom half
int screenHeight = dp.heightPx;
int screenWidth = dp.widthPx;
@@ -382,6 +394,55 @@
}
@Override
+//<<<<<<< HEAD
+ public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ float diff;
+ if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+ diff = outRect.height() * (1f - splitInfo.leftTaskPercent);
+ outRect.bottom -= diff;
+ } else {
+ diff = outRect.height() * splitInfo.leftTaskPercent;
+ outRect.top += diff;
+ }
+ }
+
+ @Override
+ public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // The preview set is for the bottom/right, inset by top/left task
+ splitOffset.x = splitInfo.leftTopBounds.width() + splitInfo.dividerBounds.width() / 2;
+ }
+ }
+
+ @Override
+ public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+ View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+ DeviceProfile dp) {
+ int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+ int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+ int totalThumbnailWidth = taskParent.getWidth();
+ int dividerBar = splitBoundsConfig.dividerBounds.width() / 2;
+ ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+ ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+ primaryLp.width = totalThumbnailWidth;
+ primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.leftTaskPercent);
+
+ secondaryLp.width = totalThumbnailWidth;
+ secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+ mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+ }
+
+//=======
+ @Override
+ public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
+ throw new IllegalStateException("Default position not available in fake landscape");
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
+ }
+
+ @Override
public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
DeviceProfile deviceProfile) {
return primary;
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index dae2dde..b34a81e 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -31,6 +32,7 @@
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
@@ -78,11 +80,11 @@
FloatProperty<View> getSecondaryViewTranslate();
/**
- * @param splitPosition The position where the view to be split will go
+ * @param stagePosition The position where the view to be split will go
* @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
* dismissal should happen
*/
- int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
+ int getSplitTaskViewDismissDirection(@StagePosition int stagePosition, DeviceProfile dp);
int getPrimaryScroll(View view);
float getPrimaryScale(View view);
int getChildStart(View view);
@@ -120,18 +122,48 @@
* @param splitholderSize height of placeholder view in portrait, width in landscape
*/
void getInitialSplitPlaceholderBounds(int splitholderSize, DeviceProfile dp,
- SplitPositionOption splitPositionOption, Rect out);
+ @StagePosition int stagePosition, Rect out);
/**
* @param splitDividerSize height of split screen drag handle in portrait, width in landscape
- * @param initialSplitOption the split position option (top/left, bottom/right) of the first
+ * @param stagePosition the split position option (top/left, bottom/right) of the first
* task selected for entering split
* @param out1 the bounds for where the first selected app will be
* @param out2 the bounds for where the second selected app will be, complimentary to
* {@param out1} based on {@param initialSplitOption}
*/
void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- SplitPositionOption initialSplitOption, Rect out1, Rect out2);
+ @StagePosition int stagePosition, Rect out1, Rect out2);
+
+ int getDefaultSplitPosition(DeviceProfile deviceProfile);
+
+ /**
+ * @param outRect This is expected to be the rect that has the dimensions for a non-split,
+ * fullscreen task in overview. This will directly be modified.
+ * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
+ * outRect for
+ */
+ void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo,
+ @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+ /**
+ * It's important to note that {@link #setSplitTaskSwipeRect(DeviceProfile, Rect,
+ * SplitConfigurationOptions.StagedSplitBounds, int)} above operates on the outRect based on
+ * launcher's coordinate system, meaning it will treat the outRect as portrait if home rotation
+ * is not allowed.
+ *
+ * However, here the splitOffset is from perspective of TaskViewSimulator, which is in display
+ * orientation coordinates. So, for example, for the fake landscape scenario, even though
+ * launcher is portrait, we inset the bottom/right task by an X coordinate instead of the
+ * usual Y
+ */
+ void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo,
+ @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+ void setGroupedTaskViewThumbnailBounds(View mSnapshot1, View mSnapshot2, View taskParent,
+ SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp);
// Overview TaskMenuView methods
float getTaskMenuX(float x, View thumbnailView, int overScroll);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 1253589..640e6cc 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -25,6 +25,7 @@
import android.content.res.Resources;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -34,13 +35,16 @@
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
@@ -162,9 +166,13 @@
}
@Override
- public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
DeviceProfile dp) {
- if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//<<<<<<< HEAD
+// if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//=======
+ if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
if (dp.isLandscape) {
// Left side
return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
@@ -172,12 +180,20 @@
// Top side
return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
}
- } else if (splitPosition.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+//<<<<<<< HEAD
+// } else if (splitPosition.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // We don't have a bottom option, so should be right
+// return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
+// }
+// throw new IllegalStateException("Invalid split stage position: " +
+// splitPosition.stagePosition);
+//=======
+ } else if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
// We don't have a bottom option, so should be right
return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
}
- throw new IllegalStateException("Invalid split stage position: " +
- splitPosition.mStagePosition);
+ throw new IllegalStateException("Invalid split stage position: " + stagePosition);
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
}
@Override
@@ -413,7 +429,7 @@
@Override
public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
- SplitPositionOption splitPositionOption, Rect out) {
+ @StagePosition int stagePosition, Rect out) {
int width = dp.widthPx;
out.set(0, 0, width, placeholderHeight);
if (!dp.isLandscape) {
@@ -422,7 +438,11 @@
}
// Now we rotate the portrait rect depending on what side we want pinned
- boolean pinToRight = splitPositionOption.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//<<<<<<< HEAD
+// boolean pinToRight = splitPositionOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//=======
+ boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
int screenHeight = dp.heightPx;
float postRotateScale = (float) screenHeight / width;
@@ -439,7 +459,7 @@
@Override
public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- SplitPositionOption initialSplitOption, Rect out1, Rect out2) {
+ @StagePosition int stagePosition, Rect out1, Rect out2) {
int screenHeight = dp.heightPx;
int screenWidth = dp.widthPx;
out1.set(0, 0, screenWidth, screenHeight / 2 - splitDividerSize);
@@ -450,7 +470,11 @@
}
// Now we rotate the portrait rect depending on what side we want pinned
- boolean pinToRight = initialSplitOption.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//<<<<<<< HEAD
+// boolean pinToRight = initialSplitOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//=======
+ boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
float postRotateScale = (float) screenHeight / screenWidth;
mTmpMatrix.reset();
@@ -468,6 +492,92 @@
}
@Override
+//<<<<<<< HEAD
+ public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ boolean isLandscape = dp.isLandscape;
+ float diff;
+ if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+ if (isLandscape) {
+ diff = outRect.width() * (1f - splitInfo.leftTaskPercent);
+ outRect.right -= diff;
+ } else {
+ diff = outRect.height() * (1f - splitInfo.topTaskPercent);
+ outRect.bottom -= diff;
+ }
+ } else {
+ if (isLandscape) {
+ diff = outRect.width() * splitInfo.leftTaskPercent;
+ outRect.left += diff;
+ } else {
+ diff = outRect.height() * splitInfo.topTaskPercent;
+ outRect.top += diff;
+ }
+ }
+ }
+
+ @Override
+ public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ if (dp.isLandscape) {
+ splitOffset.x = splitInfo.leftTopBounds.width() +
+ splitInfo.dividerBounds.width() / 2;
+ } else {
+ splitOffset.y = splitInfo.leftTopBounds.height() +
+ splitInfo.dividerBounds.height() / 2;
+ }
+ }
+ }
+
+ @Override
+ public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+ View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+ DeviceProfile dp) {
+ int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+ int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+ int totalThumbnailWidth = taskParent.getWidth();
+ int dividerBar = (dp.isLandscape ?
+ splitBoundsConfig.dividerBounds.width() :
+ splitBoundsConfig.dividerBounds.height())
+ / 2;
+ ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+ ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+ if (dp.isLandscape) {
+ primaryLp.height = totalThumbnailHeight;
+ primaryLp.width = (int) (totalThumbnailWidth * splitBoundsConfig.leftTaskPercent);
+
+ secondaryLp.height = totalThumbnailHeight;
+ secondaryLp.width = totalThumbnailWidth - primaryLp.width - dividerBar;
+ mSnapshotView2.setTranslationX(primaryLp.width + dividerBar);
+ mSnapshotView2.setTranslationY(spaceAboveSnapshot);
+ } else {
+ primaryLp.width = totalThumbnailWidth;
+ primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.topTaskPercent);
+
+ secondaryLp.width = totalThumbnailWidth;
+ secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+ mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+ mSnapshotView2.setTranslationX(0);
+ }
+ }
+
+//=======
+ @Override
+ public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
+ if (!deviceProfile.isTablet) {
+ throw new IllegalStateException("Default position available only for large screens");
+ }
+ if (deviceProfile.isLandscape) {
+ return STAGE_POSITION_BOTTOM_OR_RIGHT;
+ } else {
+ return STAGE_POSITION_TOP_OR_LEFT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
+ }
+ }
+
+ @Override
public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
DeviceProfile dp) {
if (dp.isLandscape) { // or seascape
diff --git a/src/com/android/launcher3/util/IntArray.java b/src/com/android/launcher3/util/IntArray.java
index e7235e7..1c78795 100644
--- a/src/com/android/launcher3/util/IntArray.java
+++ b/src/com/android/launcher3/util/IntArray.java
@@ -296,7 +296,7 @@
@Override
public void remove() {
- throw new UnsupportedOperationException();
+ removeIndex(--mNextIndex);
}
}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 1f1db9d..41693de 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -69,32 +69,44 @@
///////////////////////////////////
public static class SplitPositionOption {
- public final int mIconResId;
- public final int mTextResId;
+ public final int iconResId;
+ public final int textResId;
@StagePosition
- public final int mStagePosition;
+ public final int stagePosition;
@StageType
public final int mStageType;
public SplitPositionOption(int iconResId, int textResId, int stagePosition, int stageType) {
- mIconResId = iconResId;
- mTextResId = textResId;
- mStagePosition = stagePosition;
+ this.iconResId = iconResId;
+ this.textResId = textResId;
+ this.stagePosition = stagePosition;
mStageType = stageType;
}
}
public static class StagedSplitBounds {
- public final Rect mLeftTopBounds;
- public final Rect mRightBottomBounds;
- public final Rect mDividerBounds;
+ public final Rect leftTopBounds;
+ public final Rect rightBottomBounds;
+ public final Rect dividerBounds;
+ // This class is orientation-agnostic, so we compute both for later use
+ public final float topTaskPercent;
+ public final float leftTaskPercent;
public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, Rect dividerBounds) {
- mLeftTopBounds = leftTopBounds;
- mRightBottomBounds = rightBottomBounds;
- mDividerBounds = dividerBounds;
+ this.leftTopBounds = leftTopBounds;
+ this.rightBottomBounds = rightBottomBounds;
+ this.dividerBounds = dividerBounds;
+ float totalHeight = this.leftTopBounds.height()
+ + this.rightBottomBounds.height()
+ + this.dividerBounds.height();
+ float totalWidth = this.leftTopBounds.width()
+ + this.rightBottomBounds.width()
+ + this.dividerBounds.width();
+
+ leftTaskPercent = this.leftTopBounds.width() / totalWidth;
+ topTaskPercent = this.leftTopBounds.height() / totalHeight;
}
}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index b95904e..c822213 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -27,6 +27,7 @@
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ViewCache;
@@ -109,6 +110,10 @@
return null;
}
+ default StatsLogManager getStatsLogManager() {
+ return StatsLogManager.newInstance((Context) this);
+ }
+
/**
* Returns the ActivityContext associated with the given Context.
*/
diff --git a/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java b/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
deleted file mode 100644
index afceadd..0000000
--- a/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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.widget;
-
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.util.Size;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import androidx.collection.ArrayMap;
-import androidx.collection.ArraySet;
-
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.util.ComponentKey;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/** Wrapper around {@link DatabaseWidgetPreviewLoader} that contains caching logic. */
-public class CachingWidgetPreviewLoader implements WidgetPreviewLoader {
-
- @NonNull private final WidgetPreviewLoader mDelegate;
- @NonNull private final Map<ComponentKey, Map<Size, CacheResult>> mCache = new ArrayMap<>();
-
- public CachingWidgetPreviewLoader(@NonNull WidgetPreviewLoader delegate) {
- mDelegate = delegate;
- }
-
- /** Returns whether the preview is loaded for the item and size. */
- public boolean isPreviewLoaded(@NonNull WidgetItem item, @NonNull Size previewSize) {
- return getPreview(item, previewSize) != null;
- }
-
- /** Returns the cached preview for the item and size, or null if there is none. */
- @Nullable
- public Bitmap getPreview(@NonNull WidgetItem item, @NonNull Size previewSize) {
- CacheResult cacheResult = getCacheResult(item, previewSize);
- if (cacheResult instanceof CacheResult.Loaded) {
- return ((CacheResult.Loaded) cacheResult).mBitmap;
- } else {
- return null;
- }
- }
-
- @NonNull
- private CacheResult getCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
- synchronized (mCache) {
- Map<Size, CacheResult> cacheResults = mCache.get(toComponentKey(item));
- if (cacheResults == null) {
- return CacheResult.MISS;
- }
-
- return cacheResults.getOrDefault(previewSize, CacheResult.MISS);
- }
- }
-
- /**
- * Puts the result in the cache for the item and size. Returns the value previously in the
- * cache, or null if there was none.
- */
- @Nullable
- private CacheResult putCacheResult(
- @NonNull WidgetItem item,
- @NonNull Size previewSize,
- @Nullable CacheResult cacheResult) {
- ComponentKey key = toComponentKey(item);
- synchronized (mCache) {
- Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
- CacheResult previous;
- if (cacheResult == null) {
- previous = cacheResults.remove(previewSize);
- if (cacheResults.isEmpty()) {
- mCache.remove(key);
- } else {
- previous = cacheResults.put(previewSize, cacheResult);
- mCache.put(key, cacheResults);
- }
- } else {
- previous = cacheResults.put(previewSize, cacheResult);
- mCache.put(key, cacheResults);
- }
- return previous;
- }
- }
-
- private void removeCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
- ComponentKey key = toComponentKey(item);
- synchronized (mCache) {
- Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
- cacheResults.remove(previewSize);
- mCache.put(key, cacheResults);
- }
- }
-
- /**
- * Gets the preview for the widget item and size, using the value in the cache if stored.
- *
- * @return a {@link CancellationSignal}, which can cancel the request before it loads
- */
- @Override
- @UiThread
- @NonNull
- public CancellationSignal loadPreview(
- @NonNull BaseActivity activity, @NonNull WidgetItem item, @NonNull Size previewSize,
- @NonNull WidgetPreviewLoadedCallback callback) {
- CancellationSignal signal = new CancellationSignal();
- signal.setOnCancelListener(() -> {
- synchronized (mCache) {
- CacheResult cacheResult = getCacheResult(item, previewSize);
- if (!(cacheResult instanceof CacheResult.Loading)) {
- // If the key isn't actively loading, then this is a no-op. Cancelling loading
- // shouldn't clear the cache if we've already loaded.
- return;
- }
-
- CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
- CacheResult.Loading updated = prev.withoutCallback(callback);
-
- if (updated.mCallbacks.isEmpty()) {
- // If the last callback was removed, then cancel the underlying request in the
- // delegate.
- prev.mCancellationSignal.cancel();
- removeCacheResult(item, previewSize);
- } else {
- // If there are other callbacks still active, then don't cancel the delegate's
- // request, just remove this callback from the set.
- putCacheResult(item, previewSize, updated);
- }
- }
- });
-
- synchronized (mCache) {
- CacheResult cacheResult = getCacheResult(item, previewSize);
- if (cacheResult instanceof CacheResult.Loaded) {
- // If the bitmap is already present in the cache, invoke the callback immediately.
- callback.onPreviewLoaded(((CacheResult.Loaded) cacheResult).mBitmap);
- return signal;
- }
-
- if (cacheResult instanceof CacheResult.Loading) {
- // If we're already loading the preview for this key, then just add the callback
- // to the set we'll call after it loads.
- CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
- putCacheResult(item, previewSize, prev.withCallback(callback));
- return signal;
- }
-
- CancellationSignal delegateCancellationSignal =
- mDelegate.loadPreview(
- activity,
- item,
- previewSize,
- preview -> {
- CacheResult prev;
- synchronized (mCache) {
- prev = putCacheResult(
- item, previewSize, new CacheResult.Loaded(preview));
- }
- if (prev instanceof CacheResult.Loading) {
- // Notify each stored callback that the preview has loaded.
- ((CacheResult.Loading) prev).mCallbacks
- .forEach(c -> c.onPreviewLoaded(preview));
- } else {
- // If there isn't a loading object in the cache, then we were
- // notified before adding this signal to the cache. Just
- // call back to the provided callback, there can't be others.
- callback.onPreviewLoaded(preview);
- }
- });
- ArraySet<WidgetPreviewLoadedCallback> callbacks = new ArraySet<>();
- callbacks.add(callback);
- putCacheResult(
- item,
- previewSize,
- new CacheResult.Loading(delegateCancellationSignal, callbacks));
- }
-
- return signal;
- }
-
- /** Clears all cached previews for {@code items}, cancelling any in-progress preview loading. */
- public void clearPreviews(Iterable<WidgetItem> items) {
- List<CacheResult> previousCacheResults = new ArrayList<>();
- synchronized (mCache) {
- for (WidgetItem item : items) {
- Map<Size, CacheResult> previousMap = mCache.remove(toComponentKey(item));
- if (previousMap != null) {
- previousCacheResults.addAll(previousMap.values());
- }
- }
- }
-
- for (CacheResult previousCacheResult : previousCacheResults) {
- if (previousCacheResult instanceof CacheResult.Loading) {
- ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
- }
- }
- }
-
- /** Clears all cached previews, cancelling any in-progress preview loading. */
- public void clearAll() {
- List<CacheResult> previousCacheResults;
- synchronized (mCache) {
- previousCacheResults =
- mCache
- .values()
- .stream()
- .flatMap(sizeToResult -> sizeToResult.values().stream())
- .collect(Collectors.toList());
- mCache.clear();
- }
-
- for (CacheResult previousCacheResult : previousCacheResults) {
- if (previousCacheResult instanceof CacheResult.Loading) {
- ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
- }
- }
- }
-
- private abstract static class CacheResult {
- static final CacheResult MISS = new CacheResult() {};
-
- static final class Loading extends CacheResult {
- @NonNull final CancellationSignal mCancellationSignal;
- @NonNull final Set<WidgetPreviewLoadedCallback> mCallbacks;
-
- Loading(@NonNull CancellationSignal cancellationSignal,
- @NonNull Set<WidgetPreviewLoadedCallback> callbacks) {
- mCancellationSignal = cancellationSignal;
- mCallbacks = callbacks;
- }
-
- @NonNull
- Loading withCallback(@NonNull WidgetPreviewLoadedCallback callback) {
- if (mCallbacks.contains(callback)) return this;
- Set<WidgetPreviewLoadedCallback> newCallbacks =
- new ArraySet<>(mCallbacks.size() + 1);
- newCallbacks.addAll(mCallbacks);
- newCallbacks.add(callback);
- return new Loading(mCancellationSignal, newCallbacks);
- }
-
- @NonNull
- Loading withoutCallback(@NonNull WidgetPreviewLoadedCallback callback) {
- if (!mCallbacks.contains(callback)) return this;
- Set<WidgetPreviewLoadedCallback> newCallbacks =
- new ArraySet<>(mCallbacks.size() - 1);
- for (WidgetPreviewLoadedCallback existingCallback : mCallbacks) {
- if (!existingCallback.equals(callback)) {
- newCallbacks.add(existingCallback);
- }
- }
- return new Loading(mCancellationSignal, newCallbacks);
- }
- }
-
- static final class Loaded extends CacheResult {
- @NonNull final Bitmap mBitmap;
-
- Loaded(@NonNull Bitmap bitmap) {
- mBitmap = bitmap;
- }
- }
- }
-
- @NonNull
- private static ComponentKey toComponentKey(@NonNull WidgetItem item) {
- return new ComponentKey(item.componentName, item.user);
- }
-}
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index 4ec7e60..aacb9c5 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -16,21 +16,10 @@
package com.android.launcher3.widget;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import android.content.ComponentName;
-import android.content.ContentValues;
import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -39,72 +28,40 @@
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.CancellationSignal;
+import android.os.Handler;
import android.os.Process;
-import android.os.UserHandle;
import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.GraphicsUtils;
-import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator;
+import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SQLiteCacheHelper;
-import com.android.launcher3.util.Thunk;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.util.WidgetSizes;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.WeakHashMap;
import java.util.concurrent.ExecutionException;
+import java.util.function.Consumer;
-/** {@link WidgetPreviewLoader} that loads preview images from a {@link CacheDb}. */
-public class DatabaseWidgetPreviewLoader implements WidgetPreviewLoader {
+/** Utility class to load widget previews */
+public class DatabaseWidgetPreviewLoader {
private static final String TAG = "WidgetPreviewLoader";
- private static final boolean DEBUG = false;
-
- private final HashMap<String, long[]> mPackageVersions = new HashMap<>();
-
- /**
- * Weak reference objects, do not prevent their referents from being made finalizable,
- * finalized, and then reclaimed.
- * Note: synchronized block used for this variable is expensive and the block should always
- * be posted to a background thread.
- */
- @Thunk final Set<Bitmap> mUnusedBitmaps = Collections.newSetFromMap(new WeakHashMap<>());
private final Context mContext;
- private final IconCache mIconCache;
- private final UserCache mUserCache;
- private final CacheDb mDb;
private final float mPreviewBoxCornerRadius;
- public DatabaseWidgetPreviewLoader(Context context, IconCache iconCache) {
+ public DatabaseWidgetPreviewLoader(Context context) {
mContext = context;
- mIconCache = iconCache;
- mUserCache = UserCache.INSTANCE.get(context);
- mDb = new CacheDb(context);
float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
mPreviewBoxCornerRadius = previewCornerRadius > 0
? previewCornerRadius
@@ -117,251 +74,29 @@
*
* @return a request id which can be used to cancel the request.
*/
- @Override
@NonNull
- public CancellationSignal loadPreview(
- @NonNull BaseActivity activity,
+ public HandlerRunnable loadPreview(
@NonNull WidgetItem item,
@NonNull Size previewSize,
- @NonNull WidgetPreviewLoadedCallback callback) {
- int previewWidth = previewSize.getWidth();
- int previewHeight = previewSize.getHeight();
- String size = previewWidth + "x" + previewHeight;
- WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size);
-
- PreviewLoadTask task =
- new PreviewLoadTask(activity, key, item, previewWidth, previewHeight, callback);
- task.executeOnExecutor(Executors.THREAD_POOL_EXECUTOR);
-
- CancellationSignal signal = new CancellationSignal();
- signal.setOnCancelListener(task);
- return signal;
- }
-
- /** Clears the database storing previews. */
- public void refresh() {
- mDb.clear();
- }
-
- /**
- * The DB holds the generated previews for various components. Previews can also have different
- * sizes (landscape vs portrait).
- */
- private static class CacheDb extends SQLiteCacheHelper {
- private static final int DB_VERSION = 9;
-
- private static final String TABLE_NAME = "shortcut_and_widget_previews";
- private static final String COLUMN_COMPONENT = "componentName";
- private static final String COLUMN_USER = "profileId";
- private static final String COLUMN_SIZE = "size";
- private static final String COLUMN_PACKAGE = "packageName";
- private static final String COLUMN_LAST_UPDATED = "lastUpdated";
- private static final String COLUMN_VERSION = "version";
- private static final String COLUMN_PREVIEW_BITMAP = "preview_bitmap";
-
- CacheDb(Context context) {
- super(context, LauncherFiles.WIDGET_PREVIEWS_DB, DB_VERSION, TABLE_NAME);
- }
-
- @Override
- public void onCreateTable(SQLiteDatabase database) {
- database.execSQL("CREATE TABLE IF NOT EXISTS "
- + TABLE_NAME
- + " ("
- + COLUMN_COMPONENT
- + " TEXT NOT NULL, "
- + COLUMN_USER
- + " INTEGER NOT NULL, "
- + COLUMN_SIZE
- + " TEXT NOT NULL, "
- + COLUMN_PACKAGE
- + " TEXT NOT NULL, "
- + COLUMN_LAST_UPDATED
- + " INTEGER NOT NULL DEFAULT 0, "
- + COLUMN_VERSION
- + " INTEGER NOT NULL DEFAULT 0, "
- + COLUMN_PREVIEW_BITMAP
- + " BLOB, "
- + "PRIMARY KEY ("
- + COLUMN_COMPONENT
- + ", "
- + COLUMN_USER
- + ", "
- + COLUMN_SIZE
- + ") "
- +
- ");");
- }
- }
-
- @Thunk void writeToDb(WidgetCacheKey key, long[] versions, Bitmap preview) {
- ContentValues values = new ContentValues();
- values.put(CacheDb.COLUMN_COMPONENT, key.componentName.flattenToShortString());
- values.put(CacheDb.COLUMN_USER, mUserCache.getSerialNumberForUser(key.user));
- values.put(CacheDb.COLUMN_SIZE, key.mSize);
- values.put(CacheDb.COLUMN_PACKAGE, key.componentName.getPackageName());
- values.put(CacheDb.COLUMN_VERSION, versions[0]);
- values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]);
- values.put(CacheDb.COLUMN_PREVIEW_BITMAP, GraphicsUtils.flattenBitmap(preview));
- mDb.insertOrReplace(values);
- }
-
- /** Removes the package from the preview database. */
- public void removePackage(String packageName, UserHandle user) {
- removePackage(packageName, user, mUserCache.getSerialNumberForUser(user));
- }
-
- /** Removes the package from the preview database. */
- public void removePackage(String packageName, UserHandle user, long userSerial) {
- synchronized (mPackageVersions) {
- mPackageVersions.remove(packageName);
- }
-
- mDb.delete(
- CacheDb.COLUMN_PACKAGE + " = ? AND " + CacheDb.COLUMN_USER + " = ?",
- new String[]{packageName, Long.toString(userSerial)});
- }
-
- /**
- * Updates the persistent DB:
- * 1. Any preview generated for an old package version is removed
- * 2. Any preview for an absent package is removed
- * This ensures that we remove entries for packages which changed while the launcher was dead.
- *
- * @param packageUser if provided, specifies that list only contains previews for the
- * given package/user, otherwise the list contains all previews
- */
- public void removeObsoletePreviews(ArrayList<? extends ComponentKey> list,
- @Nullable PackageUserKey packageUser) {
- Preconditions.assertWorkerThread();
-
- LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
-
- for (ComponentKey key : list) {
- final long userId = mUserCache.getSerialNumberForUser(key.user);
- HashSet<String> packages = validPackages.get(userId);
- if (packages == null) {
- packages = new HashSet<>();
- validPackages.put(userId, packages);
- }
- packages.add(key.componentName.getPackageName());
- }
-
- LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
- long passedUserId = packageUser == null ? 0
- : mUserCache.getSerialNumberForUser(packageUser.mUser);
- Cursor c = null;
- try {
- c = mDb.query(
- new String[]{CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE,
- CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION},
- null, null);
- while (c.moveToNext()) {
- long userId = c.getLong(0);
- String pkg = c.getString(1);
- long lastUpdated = c.getLong(2);
- long version = c.getLong(3);
-
- if (packageUser != null && (!pkg.equals(packageUser.mPackageName)
- || userId != passedUserId)) {
- // This preview is associated with a different package/user, no need to remove.
- continue;
- }
-
- HashSet<String> packages = validPackages.get(userId);
- if (packages != null && packages.contains(pkg)) {
- long[] versions = getPackageVersion(pkg);
- if (versions[0] == version && versions[1] == lastUpdated) {
- // Every thing checks out
- continue;
- }
- }
-
- // We need to delete this package.
- packages = packagesToDelete.get(userId);
- if (packages == null) {
- packages = new HashSet<>();
- packagesToDelete.put(userId, packages);
- }
- packages.add(pkg);
- }
-
- for (int i = 0; i < packagesToDelete.size(); i++) {
- long userId = packagesToDelete.keyAt(i);
- UserHandle user = mUserCache.getUserForSerialNumber(userId);
- for (String pkg : packagesToDelete.valueAt(i)) {
- removePackage(pkg, user, userId);
- }
- }
- } catch (SQLException e) {
- Log.e(TAG, "Error updating widget previews", e);
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
- /**
- * Reads the preview bitmap from the DB or null if the preview is not in the DB.
- */
- @Thunk Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
- Cursor cursor = null;
- try {
- cursor = mDb.query(
- new String[]{CacheDb.COLUMN_PREVIEW_BITMAP},
- CacheDb.COLUMN_COMPONENT + " = ? AND " + CacheDb.COLUMN_USER + " = ? AND "
- + CacheDb.COLUMN_SIZE + " = ?",
- new String[]{
- key.componentName.flattenToShortString(),
- Long.toString(mUserCache.getSerialNumberForUser(key.user)),
- key.mSize
- });
- // If cancelled, skip getting the blob and decoding it into a bitmap
- if (loadTask.isCancelled()) {
- return null;
- }
- if (cursor.moveToNext()) {
- byte[] blob = cursor.getBlob(0);
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inBitmap = recycle;
- try {
- if (!loadTask.isCancelled()) {
- return BitmapFactory.decodeByteArray(blob, 0, blob.length, opts);
- }
- } catch (Exception e) {
- return null;
- }
- }
- } catch (SQLException e) {
- Log.w(TAG, "Error loading preview from DB", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- return null;
+ @NonNull Consumer<Bitmap> callback) {
+ Handler handler = Executors.UI_HELPER_EXECUTOR.getHandler();
+ HandlerRunnable<Bitmap> request = new HandlerRunnable<>(handler,
+ () -> generatePreview(item, previewSize.getWidth(), previewSize.getHeight()),
+ MAIN_EXECUTOR,
+ callback);
+ Utilities.postAsyncCallback(handler, request);
+ return request;
}
/**
* Returns a generated preview for a widget and if the preview should be saved in persistent
* storage.
- * @param launcher
- * @param item
- * @param recycle
- * @param previewWidth
- * @param previewHeight
- * @return Pair<Bitmap, Boolean>
*/
- private Pair<Bitmap, Boolean> generatePreview(BaseActivity launcher, WidgetItem item,
- Bitmap recycle,
- int previewWidth, int previewHeight) {
+ private Bitmap generatePreview(WidgetItem item, int previewWidth, int previewHeight) {
if (item.widgetInfo != null) {
- return generateWidgetPreview(launcher, item.widgetInfo,
- previewWidth, recycle, null);
+ return generateWidgetPreview(item.widgetInfo, previewWidth, null);
} else {
- return new Pair<>(generateShortcutPreview(launcher, item.activityInfo,
- previewWidth, previewHeight, recycle), false);
+ return generateShortcutPreview(item.activityInfo, previewWidth, previewHeight);
}
}
@@ -369,16 +104,12 @@
* Generates the widget preview from either the {@link WidgetManagerHelper} or cache
* and add badge at the bottom right corner.
*
- * @param launcher
* @param info information about the widget
* @param maxPreviewWidth width of the preview on either workspace or tray
- * @param preview bitmap that can be recycled
* @param preScaledWidthOut return the width of the returned bitmap
- * @return Pair<Bitmap (the preview) , Boolean (should be stored in db)>
*/
- public Pair<Bitmap, Boolean> generateWidgetPreview(BaseActivity launcher,
- LauncherAppWidgetProviderInfo info,
- int maxPreviewWidth, Bitmap preview, int[] preScaledWidthOut) {
+ public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info,
+ int maxPreviewWidth, int[] preScaledWidthOut) {
// Load the preview image if possible
if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE;
@@ -409,117 +140,97 @@
int previewWidth;
int previewHeight;
- boolean savePreviewImage = widgetPreviewExists || info.previewImage == 0;
+ DeviceProfile dp = ActivityContext.lookupContext(mContext).getDeviceProfile();
if (widgetPreviewExists && drawable.getIntrinsicWidth() > 0
&& drawable.getIntrinsicHeight() > 0) {
previewWidth = drawable.getIntrinsicWidth();
previewHeight = drawable.getIntrinsicHeight();
} else {
- DeviceProfile dp = launcher.getDeviceProfile();
Size widgetSize = WidgetSizes.getWidgetPaddedSizePx(mContext, info.provider, dp, spanX,
spanY);
previewWidth = widgetSize.getWidth();
previewHeight = widgetSize.getHeight();
}
- // Scale to fit width only - let the widget preview be clipped in the
- // vertical dimension
- float scale = 1f;
if (preScaledWidthOut != null) {
preScaledWidthOut[0] = previewWidth;
}
- if (previewWidth > maxPreviewWidth) {
- scale = maxPreviewWidth / (float) (previewWidth);
- }
+ // Scale to fit width only - let the widget preview be clipped in the
+ // vertical dimension
+ final float scale = previewWidth > maxPreviewWidth
+ ? (maxPreviewWidth / (float) (previewWidth)) : 1f;
if (scale != 1f) {
previewWidth = Math.max((int) (scale * previewWidth), 1);
previewHeight = Math.max((int) (scale * previewHeight), 1);
}
- final Canvas c = new Canvas();
- if (preview == null) {
- // If no bitmap was provided, then allocate a new one with the right size.
- preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
- c.setBitmap(preview);
- } else {
- // If a bitmap was passed in, attempt to reconfigure the bitmap to the same dimensions
- // as the preview.
- try {
- preview.reconfigure(previewWidth, previewHeight, preview.getConfig());
- } catch (IllegalArgumentException e) {
- // This occurs if the preview can't be reconfigured for any reason. In this case,
- // allocate a new bitmap with the right size.
- preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
- }
+ final int previewWidthF = previewWidth;
+ final int previewHeightF = previewHeight;
+ final Drawable drawableF = drawable;
- c.setBitmap(preview);
- c.drawColor(0, PorterDuff.Mode.CLEAR);
- }
-
- // Draw the scaled preview into the final bitmap
- if (widgetPreviewExists) {
- drawable.setBounds(0, 0, previewWidth, previewHeight);
- drawable.draw(c);
- } else {
- RectF boxRect;
-
- // Draw horizontal and vertical lines to represent individual columns.
- final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- if (Utilities.ATLEAST_S) {
- boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
- previewWidth, /* bottom= */ previewHeight);
-
- p.setStyle(Paint.Style.FILL);
- p.setColor(Color.WHITE);
- float roundedCorner = mContext.getResources().getDimension(
- android.R.dimen.system_app_widget_background_radius);
- c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
+ return BitmapRenderer.createHardwareBitmap(previewWidth, previewHeight, c -> {
+ // Draw the scaled preview into the final bitmap
+ if (widgetPreviewExists) {
+ drawableF.setBounds(0, 0, previewWidthF, previewHeightF);
+ drawableF.draw(c);
} else {
- boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
- }
+ RectF boxRect;
- p.setStyle(Paint.Style.STROKE);
- p.setStrokeWidth(mContext.getResources()
- .getDimension(R.dimen.widget_preview_cell_divider_width));
- p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+ // Draw horizontal and vertical lines to represent individual columns.
+ final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
- float t = boxRect.left;
- float tileSize = boxRect.width() / spanX;
- for (int i = 1; i < spanX; i++) {
- t += tileSize;
- c.drawLine(t, 0, t, previewHeight, p);
- }
+ if (Utilities.ATLEAST_S) {
+ boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
+ previewWidthF, /* bottom= */ previewHeightF);
- t = boxRect.top;
- tileSize = boxRect.height() / spanY;
- for (int i = 1; i < spanY; i++) {
- t += tileSize;
- c.drawLine(0, t, previewWidth, t, p);
- }
-
- // Draw icon in the center.
- try {
- Drawable icon =
- mIconCache.getFullResIcon(info.provider.getPackageName(), info.icon);
- if (icon != null) {
- int appIconSize = launcher.getDeviceProfile().iconSizePx;
- int iconSize = (int) Math.min(appIconSize * scale,
- Math.min(boxRect.width(), boxRect.height()));
-
- icon = mutateOnMainThread(icon);
- int hoffset = (previewWidth - iconSize) / 2;
- int yoffset = (previewHeight - iconSize) / 2;
- icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
- icon.draw(c);
+ p.setStyle(Paint.Style.FILL);
+ p.setColor(Color.WHITE);
+ float roundedCorner = mContext.getResources().getDimension(
+ android.R.dimen.system_app_widget_background_radius);
+ c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
+ } else {
+ boxRect = drawBoxWithShadow(c, previewWidthF, previewHeightF);
}
- } catch (Resources.NotFoundException e) {
- savePreviewImage = false;
+
+ p.setStyle(Paint.Style.STROKE);
+ p.setStrokeWidth(mContext.getResources()
+ .getDimension(R.dimen.widget_preview_cell_divider_width));
+ p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+
+ float t = boxRect.left;
+ float tileSize = boxRect.width() / spanX;
+ for (int i = 1; i < spanX; i++) {
+ t += tileSize;
+ c.drawLine(t, 0, t, previewHeightF, p);
+ }
+
+ t = boxRect.top;
+ tileSize = boxRect.height() / spanY;
+ for (int i = 1; i < spanY; i++) {
+ t += tileSize;
+ c.drawLine(0, t, previewWidthF, t, p);
+ }
+
+ // Draw icon in the center.
+ try {
+ Drawable icon = LauncherAppState.getInstance(mContext).getIconCache()
+ .getFullResIcon(info.provider.getPackageName(), info.icon);
+ if (icon != null) {
+ int appIconSize = dp.iconSizePx;
+ int iconSize = (int) Math.min(appIconSize * scale,
+ Math.min(boxRect.width(), boxRect.height()));
+
+ icon = mutateOnMainThread(icon);
+ int hoffset = (previewWidthF - iconSize) / 2;
+ int yoffset = (previewHeightF - iconSize) / 2;
+ icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
+ icon.draw(c);
+ }
+ } catch (Resources.NotFoundException e) {
+ }
}
- c.setBitmap(null);
- }
- return new Pair<>(preview, savePreviewImage);
+ });
}
private RectF drawBoxWithShadow(Canvas c, int width, int height) {
@@ -537,42 +248,29 @@
return builder.bounds;
}
- private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
- int maxWidth, int maxHeight, Bitmap preview) {
- int iconSize = launcher.getDeviceProfile().allAppsIconSizePx;
- int padding = launcher.getResources()
+ private Bitmap generateShortcutPreview(
+ ShortcutConfigActivityInfo info, int maxWidth, int maxHeight) {
+ int iconSize = ActivityContext.lookupContext(mContext).getDeviceProfile().allAppsIconSizePx;
+ int padding = mContext.getResources()
.getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
int size = iconSize + 2 * padding;
if (maxHeight < size || maxWidth < size) {
throw new RuntimeException("Max size is too small for preview");
}
- final Canvas c = new Canvas();
- if (preview == null || preview.getWidth() < size || preview.getHeight() < size) {
- preview = Bitmap.createBitmap(size, size, Config.ARGB_8888);
- c.setBitmap(preview);
- } else {
- if (preview.getWidth() > size || preview.getHeight() > size) {
- preview.reconfigure(size, size, preview.getConfig());
- }
+ return BitmapRenderer.createHardwareBitmap(size, size, c -> {
+ drawBoxWithShadow(c, size, size);
- // Reusing bitmap. Clear it.
- c.setBitmap(preview);
- c.drawColor(0, PorterDuff.Mode.CLEAR);
- }
+ LauncherIcons li = LauncherIcons.obtain(mContext);
+ Drawable icon = li.createBadgedIconBitmap(
+ mutateOnMainThread(info.getFullResIcon(
+ LauncherAppState.getInstance(mContext).getIconCache())),
+ Process.myUserHandle(), 0).newIcon(mContext);
+ li.recycle();
- drawBoxWithShadow(c, size, size);
-
- LauncherIcons li = LauncherIcons.obtain(mContext);
- Drawable icon = li.createBadgedIconBitmap(
- mutateOnMainThread(info.getFullResIcon(mIconCache)),
- Process.myUserHandle(), 0).newIcon(launcher);
- li.recycle();
-
- icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
- icon.draw(c);
- c.setBitmap(null);
- return preview;
+ icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
+ icon.draw(c);
+ });
}
private Drawable mutateOnMainThread(final Drawable drawable) {
@@ -585,206 +283,4 @@
throw new RuntimeException(e);
}
}
-
- /**
- * @return an array of containing versionCode and lastUpdatedTime for the package.
- */
- @Thunk long[] getPackageVersion(String packageName) {
- synchronized (mPackageVersions) {
- long[] versions = mPackageVersions.get(packageName);
- if (versions == null) {
- versions = new long[2];
- try {
- PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
- versions[0] = info.versionCode;
- versions[1] = info.lastUpdateTime;
- } catch (NameNotFoundException e) {
- Log.e(TAG, "PackageInfo not found", e);
- }
- mPackageVersions.put(packageName, versions);
- }
- return versions;
- }
- }
-
- private class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap>
- implements CancellationSignal.OnCancelListener {
- @Thunk final WidgetCacheKey mKey;
- private final WidgetItem mInfo;
- private final int mPreviewHeight;
- private final int mPreviewWidth;
- private final WidgetPreviewLoadedCallback mCallback;
- private final BaseActivity mActivity;
- @Thunk long[] mVersions;
- @Thunk Bitmap mBitmapToRecycle;
-
- @Nullable private Bitmap mUnusedPreviewBitmap;
- private boolean mSaveToDB = false;
-
- PreviewLoadTask(BaseActivity activity, WidgetCacheKey key, WidgetItem info,
- int previewWidth, int previewHeight, WidgetPreviewLoadedCallback callback) {
- mActivity = activity;
- mKey = key;
- mInfo = info;
- mPreviewHeight = previewHeight;
- mPreviewWidth = previewWidth;
- mCallback = callback;
- if (DEBUG) {
- Log.d(TAG, String.format("%s, %s, %d, %d",
- mKey, mInfo, mPreviewHeight, mPreviewWidth));
- }
- }
-
- @Override
- protected Bitmap doInBackground(Void... params) {
- Bitmap unusedBitmap = null;
-
- // If already cancelled before this gets to run in the background, then return early
- if (isCancelled()) {
- return null;
- }
- synchronized (mUnusedBitmaps) {
- // Check if we can re-use a bitmap
- for (Bitmap candidate : mUnusedBitmaps) {
- if (candidate != null && candidate.isMutable()
- && candidate.getWidth() == mPreviewWidth
- && candidate.getHeight() == mPreviewHeight) {
- unusedBitmap = candidate;
- mUnusedBitmaps.remove(unusedBitmap);
- break;
- }
- }
- }
-
- // creating a bitmap is expensive. Do not do this inside synchronized block.
- if (unusedBitmap == null) {
- unusedBitmap = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Config.ARGB_8888);
- }
- // If cancelled now, don't bother reading the preview from the DB
- if (isCancelled()) {
- return unusedBitmap;
- }
- Bitmap preview = readFromDb(mKey, unusedBitmap, this);
- // Only consider generating the preview if we have not cancelled the task already
- if (!isCancelled() && preview == null) {
- // Fetch the version info before we generate the preview, so that, in-case the
- // app was updated while we are generating the preview, we use the old version info,
- // which would gets re-written next time.
- boolean persistable = mInfo.activityInfo == null
- || mInfo.activityInfo.isPersistable();
- mVersions = persistable ? getPackageVersion(mKey.componentName.getPackageName())
- : null;
-
- // it's not in the db... we need to generate it
- Pair<Bitmap, Boolean> pair = generatePreview(mActivity, mInfo, unusedBitmap,
- mPreviewWidth, mPreviewHeight);
- preview = pair.first;
-
- if (preview != unusedBitmap) {
- mUnusedPreviewBitmap = unusedBitmap;
- }
-
- this.mSaveToDB = pair.second;
- }
- return preview;
- }
-
- @Override
- protected void onPostExecute(final Bitmap preview) {
- mCallback.onPreviewLoaded(preview);
-
- // Write the generated preview to the DB in the worker thread
- if (mVersions != null) {
- MODEL_EXECUTOR.post(new Runnable() {
- @Override
- public void run() {
- if (mUnusedPreviewBitmap != null) {
- // If we didn't end up using the bitmap, it can be added back into the
- // recycled set.
- synchronized (mUnusedBitmaps) {
- mUnusedBitmaps.add(mUnusedPreviewBitmap);
- }
- }
-
- if (!isCancelled() && mSaveToDB) {
- // If we are still using this preview, then write it to the DB and then
- // let the normal clear mechanism recycle the bitmap
- writeToDb(mKey, mVersions, preview);
- mBitmapToRecycle = preview;
- } else {
- // If we've already cancelled, then skip writing the bitmap to the DB
- // and manually add the bitmap back to the recycled set
- synchronized (mUnusedBitmaps) {
- mUnusedBitmaps.add(preview);
- }
- }
- }
- });
- } else {
- // If we don't need to write to disk, then ensure the preview gets recycled by
- // the normal clear mechanism
- mBitmapToRecycle = preview;
- }
- }
-
- @Override
- protected void onCancelled(final Bitmap preview) {
- // If we've cancelled while the task is running, then can return the bitmap to the
- // recycled set immediately. Otherwise, it will be recycled after the preview is written
- // to disk.
- if (preview != null) {
- MODEL_EXECUTOR.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mUnusedBitmaps) {
- mUnusedBitmaps.add(preview);
- }
- }
- });
- }
- }
-
- @Override
- public void onCancel() {
- cancel(true);
-
- // This only handles the case where the PreviewLoadTask is cancelled after the task has
- // successfully completed (including having written to disk when necessary). In the
- // other cases where it is cancelled while the task is running, it will be cleaned up
- // in the tasks's onCancelled() call, and if cancelled while the task is writing to
- // disk, it will be cancelled in the task's onPostExecute() call.
- if (mBitmapToRecycle != null) {
- MODEL_EXECUTOR.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mUnusedBitmaps) {
- mUnusedBitmaps.add(mBitmapToRecycle);
- }
- mBitmapToRecycle = null;
- }
- });
- }
- }
- }
-
- private static final class WidgetCacheKey extends ComponentKey {
-
- @Thunk final String mSize;
-
- WidgetCacheKey(ComponentName componentName, UserHandle user, String size) {
- super(componentName, user);
- this.mSize = size;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() ^ mSize.hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- return super.equals(o) && ((WidgetCacheKey) o).mSize.equals(mSize);
- }
- }
}
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 991910d..2347d28 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -140,10 +140,9 @@
.addDragListener(new AppWidgetHostViewDragListener(launcher));
}
if (preview == null && mAppWidgetHostViewPreview == null) {
- Drawable p = new FastBitmapDrawable(
- app.getWidgetCache().generateWidgetPreview(launcher,
- createWidgetInfo.info, maxWidth, null,
- previewSizeBeforeScale).first);
+ Drawable p = new FastBitmapDrawable(new DatabaseWidgetPreviewLoader(launcher)
+ .generateWidgetPreview(
+ createWidgetInfo.info, maxWidth, previewSizeBeforeScale));
if (RoundedCornerEnforcement.isRoundedCornerEnabled()) {
p = new RoundDrawableWrapper(p, mEnforcedRoundedCornersForWidget);
}
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index bd444db..f1ac656 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -26,14 +26,12 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-import android.os.CancellationSignal;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -42,18 +40,22 @@
import android.widget.RemoteViews;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseActivity;
import com.android.launcher3.CheckLongPressHelper;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.RoundDrawableWrapper;
+import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.util.WidgetSizes;
+import java.util.function.Consumer;
+
/**
* Represents the individual cell of the widget inside the widget tray. The preview is drawn
* horizontally centered, and scaled down if needed.
@@ -63,7 +65,7 @@
* transition from the view to drag view, so when adding padding support, DnD would need to
* consider the appropriate scaling factor.
*/
-public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
+public class WidgetCell extends LinearLayout {
private static final String TAG = "WidgetCell";
private static final boolean DEBUG = false;
@@ -115,15 +117,12 @@
protected WidgetItem mItem;
- private WidgetPreviewLoader mWidgetPreviewLoader;
+ private final DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
- protected CancellationSignal mActiveRequest;
+ protected HandlerRunnable mActiveRequest;
private boolean mAnimatePreview = true;
- private boolean mApplyBitmapDeferred = false;
- private Drawable mDeferredDrawable;
-
- protected final BaseActivity mActivity;
+ protected final ActivityContext mActivity;
private final CheckLongPressHelper mLongPressHelper;
private final float mEnforcedCornerRadius;
@@ -143,7 +142,8 @@
public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mActivity = BaseActivity.fromContext(context);
+ mActivity = ActivityContext.lookupContext(context);
+ mWidgetPreviewLoader = new DatabaseWidgetPreviewLoader(context);
mLongPressHelper = new CheckLongPressHelper(this);
mLongPressHelper.setLongPressTimeoutFactor(1);
@@ -218,7 +218,36 @@
this.mSourceContainer = sourceContainer;
}
- public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
+ /**
+ * Applies the item to this view
+ */
+ public void applyFromCellItem(WidgetItem item) {
+ applyFromCellItem(item, 1f);
+ }
+
+ /**
+ * Applies the item to this view
+ */
+ public void applyFromCellItem(WidgetItem item, float previewScale) {
+ applyFromCellItem(item, previewScale, this::applyPreview, null);
+ }
+
+ /**
+ * Applies the item to this view
+ * @param item item to apply
+ * @param previewScale factor to scale the preview
+ * @param callback callback when preview is loaded in case the preview is being loaded or cached
+ * @param cachedPreview previously cached preview bitmap is present
+ */
+ public void applyFromCellItem(WidgetItem item, float previewScale,
+ @NonNull Consumer<Bitmap> callback, @Nullable Bitmap cachedPreview) {
+ // setPreviewSize
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, item);
+ mTargetPreviewWidth = widgetSize.getWidth();
+ mTargetPreviewHeight = widgetSize.getHeight();
+ mPreviewContainerScale = previewScale;
+
applyPreviewOnAppWidgetHostView(item);
Context context = getContext();
@@ -240,14 +269,14 @@
}
}
- mWidgetPreviewLoader = loader;
if (item.activityInfo != null) {
setTag(new PendingAddShortcutInfo(item.activityInfo));
} else {
setTag(new PendingAddWidgetInfo(item.widgetInfo, mSourceContainer));
}
- }
+ ensurePreviewWithCallback(callback, cachedPreview);
+ }
private void applyPreviewOnAppWidgetHostView(WidgetItem item) {
if (mRemoteViewsPreview != null) {
@@ -294,37 +323,15 @@
return mAppWidgetHostViewPreview;
}
- /**
- * Sets if applying bitmap preview should be deferred. The UI will still load the bitmap, but
- * will not cause invalidate, so that when deferring is disabled later, all the bitmaps are
- * ready.
- * This prevents invalidates while the animation is running.
- */
- public void setApplyBitmapDeferred(boolean isDeferred) {
- if (mApplyBitmapDeferred != isDeferred) {
- mApplyBitmapDeferred = isDeferred;
- if (!mApplyBitmapDeferred && mDeferredDrawable != null) {
- applyPreview(mDeferredDrawable);
- mDeferredDrawable = null;
- }
- }
- }
-
public void setAnimatePreview(boolean shouldAnimate) {
mAnimatePreview = shouldAnimate;
}
- public void applyPreview(Bitmap bitmap) {
- FastBitmapDrawable drawable = new FastBitmapDrawable(bitmap);
- applyPreview(new RoundDrawableWrapper(drawable, mEnforcedCornerRadius));
- }
+ private void applyPreview(Bitmap bitmap) {
+ if (bitmap != null) {
+ Drawable drawable = new RoundDrawableWrapper(
+ new FastBitmapDrawable(bitmap), mEnforcedCornerRadius);
- private void applyPreview(Drawable drawable) {
- if (mApplyBitmapDeferred) {
- mDeferredDrawable = drawable;
- return;
- }
- if (drawable != null) {
// Scale down the preview size if it's wider than the cell.
float scale = 1f;
if (mTargetPreviewWidth > 0) {
@@ -349,6 +356,10 @@
} else {
mWidgetImageContainer.setAlpha(1f);
}
+ if (mActiveRequest != null) {
+ mActiveRequest.cancel();
+ mActiveRequest = null;
+ }
}
private void setContainerSize(int width, int height) {
@@ -358,7 +369,13 @@
mWidgetImageContainer.setLayoutParams(layoutParams);
}
- public void ensurePreview() {
+ /**
+ * Ensures that the preview is already loaded or being loaded. If the preview is not loaded,
+ * it applies the provided cachedPreview. If that is null, it starts a loader and notifies the
+ * callback on successful load.
+ */
+ private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
+ @Nullable Bitmap cachedPreview) {
if (mAppWidgetHostViewPreview != null) {
int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
@@ -382,38 +399,18 @@
mAppWidgetHostViewPreview.setLayoutParams(params);
mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
mWidgetImage.setVisibility(View.GONE);
- applyPreview((Drawable) null);
+ applyPreview(null);
+ return;
+ }
+ if (cachedPreview != null) {
+ applyPreview(cachedPreview);
return;
}
if (mActiveRequest != null) {
return;
}
mActiveRequest = mWidgetPreviewLoader.loadPreview(
- BaseActivity.fromContext(getContext()), mItem,
- new Size(mTargetPreviewWidth, mTargetPreviewHeight),
- this::applyPreview);
- }
-
- /** Sets the widget preview image size in number of cells. */
- public Size setPreviewSize(WidgetItem widgetItem) {
- return setPreviewSize(widgetItem, 1f);
- }
-
- /** Sets the widget preview image size, in number of cells, and preview scale. */
- public Size setPreviewSize(WidgetItem widgetItem, float previewScale) {
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, widgetItem);
- mTargetPreviewWidth = widgetSize.getWidth();
- mTargetPreviewHeight = widgetSize.getHeight();
- mPreviewContainerScale = previewScale;
- return widgetSize;
- }
-
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
- int oldTop, int oldRight, int oldBottom) {
- removeOnLayoutChangeListener(this);
- ensurePreview();
+ mItem, new Size(mTargetPreviewWidth, mTargetPreviewHeight), callback);
}
@Override
@@ -429,17 +426,6 @@
mLongPressHelper.cancelLongPress();
}
- /**
- * Helper method to get the string info of the tag.
- */
- private String getTagToString() {
- if (getTag() instanceof PendingAddWidgetInfo ||
- getTag() instanceof PendingAddShortcutInfo) {
- return getTag().toString();
- }
- return "";
- }
-
private static NavigableAppWidgetHostView createAppWidgetHostView(Context context) {
return new NavigableAppWidgetHostView(context) {
@Override
@@ -450,12 +436,7 @@
}
private static boolean isLauncherContext(Context context) {
- try {
- Launcher.getLauncher(context);
- return true;
- } catch (Exception e) {
- return false;
- }
+ return ActivityContext.lookupContext(context) instanceof Launcher;
}
@Override
diff --git a/src/com/android/launcher3/widget/WidgetPreviewLoader.java b/src/com/android/launcher3/widget/WidgetPreviewLoader.java
deleted file mode 100644
index ff5c82f..0000000
--- a/src/com/android/launcher3/widget/WidgetPreviewLoader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.widget;
-
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.util.Size;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.model.WidgetItem;
-
-/** Asynchronous loader of preview bitmaps for {@link WidgetItem}s. */
-public interface WidgetPreviewLoader {
- /**
- * Loads a widget preview and calls back to {@code callback} when complete.
- *
- * @return a {@link CancellationSignal} which can be used to cancel the request.
- */
- @NonNull
- @UiThread
- CancellationSignal loadPreview(
- @NonNull BaseActivity activity,
- @NonNull WidgetItem item,
- @NonNull Size previewSize,
- @NonNull WidgetPreviewLoadedCallback callback);
-
- /** Callback class for requests to {@link WidgetPreviewLoader}. */
- interface WidgetPreviewLoadedCallback {
- void onPreviewLoaded(@NonNull Bitmap preview);
- }
-}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 6beff3a..bb4638a 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -37,7 +37,6 @@
import android.widget.TextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.model.WidgetItem;
@@ -199,11 +198,7 @@
tableRow.setGravity(Gravity.TOP);
row.forEach(widgetItem -> {
WidgetCell widget = addItemCell(tableRow);
- widget.setPreviewSize(widgetItem);
- widget.applyFromCellItem(widgetItem, LauncherAppState.getInstance(mActivityContext)
- .getWidgetCache());
- widget.ensurePreview();
- widget.setVisibility(View.VISIBLE);
+ widget.applyFromCellItem(widgetItem);
});
widgetsTable.addView(tableRow);
});
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 9dbfa87..09f0299 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -687,7 +687,7 @@
.findFirst()
.orElse(null);
if (viewHolderForTip != null) {
- return ((ViewGroup) viewHolderForTip.mTableContainer.getChildAt(0)).getChildAt(0);
+ return ((ViewGroup) viewHolderForTip.tableContainer.getChildAt(0)).getChildAt(0);
}
return null;
@@ -745,7 +745,6 @@
mWidgetsListAdapter = new WidgetsListAdapter(
context,
LayoutInflater.from(context),
- apps.getWidgetCache(),
apps.getIconCache(),
this::getEmptySpaceHeight,
/* iconClickListener= */ WidgetsFullSheet.this,
@@ -784,7 +783,6 @@
if (mAdapterType == PRIMARY || mAdapterType == WORK) {
mWidgetsRecyclerView.addOnAttachStateChangeListener(mBindScrollbarInSearchMode);
}
- mWidgetsListAdapter.setApplyBitmapDeferred(false, mWidgetsRecyclerView);
mWidgetsListAdapter.setMaxHorizontalSpansPerRow(mMaxSpansPerRow);
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 1ad1f7a..d52134c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -24,14 +24,12 @@
import android.graphics.Rect;
import android.os.Process;
import android.util.Log;
-import android.util.Size;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
-import android.widget.TableRow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -41,29 +39,22 @@
import androidx.recyclerview.widget.RecyclerView.LayoutParams;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.recyclerview.ViewHolderBinder;
import com.android.launcher3.util.LabelComparator;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
-import com.android.launcher3.widget.WidgetCell;
-import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetListSpaceEntry;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import com.android.launcher3.widget.util.WidgetSizes;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -95,11 +86,8 @@
private static final int VIEW_TYPE_WIDGETS_SEARCH_HEADER = R.id.view_type_widgets_search_header;
private final Context mContext;
- private final Launcher mLauncher;
- private final CachingWidgetPreviewLoader mCachingPreviewLoader;
private final WidgetsDiffReporter mDiffReporter;
private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
- private final WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder;
private final WidgetListBaseRowEntryComparator mRowComparator =
new WidgetListBaseRowEntryComparator();
@@ -115,26 +103,21 @@
@Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
@Nullable private RecyclerView mRecyclerView;
@Nullable private PackageUserKey mPendingClickHeader;
- private final int mShortcutPreviewPadding;
private final int mSpacingBetweenEntries;
private int mMaxSpanSize = 4;
- private final WidgetPreviewLoadedCallback mPreviewLoadedCallback =
- ignored -> updateVisibleEntries();
-
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
- DatabaseWidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
- IntSupplier emptySpaceHeightProvider,
+ IconCache iconCache, IntSupplier emptySpaceHeightProvider,
OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) {
mContext = context;
- mLauncher = Launcher.getLauncher(context);
- mCachingPreviewLoader = new CachingWidgetPreviewLoader(widgetPreviewLoader);
mDiffReporter = new WidgetsDiffReporter(iconCache, this);
WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context);
- mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(
- layoutInflater, iconClickListener, iconLongClickListener,
- mCachingPreviewLoader, listDrawableFactory);
- mViewHolderBinders.put(VIEW_TYPE_WIDGETS_LIST, mWidgetsListTableViewHolderBinder);
+
+ mViewHolderBinders.put(
+ VIEW_TYPE_WIDGETS_LIST,
+ new WidgetsListTableViewHolderBinder(
+ layoutInflater, iconClickListener, iconLongClickListener,
+ listDrawableFactory));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_HEADER,
new WidgetsListHeaderViewHolderBinder(
@@ -150,9 +133,6 @@
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_SPACE,
new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));
- mShortcutPreviewPadding =
- 2 * context.getResources()
- .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
mSpacingBetweenEntries =
context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
}
@@ -186,28 +166,6 @@
mFilter = filter;
}
- /**
- * Defers applying bitmap on all the {@link WidgetCell} in the {@param rv}.
- *
- * @see WidgetCell#setApplyBitmapDeferred(boolean)
- */
- public void setApplyBitmapDeferred(boolean isDeferred, RecyclerView rv) {
- mWidgetsListTableViewHolderBinder.setApplyBitmapDeferred(isDeferred);
-
- for (int i = rv.getChildCount() - 1; i >= 0; i--) {
- ViewHolder viewHolder = rv.getChildViewHolder(rv.getChildAt(i));
- if (viewHolder.getItemViewType() == VIEW_TYPE_WIDGETS_LIST) {
- WidgetsRowViewHolder holder = (WidgetsRowViewHolder) viewHolder;
- for (int j = holder.mTableContainer.getChildCount() - 1; j >= 0; j--) {
- TableRow row = (TableRow) holder.mTableContainer.getChildAt(j);
- for (int k = row.getChildCount() - 1; k >= 0; k--) {
- ((WidgetCell) row.getChildAt(k)).setApplyBitmapDeferred(isDeferred);
- }
- }
- }
- }
- }
-
@Override
public int getItemCount() {
return mVisibleEntries.size();
@@ -233,7 +191,6 @@
/** Updates the widget list based on {@code tempEntries}. */
public void setWidgets(List<WidgetsListBaseEntry> tempEntries) {
- mCachingPreviewLoader.clearAll();
mAllEntries.clear();
mAllEntries.add(new WidgetListSpaceEntry());
tempEntries.stream().sorted(mRowComparator).forEach(mAllEntries::add);
@@ -247,15 +204,10 @@
public void setWidgetsOnSearch(List<WidgetsListBaseEntry> searchResults) {
// Forget the expanded package every time widget list is refreshed in search mode.
mWidgetsContentVisiblePackageUserKey = null;
- cancelLoadingPreviews();
setWidgets(searchResults);
}
private void updateVisibleEntries() {
- // If not all previews are ready, then defer this update and try again after the preview
- // loads.
- if (!ensureAllPreviewsReady()) return;
-
// Get the current top of the header with the matching key before adjusting the visible
// entries.
OptionalInt previousPositionForPackageUserKey =
@@ -293,54 +245,6 @@
}
}
- /**
- * Checks that all preview images are loaded and starts loading for those that aren't ready.
- *
- * @return true if all previews are ready and the data can be updated, false otherwise.
- */
- private boolean ensureAllPreviewsReady() {
- boolean allReady = true;
- BaseActivity activity = BaseActivity.fromContext(mContext);
- for (WidgetsListBaseEntry entry : mAllEntries) {
- if (!(entry instanceof WidgetsListContentEntry)) continue;
-
- WidgetsListContentEntry contentEntry = (WidgetsListContentEntry) entry;
- if (!matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
- // If the entry isn't visible, clear any loaded previews.
- mCachingPreviewLoader.clearPreviews(contentEntry.mWidgets);
- continue;
- }
-
- for (int i = 0; i < entry.mWidgets.size(); i++) {
- WidgetItem widgetItem = entry.mWidgets.get(i);
- DeviceProfile deviceProfile = activity.getDeviceProfile();
- Size widgetSize = WidgetSizes.getWidgetItemSizePx(mContext, deviceProfile,
- widgetItem);
- if (widgetItem.isShortcut()) {
- widgetSize =
- new Size(
- widgetSize.getWidth() + mShortcutPreviewPadding,
- widgetSize.getHeight() + mShortcutPreviewPadding);
- }
-
- if (widgetItem.hasPreviewLayout()
- || mCachingPreviewLoader.isPreviewLoaded(widgetItem, widgetSize)) {
- // The widget is ready if it can be rendered with a preview layout or if its
- // preview bitmap is in the cache.
- continue;
- }
-
- // If we've reached this point, we should load the preview for the widget.
- allReady = false;
- mCachingPreviewLoader.loadPreview(
- activity,
- widgetItem,
- widgetSize,
- mPreviewLoadedCallback);
- }
- }
- return allReady;
- }
/** Returns whether {@code entry} matches {@code key}. */
private static boolean isHeaderForPackageUserKey(
@@ -361,13 +265,17 @@
public void resetExpandedHeader() {
if (mWidgetsContentVisiblePackageUserKey != null) {
mWidgetsContentVisiblePackageUserKey = null;
- cancelLoadingPreviews();
updateVisibleEntries();
}
}
@Override
- public void onBindViewHolder(ViewHolder holder, int pos) {
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ onBindViewHolder(holder, position, Collections.EMPTY_LIST);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int pos, List<Object> payloads) {
ViewHolderBinder viewHolderBinder = mViewHolderBinders.get(getItemViewType(pos));
WidgetsListBaseEntry entry = mVisibleEntries.get(pos);
@@ -376,7 +284,7 @@
if (pos == (getItemCount() - 1)) {
listPos |= POSITION_LAST;
}
- viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), listPos);
+ viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), listPos, payloads);
holder.itemView.setTag(R.id.tag_widget_entry, entry);
}
@@ -430,11 +338,10 @@
// Ignore invalid clicks, such as collapsing a package that isn't currently expanded.
if (!showWidgets && !packageUserKey.equals(mWidgetsContentVisiblePackageUserKey)) return;
- cancelLoadingPreviews();
-
if (showWidgets) {
mWidgetsContentVisiblePackageUserKey = packageUserKey;
- mLauncher.getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
+ ActivityContext.lookupContext(mContext)
+ .getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
} else {
mWidgetsContentVisiblePackageUserKey = null;
}
@@ -446,16 +353,6 @@
updateVisibleEntries();
}
- private void cancelLoadingPreviews() {
- mCachingPreviewLoader.clearAll();
- }
-
- /** Returns the position of the currently expanded header, or empty if it's not present. */
- public OptionalInt getSelectedHeaderPosition() {
- if (mWidgetsContentVisiblePackageUserKey == null) return OptionalInt.empty();
- return getPositionForPackageUserKey(mWidgetsContentVisiblePackageUserKey);
- }
-
/**
* Returns the position of {@code key} in {@link #mVisibleEntries}, or empty if it's not
* present.
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
index 00750bd..fadb637 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
@@ -23,6 +23,8 @@
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
+import java.util.List;
+
/**
* Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
*/
@@ -50,7 +52,7 @@
@Override
public void bindViewHolder(WidgetsListHeaderHolder viewHolder, WidgetsListHeaderEntry data,
- @ListPosition int position) {
+ @ListPosition int position, List<Object> payloads) {
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
widgetsListHeader.applyFromItemInfoWithIcon(data);
widgetsListHeader.setExpanded(data.isWidgetListShown());
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
index 1e2a3bf..bff43c1 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
@@ -24,6 +24,8 @@
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
+import java.util.List;
+
/**
* Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
*/
@@ -51,7 +53,7 @@
@Override
public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder,
- WidgetsListSearchHeaderEntry data, @ListPosition int position) {
+ WidgetsListSearchHeaderEntry data, @ListPosition int position, List<Object> payloads) {
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
widgetsListHeader.applyFromItemInfoWithIcon(data);
widgetsListHeader.setExpanded(data.isWidgetListShown());
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 804b0ae..8c9ff09 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -20,7 +20,7 @@
import android.graphics.Bitmap;
import android.util.Log;
-import android.util.Size;
+import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -33,7 +33,6 @@
import com.android.launcher3.R;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.recyclerview.ViewHolderBinder;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.util.WidgetsTableUtils;
@@ -53,31 +52,18 @@
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
- private final CachingWidgetPreviewLoader mWidgetPreviewLoader;
- private boolean mApplyBitmapDeferred = false;
public WidgetsListTableViewHolderBinder(
LayoutInflater layoutInflater,
OnClickListener iconClickListener,
OnLongClickListener iconLongClickListener,
- CachingWidgetPreviewLoader widgetPreviewLoader,
WidgetsListDrawableFactory listDrawableFactory) {
mLayoutInflater = layoutInflater;
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
- mWidgetPreviewLoader = widgetPreviewLoader;
mListDrawableFactory = listDrawableFactory;
}
- /**
- * Defers applying bitmap on all the {@link WidgetCell} at
- * {@link #bindViewHolder(WidgetsRowViewHolder, WidgetsListContentEntry, int)} if
- * {@code applyBitmapDeferred} is {@code true}.
- */
- public void setApplyBitmapDeferred(boolean applyBitmapDeferred) {
- mApplyBitmapDeferred = applyBitmapDeferred;
- }
-
@Override
public WidgetsRowViewHolder newViewHolder(ViewGroup parent) {
if (DEBUG) {
@@ -87,25 +73,30 @@
WidgetsRowViewHolder viewHolder =
new WidgetsRowViewHolder(mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false));
- viewHolder.mTableContainer.setBackgroundDrawable(
+ viewHolder.tableContainer.setBackgroundDrawable(
mListDrawableFactory.createContentBackgroundDrawable());
return viewHolder;
}
@Override
public void bindViewHolder(WidgetsRowViewHolder holder, WidgetsListContentEntry entry,
- @ListPosition int position) {
- WidgetsListTableView table = holder.mTableContainer;
+ @ListPosition int position, List<Object> payloads) {
+ for (Object payload : payloads) {
+ Pair<WidgetItem, Bitmap> pair = (Pair) payload;
+ holder.previewCache.put(pair.first, pair.second);
+ }
+
+ WidgetsListTableView table = holder.tableContainer;
if (DEBUG) {
Log.d(TAG, String.format("onBindViewHolder [widget#=%d, table.getChildCount=%d]",
entry.mWidgets.size(), table.getChildCount()));
}
table.setListDrawableState(((position & POSITION_LAST) != 0) ? LAST : MIDDLE);
-
List<ArrayList<WidgetItem>> widgetItemsTable =
WidgetsTableUtils.groupWidgetItemsIntoTable(
entry.mWidgets, entry.getMaxSpanSizeInCells());
recycleTableBeforeBinding(table, widgetItemsTable);
+
// Bind the widget items.
for (int i = 0; i < widgetItemsTable.size(); i++) {
List<WidgetItem> widgetItemsPerRow = widgetItemsTable.get(i);
@@ -115,16 +106,17 @@
WidgetCell widget = (WidgetCell) row.getChildAt(j);
widget.clear();
WidgetItem widgetItem = widgetItemsPerRow.get(j);
- Size previewSize = widget.setPreviewSize(widgetItem);
- widget.applyFromCellItem(widgetItem, mWidgetPreviewLoader);
- widget.setApplyBitmapDeferred(mApplyBitmapDeferred);
- Bitmap preview = mWidgetPreviewLoader.getPreview(widgetItem, previewSize);
- if (preview == null) {
- widget.ensurePreview();
- } else {
- widget.applyPreview(preview);
- }
widget.setVisibility(View.VISIBLE);
+
+ // When preview loads, notify adapter to rebind the item and possibly animate
+ widget.applyFromCellItem(widgetItem, 1f,
+ bitmap -> {
+ if (holder.getBindingAdapter() != null) {
+ holder.getBindingAdapter().notifyItemChanged(
+ holder.getBindingAdapterPosition(),
+ Pair.create(widgetItem, bitmap));
+ }
+ }, holder.previewCache.get(widgetItem));
}
}
}
@@ -165,6 +157,7 @@
View preview = widget.findViewById(R.id.widget_preview_container);
preview.setOnClickListener(mIconClickListener);
preview.setOnLongClickListener(mIconLongClickListener);
+ widget.setAnimatePreview(false);
tableRow.addView(widget);
}
}
@@ -173,9 +166,10 @@
@Override
public void unbindViewHolder(WidgetsRowViewHolder holder) {
- int numOfRows = holder.mTableContainer.getChildCount();
+ int numOfRows = holder.tableContainer.getChildCount();
+ holder.previewCache.clear();
for (int i = 0; i < numOfRows; i++) {
- TableRow tableRow = (TableRow) holder.mTableContainer.getChildAt(i);
+ TableRow tableRow = (TableRow) holder.tableContainer.getChildAt(i);
int numOfCols = tableRow.getChildCount();
for (int j = 0; j < numOfCols; j++) {
WidgetCell widget = (WidgetCell) tableRow.getChildAt(j);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 60dfebe..c986007 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -32,7 +32,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.widget.WidgetCell;
@@ -109,10 +108,7 @@
for (WidgetItem widgetItem : widgetItems) {
WidgetCell widgetCell = addItemCell(tableRow);
- widgetCell.setPreviewSize(widgetItem, data.mPreviewScale);
- widgetCell.applyFromCellItem(widgetItem,
- LauncherAppState.getInstance(getContext()).getWidgetCache());
- widgetCell.ensurePreview();
+ widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
}
addView(tableRow);
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
index 618e2cb..fe2d84b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
@@ -15,20 +15,26 @@
*/
package com.android.launcher3.widget.picker;
+import android.graphics.Bitmap;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.android.launcher3.R;
+import com.android.launcher3.model.WidgetItem;
+
+import java.util.HashMap;
+import java.util.Map;
/** A {@link ViewHolder} for showing widgets of an app in the full widget picker. */
public final class WidgetsRowViewHolder extends ViewHolder {
- public final WidgetsListTableView mTableContainer;
+ public final WidgetsListTableView tableContainer;
+ public final Map<WidgetItem, Bitmap> previewCache = new HashMap<>();
public WidgetsRowViewHolder(View v) {
super(v);
- mTableContainer = v.findViewById(R.id.widgets_table);
+ tableContainer = v.findViewById(R.id.widgets_table);
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
index f33c2fa..1aa5753 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
@@ -27,6 +27,7 @@
import com.android.launcher3.recyclerview.ViewHolderBinder;
import com.android.launcher3.widget.model.WidgetListSpaceEntry;
+import java.util.List;
import java.util.function.IntSupplier;
/**
@@ -47,7 +48,8 @@
}
@Override
- public void bindViewHolder(ViewHolder holder, WidgetListSpaceEntry data, int position) {
+ public void bindViewHolder(ViewHolder holder, WidgetListSpaceEntry data,
+ @ListPosition int position, List<Object> payloads) {
((EmptySpaceView) holder.itemView).setFixedHeight(mEmptySpaceHeightProvider.getAsInt());
}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 631067b..12e9e1e 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -150,7 +150,6 @@
}
}
- app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
return updatedItems;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index da55c28..aeddc4c 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -20,7 +20,78 @@
default_applicable_licenses: ["packages_apps_Launcher3_license"],
}
+// Source code used for test
filegroup {
- name: "launcher3-test-src-common",
- srcs: ["src_common/**/*.java"],
+ name: "launcher-tests-src",
+ srcs: ["src/**/*.java"],
+}
+
+// Source code used for oop test helpers
+filegroup {
+ name: "launcher-oop-tests-src",
+ srcs: [
+ "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
+ "src/com/android/launcher3/ui/ActivityLeakTracker.java",
+ "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
+ "src/com/android/launcher3/util/Wait.java",
+ "src/com/android/launcher3/util/WidgetUtils.java",
+ "src/com/android/launcher3/util/rule/FailureWatcher.java",
+ "src/com/android/launcher3/util/rule/LauncherActivityRule.java",
+ "src/com/android/launcher3/util/rule/ScreenRecordRule.java",
+ "src/com/android/launcher3/util/rule/ShellCommandRule.java",
+ "src/com/android/launcher3/util/rule/SimpleActivityRule.java",
+ "src/com/android/launcher3/util/rule/TestStabilityRule.java",
+ "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
+ "src/com/android/launcher3/testcomponent/BaseTestingActivity.java",
+ "src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java",
+ "src/com/android/launcher3/testcomponent/TestCommandReceiver.java",
+ "src/com/android/launcher3/testcomponent/TestLauncherActivity.java",
+ ],
+}
+
+// Library with all the dependencies for building quickstep
+android_library {
+ name: "Launcher3TestLib",
+ srcs: [ ],
+ resource_dirs: ["res"],
+ static_libs: [
+ "launcher-aosp-tapl",
+ "androidx.test.core",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "androidx.test.espresso.core",
+ "androidx.test.espresso.contrib",
+ "androidx.test.espresso.intents",
+ "androidx.test.uiautomator_uiautomator",
+ "mockito-target-inline-minus-junit4",
+ "launcher_log_protos_lite",
+ "truth-prebuilt"
+ ],
+ manifest: "AndroidManifest-common.xml",
+ platform_apis: true,
+}
+
+android_test {
+ name: "Launcher3Tests",
+ srcs: [
+ ":launcher-tests-src",
+ ],
+ static_libs: ["Launcher3TestLib"],
+ libs: [
+ "android.test.base",
+ "android.test.runner",
+ "android.test.mock",
+ ],
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+ use_embedded_native_libs: false,
+ compile_multilib: "both",
+ instrumentation_for: "Launcher3",
+ manifest: "AndroidManifest.xml",
+ platform_apis: true,
+ test_config: "Launcher3Tests.xml",
+ data: [":Launcher3"]
}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 6adc685..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-#
-# Build rule for Launcher3Tests
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.runner \
- androidx.test.rules \
- androidx.test.uiautomator_uiautomator \
- mockito-target-minus-junit4 \
- launcher_log_protos_lite
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_STATIC_JAVA_LIBRARIES += launcher-aosp-tapl
-
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-java-files-under, src_common)
-
-
-LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest-common.xml
-
-LOCAL_PACKAGE_NAME := Launcher3Tests
-
-LOCAL_INSTRUMENTATION_FOR := Launcher3
-
-LOCAL_TEST_CONFIG := Launcher3Tests.xml
-
-LOCAL_COMPATIBILITY_SUPPORT_FILES := $(call intermediates-dir-for,APPS,Launcher3)/package.apk:Launcher3.apk
-
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 918ec4a..8222f75 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -24,7 +24,7 @@
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
- <application android:debuggable="true">
+ <application android:debuggable="true" android:extractNativeLibs="true">
<uses-library android:name="android.test.runner"/>
<receiver
diff --git a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java b/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
similarity index 90%
rename from robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
rename to tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
index 2a94d9b..23e6235 100644
--- a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
+++ b/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.folder;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -23,6 +25,9 @@
import android.content.Intent;
import android.os.UserHandle;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.Executors;
@@ -30,15 +35,11 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
import java.util.ArrayList;
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class FolderNameProviderTest {
private Context mContext;
private WorkspaceItemInfo mItem1;
@@ -46,7 +47,7 @@
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ mContext = getApplicationContext();
mItem1 = new WorkspaceItemInfo(new AppInfo(
new ComponentName("a.b.c", "a.b.c/a.b.c.d"),
"title1",
diff --git a/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java b/tests/src/com/android/launcher3/logging/FileLogTest.java
similarity index 89%
rename from robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
rename to tests/src/com/android/launcher3/logging/FileLogTest.java
index 01b23ba..e5f8cec 100644
--- a/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
+++ b/tests/src/com/android/launcher3/logging/FileLogTest.java
@@ -1,16 +1,17 @@
package com.android.launcher3.logging;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
import java.io.File;
import java.io.PrintWriter;
@@ -20,8 +21,8 @@
/**
* Tests for {@link FileLog}
*/
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class FileLogTest {
private File mTempDir;
@@ -29,7 +30,7 @@
public void setUp() {
int count = 0;
do {
- mTempDir = new File(RuntimeEnvironment.application.getCacheDir(),
+ mTempDir = new File(getApplicationContext().getCacheDir(),
"log-test-" + (count++));
} while (!mTempDir.mkdir());
diff --git a/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
similarity index 95%
rename from robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
rename to tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 83bf7da..6764e09 100644
--- a/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -16,6 +16,8 @@
package com.android.launcher3.popup;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
@@ -27,10 +29,11 @@
import android.content.pm.ShortcutInfo;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Collections;
@@ -39,7 +42,8 @@
/**
* Tests the sorting and filtering of shortcuts in {@link PopupPopulator}.
*/
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class PopupPopulatorTest {
@Test
@@ -137,7 +141,7 @@
private ShortcutInfo createInfo(boolean isStatic, int rank) {
ShortcutInfo info = spy(new ShortcutInfo.Builder(
- RuntimeEnvironment.application, generateId(isStatic, rank))
+ getApplicationContext(), generateId(isStatic, rank))
.setRank(rank)
.build());
doReturn(isStatic).when(info).isDeclaredInManifest();
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 0d5b9ad..1a6ce8c 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -52,7 +52,6 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
-import com.android.launcher3.common.WidgetUtils;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.tapl.LauncherInstrumentation;
@@ -63,6 +62,7 @@
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.LauncherActivityRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 9c6c317..fa39ce0 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -17,7 +17,7 @@
import static androidx.test.InstrumentationRegistry.getTargetContext;
-import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
diff --git a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
new file mode 100644
index 0000000..2618a2e
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
@@ -0,0 +1,62 @@
+/*
+ * 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.content.ContextWrapper;
+import android.view.ContextThemeWrapper;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+
+/**
+ * {@link ContextWrapper} with internal Launcher interface for testing
+ */
+public class ActivityContextWrapper extends ContextThemeWrapper implements ActivityContext {
+
+ private final DeviceProfile mProfile;
+ private final MyDragLayer mMyDragLayer;
+
+ public ActivityContextWrapper(Context base) {
+ super(base, android.R.style.Theme_DeviceDefault);
+ mProfile = InvariantDeviceProfile.INSTANCE.get(base).getDeviceProfile(base).copy(base);
+ mMyDragLayer = new MyDragLayer(this);
+ }
+
+ @Override
+ public BaseDragLayer getDragLayer() {
+ return mMyDragLayer;
+ }
+
+ @Override
+ public DeviceProfile getDeviceProfile() {
+ return mProfile;
+ }
+
+ private static class MyDragLayer extends BaseDragLayer<ActivityContextWrapper> {
+
+ MyDragLayer(Context context) {
+ super(context, null, 1);
+ }
+
+ @Override
+ public void recreateControllers() {
+ mControllers = new TouchController[0];
+ }
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java b/tests/src/com/android/launcher3/util/GridOccupancyTest.java
similarity index 92%
rename from robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
rename to tests/src/com/android/launcher3/util/GridOccupancyTest.java
index 2f3fc37..b498077 100644
--- a/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
+++ b/tests/src/com/android/launcher3/util/GridOccupancyTest.java
@@ -4,14 +4,17 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
/**
* Unit tests for {@link GridOccupancy}
*/
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class GridOccupancyTest {
@Test
diff --git a/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java b/tests/src/com/android/launcher3/util/IntArrayTest.java
similarity index 86%
rename from robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
rename to tests/src/com/android/launcher3/util/IntArrayTest.java
index c08e198..a3c7007 100644
--- a/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
+++ b/tests/src/com/android/launcher3/util/IntArrayTest.java
@@ -17,14 +17,17 @@
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
/**
- * Robolectric unit tests for {@link IntArray}
+ * Unit tests for {@link IntArray}
*/
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class IntArrayTest {
@Test
diff --git a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java b/tests/src/com/android/launcher3/util/IntSetTest.java
similarity index 91%
rename from robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
rename to tests/src/com/android/launcher3/util/IntSetTest.java
index 7a8c00b..cdb2891 100644
--- a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
+++ b/tests/src/com/android/launcher3/util/IntSetTest.java
@@ -21,14 +21,17 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
/**
- * Robolectric unit tests for {@link IntSet}
+ * Unit tests for {@link IntSet}
*/
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class IntSetTest {
@Test
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
index fe6143c..8b5e197 100644
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ b/tests/src/com/android/launcher3/util/Wait.java
@@ -52,7 +52,7 @@
throw new RuntimeException(t);
}
Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis());
- launcher.checkForAnomaly();
+ launcher.checkForAnomaly(false);
Assert.fail(message.get());
}
diff --git a/tests/src_common/com/android/launcher3/common/WidgetUtils.java b/tests/src/com/android/launcher3/util/WidgetUtils.java
similarity index 82%
rename from tests/src_common/com/android/launcher3/common/WidgetUtils.java
rename to tests/src/com/android/launcher3/util/WidgetUtils.java
index 97500e3..6fc8491 100644
--- a/tests/src_common/com/android/launcher3/common/WidgetUtils.java
+++ b/tests/src/com/android/launcher3/util/WidgetUtils.java
@@ -13,19 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.common;
+package com.android.launcher3.util;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Bundle;
+import android.os.Process;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -102,4 +108,17 @@
resolver.insert(LauncherSettings.Favorites.CONTENT_URI,
writer.getValues(targetContext));
}
+
+
+ /**
+ * Creates a {@link AppWidgetProviderInfo} for the provided component name
+ */
+ public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) {
+ AppWidgetProviderInfo info = AppWidgetManager.getInstance(getApplicationContext())
+ .getInstalledProvidersForPackage(
+ getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
+ .get(0);
+ info.provider = cn;
+ return info;
+ }
}
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index 0b60ffc..fae55cc 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -30,6 +30,7 @@
public FailureWatcher(UiDevice device, LauncherInstrumentation launcher) {
mDevice = device;
mLauncher = launcher;
+ Log.d("b/196820244", "FailureWatcher.ctor", new Exception());
}
@Override
@@ -44,7 +45,9 @@
@Override
public void evaluate() throws Throwable {
try {
+ Log.d("b/196820244", "Before evaluate");
FailureWatcher.super.apply(base, description).evaluate();
+ Log.d("b/196820244", "After evaluate");
} finally {
if (mLauncher.hadNontestEvents()) {
throw new AssertionError(
@@ -64,7 +67,9 @@
}
public static void onError(UiDevice device, Description description, Throwable e) {
+ Log.d("b/196820244", "onError 1");
if (device == null) return;
+ Log.d("b/196820244", "onError 2");
final File parentFile = getInstrumentation().getTargetContext().getFilesDir();
final File sceenshot = new File(parentFile,
"TestScreenshot-" + description.getMethodName() + ".png");
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
similarity index 96%
rename from robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
rename to tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index a6f892c..24ae583 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.widget;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -25,6 +27,9 @@
import android.graphics.Point;
import android.graphics.Rect;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -32,15 +37,13 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class LauncherAppWidgetProviderInfoTest {
private static final int CELL_SIZE = 50;
@@ -51,8 +54,7 @@
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = getApplicationContext();
}
@Test
@@ -260,6 +262,7 @@
return null;
}).when(profile).getCellSize(any(Point.class));
Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
+ Mockito.when(profile.shouldInsetWidgets()).thenReturn(true);
InvariantDeviceProfile idp = new InvariantDeviceProfile();
List<DeviceProfile> supportedProfiles = new ArrayList<>(idp.supportedProfiles);
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
similarity index 95%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
index b9f183c..6232938 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
@@ -15,13 +15,16 @@
*/
package com.android.launcher3.widget.picker;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -30,6 +33,8 @@
import android.os.UserHandle;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
@@ -48,15 +53,12 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsDiffReporterTest {
private static final String TEST_PACKAGE_PREFIX = "com.android.test";
private static final WidgetListBaseRowEntryComparator COMPARATOR =
@@ -87,7 +89,7 @@
.getComponent().getPackageName())
.when(mIconCache).getTitleNoCache(any());
- mContext = RuntimeEnvironment.application;
+ mContext = getApplicationContext();
mWidgetsDiffReporter = new WidgetsDiffReporter(mIconCache, mAdapter);
mHeaderA = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "A",
/* appName= */ "A", /* numOfWidgets= */ 3);
@@ -294,14 +296,10 @@
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
WidgetItem widgetItem = new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
similarity index 91%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
index fb44ca1..44d6964 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
@@ -15,12 +15,13 @@
*/
package com.android.launcher3.widget.picker;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -31,6 +32,8 @@
import android.view.LayoutInflater;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
@@ -38,8 +41,9 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.util.ActivityContextWrapper;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
@@ -51,20 +55,20 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+/**
+ * Unit tests for WidgetsListAdapter
+ * Note that all indices matching are shifted by 1 to account for the empty space at the start.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsListAdapterTest {
private static final String TEST_PACKAGE_PLACEHOLDER = "com.google.test";
@Mock private LayoutInflater mMockLayoutInflater;
- @Mock private DatabaseWidgetPreviewLoader mMockWidgetCache;
@Mock private RecyclerView.AdapterDataObserver mListener;
@Mock private IconCache mIconCache;
@@ -76,12 +80,12 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = new ActivityContextWrapper(getApplicationContext());
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
mUserHandle = Process.myUserHandle();
- mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater, mMockWidgetCache,
+ mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater,
mIconCache, () -> 0, null, null);
mAdapter.registerAdapterDataObserver(mListener);
@@ -102,7 +106,7 @@
mAdapter.setWidgets(generateSampleMap(1));
mAdapter.setWidgets(generateSampleMap(2));
- verify(mListener).onItemRangeInserted(eq(1), eq(1));
+ verify(mListener).onItemRangeInserted(eq(2), eq(1));
}
@Test
@@ -110,7 +114,7 @@
mAdapter.setWidgets(generateSampleMap(2));
mAdapter.setWidgets(generateSampleMap(1));
- verify(mListener).onItemRangeRemoved(eq(1), eq(1));
+ verify(mListener).onItemRangeRemoved(eq(2), eq(1));
}
@Test
@@ -118,7 +122,7 @@
mAdapter.setWidgets(generateSampleMap(1));
mAdapter.setWidgets(generateSampleMap(1));
- verify(mListener).onItemRangeChanged(eq(0), eq(1), isNull());
+ verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
}
@Test
@@ -137,7 +141,7 @@
// THEN the visible entries list becomes:
// [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
// com.google.test.1 content is inserted into position 2.
- verify(mListener).onItemRangeInserted(eq(2), eq(1));
+ verify(mListener).onItemRangeInserted(eq(3), eq(1));
}
@Test
@@ -165,7 +169,7 @@
mAdapter.setWidgets(allEntries);
// THEN the onItemRangeChanged is invoked for "com.google.test1 content" at index 2.
- verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
+ verify(mListener).onItemRangeChanged(eq(3), eq(1), isNull());
}
@Test
@@ -196,15 +200,16 @@
allAppsWithWidgets.get(6), allAppsWithWidgets.get(7));
mAdapter.setWidgets(newList);
+ // Account for 1st items as empty space
// Computation logic | [Intermediate list during computation]
// THEN B <> C < 0, removed B from index 1 | [A, E]
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 1, /* itemCount= */ 1);
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
// THEN E <> C > 0, C inserted to index 1 | [A, C, E]
- verify(mListener).onItemRangeInserted(/* positionStart= */ 1, /* itemCount= */ 1);
- // THEN E <> D > 0, D inserted to index 2 | [A, C, D, E]
verify(mListener).onItemRangeInserted(/* positionStart= */ 2, /* itemCount= */ 1);
+ // THEN E <> D > 0, D inserted to index 2 | [A, C, D, E]
+ verify(mListener).onItemRangeInserted(/* positionStart= */ 3, /* itemCount= */ 1);
// THEN E <> null = -1, E deleted from index 3 | [A, C, D]
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 4, /* itemCount= */ 1);
}
@Test
@@ -227,8 +232,8 @@
// THEN expanded app is reset and the visible entries list becomes:
// [com.google.test0, com.google.test1, com.google.test2]
- verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
+ verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
}
/**
@@ -265,14 +270,10 @@
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
similarity index 76%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index b7d7788..969c12a 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -15,13 +15,16 @@
*/
package com.android.launcher3.widget.picker;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -31,7 +34,9 @@
import android.widget.FrameLayout;
import android.widget.TextView;
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -39,28 +44,23 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.util.ActivityContextWrapper;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsListHeaderViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -68,55 +68,41 @@
private Context mContext;
private WidgetsListHeaderViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
- // Replace ActivityController with ActivityScenario, which is the recommended way for activity
- // testing.
- private ActivityController<TestActivity> mActivityController;
- private TestActivity mTestActivity;
@Mock
private IconCache mIconCache;
@Mock
- private DeviceProfile mDeviceProfile;
- @Mock
private OnHeaderClickListener mOnHeaderClickListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+
+ mContext = new ActivityContextWrapper(getApplicationContext());
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
- mActivityController = Robolectric.buildActivity(TestActivity.class);
- mTestActivity = mActivityController.setup().get();
- mTestActivity.setDeviceProfile(mDeviceProfile);
-
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
- LayoutInflater.from(mTestActivity),
+ LayoutInflater.from(mContext),
mOnHeaderClickListener,
- new WidgetsListDrawableFactory(mTestActivity));
- }
-
- @After
- public void tearDown() {
- mActivityController.destroy();
+ new WidgetsListDrawableFactory(mContext));
}
@Test
public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mTestActivity));
+ new FrameLayout(mContext));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListHeaderEntry entry = generateSampleAppHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -127,14 +113,14 @@
@Test
public void bindViewHolder_shouldAttachOnHeaderClickListener() {
WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mTestActivity));
+ new FrameLayout(mContext));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListHeaderEntry entry = generateSampleAppHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
widgetsListHeader.callOnClick();
verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
@@ -153,14 +139,10 @@
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
similarity index 76%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
index 2b4cea0..453f4fb 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
@@ -15,13 +15,16 @@
*/
package com.android.launcher3.widget.picker;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -31,7 +34,9 @@
import android.widget.FrameLayout;
import android.widget.TextView;
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -39,28 +44,23 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.util.ActivityContextWrapper;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsListSearchHeaderViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -68,55 +68,40 @@
private Context mContext;
private WidgetsListSearchHeaderViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
- // Replace ActivityController with ActivityScenario, which is the recommended way for activity
- // testing.
- private ActivityController<TestActivity> mActivityController;
- private TestActivity mTestActivity;
@Mock
private IconCache mIconCache;
@Mock
- private DeviceProfile mDeviceProfile;
- @Mock
private OnHeaderClickListener mOnHeaderClickListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = new ActivityContextWrapper(getApplicationContext());
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
- mActivityController = Robolectric.buildActivity(TestActivity.class);
- mTestActivity = mActivityController.setup().get();
- mTestActivity.setDeviceProfile(mDeviceProfile);
-
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder(
- LayoutInflater.from(mTestActivity),
+ LayoutInflater.from(mContext),
mOnHeaderClickListener,
- new WidgetsListDrawableFactory(mTestActivity));
- }
-
- @After
- public void tearDown() {
- mActivityController.destroy();
+ new WidgetsListDrawableFactory(mContext));
}
@Test
public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mTestActivity));
+ new FrameLayout(mContext));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -128,14 +113,14 @@
@Test
public void bindViewHolder_shouldAttachOnHeaderClickListener() {
WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mTestActivity));
+ new FrameLayout(mContext));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
widgetsListHeader.callOnClick();
verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
@@ -154,14 +139,10 @@
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
similarity index 70%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index 9f66fb7..5816b77 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -15,13 +15,14 @@
*/
package com.android.launcher3.widget.picker;
-import static android.os.Looper.getMainLooper;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -35,7 +36,9 @@
import android.widget.TableRow;
import android.widget.TextView;
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -43,30 +46,24 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsListTableViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -74,10 +71,6 @@
private Context mContext;
private WidgetsListTableViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
- // Replace ActivityController with ActivityScenario, which is the recommended way for activity
- // testing.
- private ActivityController<TestActivity> mActivityController;
- private TestActivity mTestActivity;
@Mock
private OnLongClickListener mOnLongClickListener;
@@ -85,56 +78,42 @@
private OnClickListener mOnIconClickListener;
@Mock
private IconCache mIconCache;
- @Mock
- private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
- @Mock
- private DeviceProfile mDeviceProfile;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = new ActivityContextWrapper(getApplicationContext());
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
- mActivityController = Robolectric.buildActivity(TestActivity.class);
- mTestActivity = mActivityController.setup().get();
- mTestActivity.setDeviceProfile(mDeviceProfile);
-
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
mViewHolderBinder = new WidgetsListTableViewHolderBinder(
- LayoutInflater.from(mTestActivity),
+ LayoutInflater.from(mContext),
mOnIconClickListener,
mOnLongClickListener,
- new CachingWidgetPreviewLoader(mWidgetPreviewLoader),
- new WidgetsListDrawableFactory(mTestActivity));
- }
-
- @After
- public void tearDown() {
- mActivityController.destroy();
+ new WidgetsListDrawableFactory(mContext));
}
@Test
- public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() {
+ public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() throws Exception {
WidgetsRowViewHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mTestActivity));
+ new FrameLayout(mContext));
WidgetsListContentEntry entry = generateSampleAppWithWidgets(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
- shadowOf(getMainLooper()).idle();
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+ Executors.MAIN_EXECUTOR.submit(() -> { }).get();
// THEN the table container has one row, which contains 3 widgets.
// View: .SampleWidget0 | .SampleWidget1 | .SampleWidget2
- assertThat(viewHolder.mTableContainer.getChildCount()).isEqualTo(1);
- TableRow row = (TableRow) viewHolder.mTableContainer.getChildAt(0);
+ assertThat(viewHolder.tableContainer.getChildCount()).isEqualTo(1);
+ TableRow row = (TableRow) viewHolder.tableContainer.getChildAt(0);
assertThat(row.getChildCount()).isEqualTo(3);
// Widget 0 label is .SampleWidget0.
assertWidgetCellWithLabel(row.getChildAt(0), ".SampleWidget0");
@@ -152,18 +131,15 @@
return new WidgetsListContentEntry(appInfo,
/* titleSectionName= */ "",
- generateWidgetItems(packageName, numOfWidgets));
+ generateWidgetItems(packageName, numOfWidgets),
+ Integer.MAX_VALUE);
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
similarity index 92%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
rename to tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
index 106cac0..4b61b2c 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
@@ -15,15 +15,20 @@
*/
package com.android.launcher3.widget.picker.model;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
-import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.ComponentWithLabel;
@@ -38,16 +43,13 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsListContentEntryTest {
private static final String PACKAGE_NAME = "com.android.test";
private static final String PACKAGE_NAME_2 = "com.android.test2";
@@ -60,7 +62,6 @@
@Mock private IconCache mIconCache;
- private Context mContext;
private InvariantDeviceProfile mTestProfile;
@Before
@@ -71,7 +72,6 @@
mWidgetsToLabels.put(mWidget2, "Dog");
mWidgetsToLabels.put(mWidget3, "Bird");
- mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
@@ -242,17 +242,12 @@
assertThat(widgetsListRowEntry1.equals(widgetsListRowEntry2)).isTrue();
}
-
private WidgetItem createWidgetItem(ComponentName componentName, int spanX, int spanY) {
String label = mWidgetsToLabels.get(componentName);
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = componentName;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(componentName));
+ AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(componentName);
LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
- LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo);
+ LauncherAppWidgetProviderInfo.fromProviderInfo(getApplicationContext(), widgetInfo);
launcherAppWidgetProviderInfo.spanX = spanX;
launcherAppWidgetProviderInfo.spanY = spanY;
launcherAppWidgetProviderInfo.label = label;
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
similarity index 90%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
rename to tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index 36b6f01..c862d6b 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -16,7 +16,10 @@
package com.android.launcher3.widget.picker.search;
-import static android.os.Looper.getMainLooper;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -25,7 +28,6 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -33,6 +35,9 @@
import android.graphics.Bitmap;
import android.os.UserHandle;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.ComponentWithLabel;
@@ -52,16 +57,13 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class SimpleWidgetsSearchAlgorithmTest {
@Mock private IconCache mIconCache;
@@ -82,7 +84,7 @@
private SearchCallback<WidgetsListBaseEntry> mSearchCallback;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
@@ -91,7 +93,7 @@
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
- mContext = RuntimeEnvironment.application;
+ mContext = getApplicationContext();
mCalendarHeaderEntry =
createWidgetsHeaderEntry("com.example.android.Calendar", "Calendar", 2);
@@ -102,8 +104,8 @@
mClockHeaderEntry = createWidgetsHeaderEntry("com.example.android.Clock", "Clock", 3);
mClockContentEntry = createWidgetsContentEntry("com.example.android.Clock", "Clock", 3);
-
- mSimpleWidgetsSearchAlgorithm = new SimpleWidgetsSearchAlgorithm(mDataProvider);
+ mSimpleWidgetsSearchAlgorithm = MAIN_EXECUTOR.submit(
+ () -> new SimpleWidgetsSearchAlgorithm(mDataProvider)).get();
doReturn(Collections.EMPTY_LIST).when(mDataProvider).getAllWidgets();
}
@@ -156,13 +158,13 @@
}
@Test
- public void doSearch_shouldInformCallback() {
+ public void doSearch_shouldInformCallback() throws Exception {
doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
.when(mDataProvider)
.getAllWidgets();
mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
- shadowOf(getMainLooper()).idle();
+ MAIN_EXECUTOR.submit(() -> { }).get();
verify(mSearchCallback).onSearchResult(
matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
}
@@ -195,14 +197,10 @@
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
+ AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
WidgetItem widgetItem = new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java b/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
similarity index 83%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
rename to tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
index 7ac879a..583d37f 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
@@ -16,39 +16,38 @@
package com.android.launcher3.widget.picker.search;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.content.Context;
import android.view.View;
import android.widget.ImageButton;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.search.SearchAlgorithm;
-import com.android.launcher3.testing.TestActivity;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.android.controller.ActivityController;
import java.util.ArrayList;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class WidgetsSearchBarControllerTest {
private WidgetsSearchBarController mController;
- // TODO: Replace ActivityController with ActivityScenario, which is the recommended way for
- // activity testing.
- private ActivityController<TestActivity> mActivityController;
private ExtendedEditText mEditText;
private ImageButton mCancelButton;
@Mock
@@ -59,20 +58,14 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mActivityController = Robolectric.buildActivity(TestActivity.class);
- TestActivity testActivity = mActivityController.setup().get();
+ Context context = getApplicationContext();
- mEditText = new ExtendedEditText(testActivity);
- mCancelButton = new ImageButton(testActivity);
+ mEditText = new ExtendedEditText(context);
+ mCancelButton = new ImageButton(context);
mController = new WidgetsSearchBarController(
mSearchAlgorithm, mEditText, mCancelButton, mSearchModeListener);
}
- @After
- public void tearDown() {
- mActivityController.destroy();
- }
-
@Test
public void onSearchResult_shouldInformSearchModeListener() {
ArrayList<WidgetsListBaseEntry> entries = new ArrayList<>();
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
similarity index 89%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
rename to tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
index 56d7d68..d6da776 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
@@ -15,11 +15,14 @@
*/
package com.android.launcher3.widget.picker.util;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -29,6 +32,9 @@
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
@@ -42,15 +48,12 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public final class WidgetsTableUtilsTest {
private static final String TEST_PACKAGE = "com.google.test";
@@ -73,7 +76,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = getApplicationContext();
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
@@ -152,16 +155,14 @@
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
widgetSizes.stream().forEach(
widgetSize -> {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
- AppWidgetProviderInfo info = new AppWidgetProviderInfo();
- info.provider = ComponentName.createRelative(TEST_PACKAGE,
- ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y);
+ AppWidgetProviderInfo info = createAppWidgetProviderInfo(
+ ComponentName.createRelative(
+ TEST_PACKAGE,
+ ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y));
LauncherAppWidgetProviderInfo widgetInfo =
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
widgetInfo.spanX = widgetSize.x;
widgetInfo.spanY = widgetSize.y;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(widgetInfo.provider));
widgetItems.add(new WidgetItem(widgetInfo, mTestProfile, mIconCache));
}
);
diff --git a/tests/src_common/README.md b/tests/src_common/README.md
deleted file mode 100644
index 2bc9e73..0000000
--- a/tests/src_common/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Common source code used by both android tests and robolectric tests
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 77c8b25..e3f35e1 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -248,11 +248,24 @@
if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) {
if (TestHelpers.isInLauncherProcess()) {
pm.setComponentEnabledSetting(cn, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
+ // b/195031154
+ SystemClock.sleep(5000);
} else {
try {
final int userId = ContextUtils.getUserId(getContext());
+ final String launcherPidCommand = "pidof " + pi.packageName;
+ final String initialPid = mDevice.executeShellCommand(launcherPidCommand)
+ .replaceAll("\\s", "");
mDevice.executeShellCommand(
"pm enable --user " + userId + " " + cn.flattenToString());
+ // Wait for Launcher restart after enabling test provider.
+ for (int i = 0; i < 100; ++i) {
+ final String currentPid = mDevice.executeShellCommand(launcherPidCommand)
+ .replaceAll("\\s", "");
+ if (!currentPid.isEmpty() && !currentPid.equals(initialPid)) break;
+ if (i == 99) fail("Launcher didn't restart after enabling test provider");
+ SystemClock.sleep(100);
+ }
} catch (IOException e) {
fail(e.toString());
}
@@ -305,7 +318,7 @@
public boolean isTwoPanels() {
return getTestInfo(TestProtocol.REQUEST_IS_TWO_PANELS)
- .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
private void setForcePauseTimeout(long timeout) {
@@ -379,7 +392,7 @@
}
}
- private String getSystemAnomalyMessage() {
+ private String getSystemAnomalyMessage(boolean ignoreNavmodeChangeStates) {
try {
{
final StringBuilder sb = new StringBuilder();
@@ -402,16 +415,18 @@
if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
- final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
- .stream()
- .map(LauncherInstrumentation::getApplicationPackageSafe)
- .distinct()
- .filter(pkg -> pkg != null)
- .collect(Collectors.joining(","));
- if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
+ if (!ignoreNavmodeChangeStates) {
+ final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
+ .stream()
+ .map(LauncherInstrumentation::getApplicationPackageSafe)
+ .distinct()
+ .filter(pkg -> pkg != null)
+ .collect(Collectors.joining(","));
+ if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
- if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
- return "Screen is empty";
+ if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
+ return "Screen is empty";
+ }
}
final String navigationModeError = getNavigationModeMismatchError(true);
@@ -423,8 +438,12 @@
return null;
}
- public void checkForAnomaly() {
- final String systemAnomalyMessage = getSystemAnomalyMessage();
+ private void checkForAnomaly() {
+ checkForAnomaly(false);
+ }
+
+ public void checkForAnomaly(boolean ignoreNavmodeChangeStates) {
+ final String systemAnomalyMessage = getSystemAnomalyMessage(ignoreNavmodeChangeStates);
if (systemAnomalyMessage != null) {
Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
"http://go/tapl : Tests are broken by a non-Launcher system error: "
@@ -756,7 +775,7 @@
if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
GestureScope gestureScope = gestureStartFromLauncher
- ? (isTablet()? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
+ ? (isTablet() ? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
: GestureScope.OUTSIDE_WITH_PILFER;
linearGesture(
displaySize.x / 2, displaySize.y - 1,