summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSchneider Victor-tulias <victortulias@google.com>2023-03-16 15:01:15 -0700
committerSchneider Victor-tulias <victortulias@google.com>2023-03-27 14:36:01 -0700
commit2851be8cba163c8abf36e82e748fa0cce225189c (patch)
tree39fae11dbfcaedbe0260eeb032ceb286684dac46
parentafdf2f10203824d6bc793f6ce0aaeec1d49dc56d (diff)
downloadLauncher3-2851be8cba163c8abf36e82e748fa0cce225189c.tar.gz
Add the gesture nav tutorial menu page
- Added the gesture tutorial menu page (launched using an intent extra) - tutorial steps now launch the menu when complete if launched from the menu - the new default set of tutorial steps is home -> back -> overview. this is to handle the case where an intent is launched that is meant to launch the tutorial menu, but ENABLE_NEW_GESTURE_NAV_TUTORIAL is false Flag: ENABLE_NEW_GESTURE_NAV_TUTORIAL Bug: 274463555 Test: Ran the tutorial and menu on a large screen, foldable and phone Change-Id: I2eb5f658115be4d5ecb0233a8f09d22efe6ebadc
-rw-r--r--quickstep/res/drawable-sw600dp-land/gesture_tutorial_back_step_shape.xml23
-rw-r--r--quickstep/res/drawable-sw600dp-land/gesture_tutorial_home_step_shape.xml27
-rw-r--r--quickstep/res/drawable-sw600dp-land/gesture_tutorial_overview_step_shape.xml27
-rw-r--r--quickstep/res/drawable-sw720dp-land/gesture_tutorial_back_step_shape.xml23
-rw-r--r--quickstep/res/drawable-sw720dp-land/gesture_tutorial_home_step_shape.xml27
-rw-r--r--quickstep/res/drawable-sw720dp-land/gesture_tutorial_overview_step_shape.xml27
-rw-r--r--quickstep/res/drawable/gesture_tutorial_back_step_shape.xml27
-rw-r--r--quickstep/res/drawable/gesture_tutorial_home_step_shape.xml23
-rw-r--r--quickstep/res/drawable/gesture_tutorial_menu_button_background.xml19
-rw-r--r--quickstep/res/drawable/gesture_tutorial_overview_step_shape.xml23
-rw-r--r--quickstep/res/layout-sw600dp-land/gesture_tutorial_step_menu.xml157
-rw-r--r--quickstep/res/layout/gesture_tutorial_step_menu.xml161
-rw-r--r--quickstep/res/values-sw600dp-land/dimens.xml10
-rw-r--r--quickstep/res/values-sw720dp-land/dimens.xml27
-rw-r--r--quickstep/res/values/colors.xml7
-rw-r--r--quickstep/res/values/dimens.xml12
-rw-r--r--quickstep/res/values/styles.xml7
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java52
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java6
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java8
-rw-r--r--quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java92
-rw-r--r--quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java41
-rw-r--r--quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java8
-rw-r--r--quickstep/src/com/android/quickstep/interaction/MenuFragment.java69
-rw-r--r--quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java8
-rw-r--r--quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialController.java109
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialFragment.java64
32 files changed, 962 insertions, 142 deletions
diff --git a/quickstep/res/drawable-sw600dp-land/gesture_tutorial_back_step_shape.xml b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_back_step_shape.xml
new file mode 100644
index 0000000000..0f2650b83f
--- /dev/null
+++ b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_back_step_shape.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="84dp"
+ android:height="208dp"
+ android:viewportWidth="84"
+ android:viewportHeight="208">
+ <path
+ android:pathData="M24.53,169.2L32.09,165.56C77.7,143.55 77.7,64.45 32.09,42.35L24.53,38.71C14.55,33.95 6.06,25.56 0,14.92V193.08C6.06,182.44 14.55,174.05 24.53,169.2Z"
+ android:fillColor="#217500"/>
+</vector>
diff --git a/quickstep/res/drawable-sw600dp-land/gesture_tutorial_home_step_shape.xml b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_home_step_shape.xml
new file mode 100644
index 0000000000..4cccd09bf5
--- /dev/null
+++ b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_home_step_shape.xml
@@ -0,0 +1,27 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="232dp"
+ android:height="67dp"
+ android:viewportWidth="232"
+ android:viewportHeight="67">
+ <group>
+ <clip-path
+ android:pathData="M0,0h232v67h-232z"/>
+ <path
+ android:pathData="M180.9,0.6H51.1C22.9,0.6 0,23.4 0,51.7V67.6H232V51.7C232,23.4 209.1,0.6 180.9,0.6Z"
+ android:fillColor="#4B67AE"/>
+ </group>
+</vector>
diff --git a/quickstep/res/drawable-sw600dp-land/gesture_tutorial_overview_step_shape.xml b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_overview_step_shape.xml
new file mode 100644
index 0000000000..7011f6c263
--- /dev/null
+++ b/quickstep/res/drawable-sw600dp-land/gesture_tutorial_overview_step_shape.xml
@@ -0,0 +1,27 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="194dp"
+ android:height="94dp"
+ android:viewportWidth="194"
+ android:viewportHeight="94">
+ <group>
+ <clip-path
+ android:pathData="M0,0h194v94.09h-194z"/>
+ <path
+ android:pathData="M185.56,76.95C184.79,75.3 184.3,73.56 184.21,71.81L182.85,55.81C182.46,51.34 180.13,47.27 176.45,44.65L163.25,35.44C161.8,34.37 160.54,33.11 159.47,31.65L150.16,18.46C147.54,14.77 143.47,12.45 139,12.06L123,10.6C121.25,10.41 119.51,10.02 117.86,9.24L103.31,2.45C101.27,1.49 99.04,1 96.91,1C94.77,1 92.54,1.49 90.5,2.45L75.95,9.24C74.31,10.02 72.56,10.51 70.81,10.6L54.81,11.96C50.35,12.35 46.27,14.68 43.65,18.36L34.44,31.56C33.37,33.01 32.11,34.27 30.66,35.34L17.27,44.65C13.58,47.27 11.26,51.34 10.87,55.81L9.41,71.81C9.22,73.56 8.83,75.3 8.05,76.95L1.26,91.5C0.78,92.67 0.39,93.83 0.1,94.99H193.52C193.32,93.83 192.94,92.57 192.35,91.5L185.56,76.95Z"
+ android:fillColor="#7E44AD"/>
+ </group>
+</vector>
diff --git a/quickstep/res/drawable-sw720dp-land/gesture_tutorial_back_step_shape.xml b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_back_step_shape.xml
new file mode 100644
index 0000000000..02f6ff9e38
--- /dev/null
+++ b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_back_step_shape.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="122dp"
+ android:height="303dp"
+ android:viewportWidth="122"
+ android:viewportHeight="303">
+ <path
+ android:pathData="M35.65,245.9L46.63,240.61C112.92,208.62 112.92,93.67 46.63,61.54L35.65,56.26C21.15,49.34 8.81,37.14 0,21.69V280.6C8.81,265.15 21.15,252.95 35.65,245.9Z"
+ android:fillColor="#217500"/>
+</vector>
diff --git a/quickstep/res/drawable-sw720dp-land/gesture_tutorial_home_step_shape.xml b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_home_step_shape.xml
new file mode 100644
index 0000000000..5becb8b0fe
--- /dev/null
+++ b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_home_step_shape.xml
@@ -0,0 +1,27 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="362dp"
+ android:height="73dp"
+ android:viewportWidth="362"
+ android:viewportHeight="73">
+ <group>
+ <clip-path
+ android:pathData="M0,0h362v73h-362z"/>
+ <path
+ android:pathData="M282.3,0H79.7C38,0 3.7,32.1 0.3,73H361.7C358.3,32.1 324,0 282.3,0Z"
+ android:fillColor="#4B67AE"/>
+ </group>
+</vector>
diff --git a/quickstep/res/drawable-sw720dp-land/gesture_tutorial_overview_step_shape.xml b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_overview_step_shape.xml
new file mode 100644
index 0000000000..7143089d48
--- /dev/null
+++ b/quickstep/res/drawable-sw720dp-land/gesture_tutorial_overview_step_shape.xml
@@ -0,0 +1,27 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="297dp"
+ android:height="144dp"
+ android:viewportWidth="297"
+ android:viewportHeight="144">
+ <group>
+ <clip-path
+ android:pathData="M0,0h297v144.04h-297z"/>
+ <path
+ android:pathData="M284.38,116.48C283.19,113.95 282.45,111.28 282.3,108.61L280.22,84.1C279.63,77.27 276.06,71.03 270.42,67.03L250.22,52.92C247.99,51.28 246.06,49.35 244.43,47.13L230.18,26.93C226.16,21.29 219.93,17.72 213.1,17.13L188.6,14.9C185.92,14.6 183.25,14.01 180.72,12.82L158.45,2.43C155.33,0.94 151.91,0.2 148.65,0.2C145.38,0.2 141.97,0.94 138.85,2.43L116.57,12.82C114.05,14.01 111.38,14.75 108.7,14.9L84.2,16.98C77.37,17.57 71.13,21.14 67.12,26.78L53.01,46.98C51.38,49.21 49.45,51.14 47.22,52.77L26.73,67.03C21.09,71.03 17.52,77.27 16.93,84.1L14.7,108.61C14.4,111.28 13.81,113.95 12.62,116.48L2.23,138.75C1.48,140.53 0.89,142.32 0.45,144.1H296.55C296.26,142.32 295.66,140.38 294.77,138.75L284.38,116.48Z"
+ android:fillColor="#7E44AD"/>
+ </group>
+</vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_back_step_shape.xml b/quickstep/res/drawable/gesture_tutorial_back_step_shape.xml
new file mode 100644
index 0000000000..68c5eb1fbd
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_back_step_shape.xml
@@ -0,0 +1,27 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="83dp"
+ android:height="208dp"
+ android:viewportWidth="83"
+ android:viewportHeight="208">
+ <group>
+ <clip-path
+ android:pathData="M0,0h83.95v208h-83.95z"/>
+ <path
+ android:pathData="M23.53,169.2L31.09,165.56C76.7,143.55 76.7,64.45 31.09,42.35L23.53,38.71C13.55,33.95 5.06,25.56 -1,14.92V193.08C5.06,182.44 13.55,174.05 23.53,169.2Z"
+ android:fillColor="#217500"/>
+ </group>
+</vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_home_step_shape.xml b/quickstep/res/drawable/gesture_tutorial_home_step_shape.xml
new file mode 100644
index 0000000000..698cba140b
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_home_step_shape.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="364dp"
+ android:height="66dp"
+ android:viewportWidth="364"
+ android:viewportHeight="66">
+ <path
+ android:pathData="M283.8,0H80.2C40.7,0 8,28.5 1.3,66H362.8C356,28.5 323.3,0 283.8,0Z"
+ android:fillColor="#4B67AE"/>
+</vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_menu_button_background.xml b/quickstep/res/drawable/gesture_tutorial_menu_button_background.xml
new file mode 100644
index 0000000000..1ab776bd6e
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_menu_button_background.xml
@@ -0,0 +1,19 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="@dimen/gesture_tutorial_menu_button_radius" />
+</shape>
diff --git a/quickstep/res/drawable/gesture_tutorial_overview_step_shape.xml b/quickstep/res/drawable/gesture_tutorial_overview_step_shape.xml
new file mode 100644
index 0000000000..cc2c491ef3
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_overview_step_shape.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="200dp"
+ android:height="76dp"
+ android:viewportWidth="200"
+ android:viewportHeight="76">
+ <path
+ android:pathData="M188.6,56.5C188.2,51.9 185.8,47.7 182,45L168.4,35.5C166.9,34.4 165.6,33.1 164.5,31.6L155,18C152.3,14.2 148.1,11.8 143.5,11.4L127,9.9C125.2,9.7 123.4,9.3 121.7,8.5L106.7,1.5C104.6,0.5 102.3,0 100.1,0C97.8,0 95.6,0.5 93.5,1.5L78.5,8.5C76.8,9.3 75,9.8 73.2,9.9L56.7,11.3C52.1,11.7 47.9,14.1 45.2,17.9L35.7,31.5C34.6,33 33.3,34.3 31.8,35.4L18,45C14.2,47.7 11.8,51.9 11.4,56.5L9.9,73C9.8,74 9.6,75 9.3,76H190.6C190.3,75 190.1,74 190,73L188.6,56.5Z"
+ android:fillColor="#7E44AD"/>
+</vector>
diff --git a/quickstep/res/layout-sw600dp-land/gesture_tutorial_step_menu.xml b/quickstep/res/layout-sw600dp-land/gesture_tutorial_step_menu.xml
new file mode 100644
index 0000000000..39c7e73d2d
--- /dev/null
+++ b/quickstep/res/layout-sw600dp-land/gesture_tutorial_step_menu.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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"
+ android:paddingTop="@dimen/gesture_tutorial_menu_padding_top"
+ android:paddingBottom="@dimen/gesture_tutorial_menu_padding_bottom"
+ android:paddingHorizontal="@dimen/gesture_tutorial_menu_padding_horizontal"
+ android:background="@color/gesture_tutorial_menu_background">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/gesture_tutorial_menu_home_button"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:layout_marginEnd="@dimen/gesture_tutorial_menu_button_spacing"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_home_tutorial_background"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/gesture_tutorial_menu_back_button">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_home_step_shape"
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_home_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/home_gesture_tutorial_title"
+
+ 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/gesture_tutorial_menu_back_button"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:layout_marginEnd="@dimen/gesture_tutorial_menu_button_spacing"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_back_tutorial_exiting_app"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toEndOf="@id/gesture_tutorial_menu_home_button"
+ app:layout_constraintEnd_toStartOf="@id/gesture_tutorial_menu_overview_button">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_back_step_shape"
+ android:layout_marginBottom="@dimen/gesture_tutorial_menu_back_shape_bottom_margin"
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_back_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/back_gesture_tutorial_title"
+
+ 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/gesture_tutorial_menu_overview_button"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_overview_tutorial_background"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toEndOf="@id/gesture_tutorial_menu_back_button"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_overview_step_shape"
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_overview_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/overview_gesture_tutorial_title"
+
+ 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.Guideline
+ android:id="@+id/guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+
+ app:layout_constraintGuide_end="@dimen/gesture_tutorial_menu_done_button_spacing"/>
+
+ <Button
+ style="@style/TextAppearance.GestureTutorial.ButtonLabel"
+ android:id="@+id/gesture_tutorial_menu_done_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingVertical="16dp"
+ android:paddingHorizontal="26dp"
+ android:layout_marginVertical="@dimen/gesture_tutorial_menu_done_button_margin"
+ android:text="@string/gesture_tutorial_action_button_label"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:stateListAnimator="@null"
+
+ app:layout_constraintTop_toBottomOf="@id/guideline"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_step_menu.xml b/quickstep/res/layout/gesture_tutorial_step_menu.xml
new file mode 100644
index 0000000000..2836259e1a
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_step_menu.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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"
+ android:paddingTop="@dimen/gesture_tutorial_menu_padding_top"
+ android:paddingBottom="@dimen/gesture_tutorial_menu_padding_bottom"
+ android:paddingHorizontal="@dimen/gesture_tutorial_menu_padding_horizontal"
+ android:background="@color/gesture_tutorial_menu_background"
+ android:clipToPadding="false">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/gesture_tutorial_menu_home_button"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_home_tutorial_background"
+ app:layout_constraintVertical_chainStyle="packed"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/gesture_tutorial_menu_back_button"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_home_step_shape"
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_home_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/home_gesture_tutorial_title"
+
+ 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/gesture_tutorial_menu_back_button"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:layout_marginTop="@dimen/gesture_tutorial_menu_button_spacing"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_back_tutorial_exiting_app"
+
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_menu_home_button"
+ app:layout_constraintBottom_toTopOf="@id/gesture_tutorial_menu_overview_button"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_back_step_shape"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_back_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/back_gesture_tutorial_title"
+
+ 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/gesture_tutorial_menu_overview_button"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/gesture_tutorial_menu_button_height"
+ android:layout_marginTop="@dimen/gesture_tutorial_menu_button_spacing"
+ android:background="@drawable/gesture_tutorial_menu_button_background"
+ android:clipToOutline="true"
+ android:backgroundTint="@color/gesture_overview_tutorial_background"
+
+ app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_menu_back_button"
+ app:layout_constraintBottom_toTopOf="@id/guideline"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gesture_tutorial_overview_step_shape"
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <TextView
+ style="@style/TextAppearance.GestureTutorial.MenuButton"
+ android:id="@+id/gesture_tutorial_menu_overview_button_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/overview_gesture_tutorial_title"
+
+ 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.Guideline
+ android:id="@+id/guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+
+ app:layout_constraintGuide_end="@dimen/gesture_tutorial_menu_done_button_spacing"/>
+
+ <Button
+ style="@style/TextAppearance.GestureTutorial.ButtonLabel"
+ android:id="@+id/gesture_tutorial_menu_done_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingVertical="16dp"
+ android:paddingHorizontal="26dp"
+ android:text="@string/gesture_tutorial_action_button_label"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:stateListAnimator="@null"
+
+ app:layout_constraintTop_toBottomOf="@id/guideline"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/values-sw600dp-land/dimens.xml b/quickstep/res/values-sw600dp-land/dimens.xml
index 4ee388a8f6..9853140f01 100644
--- a/quickstep/res/values-sw600dp-land/dimens.xml
+++ b/quickstep/res/values-sw600dp-land/dimens.xml
@@ -18,4 +18,14 @@
<!-- All Set page -->
<dimen name="allset_page_margin_horizontal">48dp</dimen>
+ <!-- Gesture Tutorial menu page -->
+ <dimen name="gesture_tutorial_menu_padding_horizontal">48dp</dimen>
+ <dimen name="gesture_tutorial_menu_padding_top">32dp</dimen>
+ <dimen name="gesture_tutorial_menu_padding_bottom">16dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_height">491dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_spacing">24dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_top_spacing">40dp</dimen>
+ <dimen name="gesture_tutorial_menu_back_shape_bottom_margin">49dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_margin">16dp</dimen>
+
</resources>
diff --git a/quickstep/res/values-sw720dp-land/dimens.xml b/quickstep/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000000..1d02ab5bc0
--- /dev/null
+++ b/quickstep/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+
+ <!-- Gesture Tutorial menu page -->
+ <dimen name="gesture_tutorial_menu_button_height">580dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_spacing">49dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_top_spacing">24dp</dimen>
+ <dimen name="gesture_tutorial_menu_back_shape_bottom_margin">21dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_spacing">80dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_margin">0dp</dimen>
+
+</resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index b747ff2e08..3cc9c1513d 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -43,13 +43,14 @@
<color name="gesture_tutorial_taskbar_color">#E8EAED</color>
<!-- Redesigned gesture navigation tutorial -->
- <color name="gesture_home_tutorial_background">#FFB399</color>
+ <color name="gesture_home_tutorial_background">#FFAD91</color>
<color name="gesture_home_tutorial_swipe_up_rect">#3857C7</color>
- <color name="gesture_back_tutorial_exiting_app">#F3A5B9</color>
+ <color name="gesture_back_tutorial_exiting_app">#F9A2B9</color>
<color name="gesture_back_tutorial_background">#3857C7</color>
- <color name="gesture_overview_tutorial_background">#E2F3AF</color>
+ <color name="gesture_overview_tutorial_background">#DFF3AF</color>
<color name="gesture_overview_tutorial_swipe_rect">#7E44AD</color>
<color name="gesture_overview_background">#BFC8CB</color>
+ <color name="gesture_tutorial_menu_background">#1C1B1F</color>
<!-- Mock hotseat -->
<color name="mock_app_icon">#BDC1C6</color>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 93fb65d107..3df5d57b55 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -124,6 +124,18 @@
<dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen>
<dimen name="gesture_tutorial_back_gesture_end_corner_radius">36dp</dimen>
+ <!-- Gesture Tutorial menu page -->
+ <dimen name="gesture_tutorial_menu_padding_horizontal">24dp</dimen>
+ <dimen name="gesture_tutorial_menu_padding_top">31dp</dimen>
+ <dimen name="gesture_tutorial_menu_padding_bottom">24dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_height">0dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_spacing">16dp</dimen>
+ <dimen name="gesture_tutorial_menu_button_radius">28dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_top_spacing">0dp</dimen>
+ <dimen name="gesture_tutorial_menu_back_shape_bottom_margin">0dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_spacing">72dp</dimen>
+ <dimen name="gesture_tutorial_menu_done_button_margin">0dp</dimen>
+
<!-- Gesture Tutorial mock conversations -->
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
<dimen name="gesture_tutorial_message_icon_corner_radius">100dp</dimen>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 952de70f33..8eea37f6c2 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -47,6 +47,13 @@
<item name="android:lineHeight">44sp</item>
</style>
+ <style name="TextAppearance.GestureTutorial.MenuButton"
+ parent="TextAppearance.GestureTutorial.Feedback.Title">
+ <item name="android:gravity">center</item>
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="fontWeight">400</item>
+ </style>
+
<style name="TextAppearance.GestureTutorial.Feedback.Title.AllSet"
parent="TextAppearance.GestureTutorial.Feedback.Title">
<item name="android:letterSpacing">0.03</item>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
index 9384a89fca..67ea1af056 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
@@ -294,17 +294,27 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
}
PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
sandboxCategory.setSummary("Learn and practice navigation gestures");
+ Preference launchTutorialStepMenuPreference = new Preference(context);
+ launchTutorialStepMenuPreference.setKey("launchTutorialStepMenu");
+ launchTutorialStepMenuPreference.setTitle("Launch Gesture Tutorial Steps menu");
+ launchTutorialStepMenuPreference.setSummary("Select a gesture tutorial step.");
+ launchTutorialStepMenuPreference.setOnPreferenceClickListener(preference -> {
+ startActivity(launchSandboxIntent.putExtra("use_tutorial_menu", true));
+ return true;
+ });
+ sandboxCategory.addPreference(launchTutorialStepMenuPreference);
Preference launchOnboardingTutorialPreference = new Preference(context);
launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {
- "HOME_NAVIGATION",
- "BACK_NAVIGATION",
- "OVERVIEW_NAVIGATION"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps",
+ new String[] {
+ "HOME_NAVIGATION",
+ "BACK_NAVIGATION",
+ "OVERVIEW_NAVIGATION"}));
return true;
});
sandboxCategory.addPreference(launchOnboardingTutorialPreference);
@@ -313,9 +323,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchBackTutorialPreference.setTitle("Launch Back Tutorial");
launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {"BACK_NAVIGATION"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
return true;
});
sandboxCategory.addPreference(launchBackTutorialPreference);
@@ -324,9 +334,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {"HOME_NAVIGATION"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
return true;
});
sandboxCategory.addPreference(launchHomeTutorialPreference);
@@ -335,9 +345,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {"OVERVIEW_NAVIGATION"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
return true;
});
sandboxCategory.addPreference(launchOverviewTutorialPreference);
@@ -346,9 +356,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchAssistantTutorialPreference.setTitle("Launch Assistant Tutorial");
launchAssistantTutorialPreference.setSummary("Learn how to use the Assistant gesture");
launchAssistantTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {"ASSISTANT"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", new String[] {"ASSISTANT"}));
return true;
});
sandboxCategory.addPreference(launchAssistantTutorialPreference);
@@ -357,9 +367,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra(
- "tutorial_steps",
- new String[] {"SANDBOX_MODE"}));
+ startActivity(launchSandboxIntent
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", new String[] {"SANDBOX_MODE"}));
return true;
});
sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 2f3a912fb4..40c600f512 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.quickstep.interaction.TutorialController.TutorialType.ASSISTANT_COMPLETE;
-
import android.graphics.PointF;
import com.android.launcher3.R;
@@ -47,7 +45,7 @@ final class AssistantGestureTutorialController extends TutorialController {
case ASSISTANT_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
@@ -81,7 +79,7 @@ final class AssistantGestureTutorialController extends TutorialController {
break;
case ASSISTANT_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
index f440638125..90a1c36dc4 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
@@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the Home gesture interactive tutorial. */
public class AssistantGestureTutorialFragment extends TutorialFragment {
- public AssistantGestureTutorialFragment() {}
+ public AssistantGestureTutorialFragment(boolean fromTutorialMenu) {
+ super(fromTutorialMenu);
+ }
@Override
TutorialController createController(TutorialType type) {
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 30546b04e0..920b32d4c1 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -109,7 +109,7 @@ final class BackGestureTutorialController extends TutorialController {
case BACK_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
@@ -191,7 +191,7 @@ final class BackGestureTutorialController extends TutorialController {
}
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
} else if (mTutorialType == BACK_NAVIGATION) {
switch (result) {
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 37253e2b40..a16b239ff5 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -34,7 +34,13 @@ import java.util.ArrayList;
/** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment {
- public BackGestureTutorialFragment() {}
+ public BackGestureTutorialFragment() {
+ this(false);
+ }
+
+ public BackGestureTutorialFragment(boolean fromTutorialMenu) {
+ super(fromTutorialMenu);
+ }
@Nullable
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index 4a701202db..1ac07425bd 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -26,10 +26,12 @@ import android.view.View;
import android.view.Window;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -42,11 +44,12 @@ public class GestureSandboxActivity extends FragmentActivity {
private static final String KEY_TUTORIAL_STEPS = "tutorial_steps";
private static final String KEY_CURRENT_STEP = "current_step";
- private static final String KEY_GESTURE_COMPLETE = "gesture_complete";
+ static final String KEY_TUTORIAL_TYPE = "tutorial_type";
+ static final String KEY_GESTURE_COMPLETE = "gesture_complete";
+ static final String KEY_USE_TUTORIAL_MENU = "use_tutorial_menu";
- private TutorialType[] mTutorialSteps;
- private TutorialType mCurrentTutorialStep;
- private TutorialFragment mFragment;
+ @Nullable private TutorialType[] mTutorialSteps;
+ private GestureSandboxFragment mFragment;
private int mCurrentStep;
private int mNumSteps;
@@ -67,10 +70,26 @@ public class GestureSandboxActivity extends FragmentActivity {
mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
- mTutorialSteps = getTutorialSteps(args);
- mCurrentTutorialStep = mTutorialSteps[mCurrentStep - 1];
- mFragment = TutorialFragment.newInstance(
- mCurrentTutorialStep, args.getBoolean(KEY_GESTURE_COMPLETE, false));
+
+ boolean gestureComplete = args != null && args.getBoolean(KEY_GESTURE_COMPLETE, false);
+ if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
+ && args != null
+ && args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) {
+ mTutorialSteps = null;
+ TutorialType tutorialTypeOverride = (TutorialType) args.get(KEY_TUTORIAL_TYPE);
+ mFragment = tutorialTypeOverride == null
+ ? new MenuFragment()
+ : makeTutorialFragment(
+ tutorialTypeOverride,
+ gestureComplete,
+ /* fromMenu= */ true);
+ } else {
+ mTutorialSteps = getTutorialSteps(args);
+ mFragment = makeTutorialFragment(
+ mTutorialSteps[mCurrentStep - 1],
+ gestureComplete,
+ /* fromMenu= */ false);
+ }
getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit();
@@ -81,7 +100,9 @@ public class GestureSandboxActivity extends FragmentActivity {
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
- disableSystemGestures();
+ if (mFragment.shouldDisableSystemGestures()) {
+ disableSystemGestures();
+ }
mFragment.onAttachedToWindow();
}
@@ -103,7 +124,7 @@ public class GestureSandboxActivity extends FragmentActivity {
protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep);
- savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, mFragment.isGestureComplete());
+ mFragment.onSaveInstanceState(savedInstanceState);
super.onSaveInstanceState(savedInstanceState);
}
@@ -134,21 +155,45 @@ public class GestureSandboxActivity extends FragmentActivity {
* If there is no following step, the tutorial is closed.
*/
public void continueTutorial() {
- if (isTutorialComplete()) {
- mFragment.closeTutorial();
+ if (isTutorialComplete() || mTutorialSteps == null) {
+ mFragment.close();
return;
}
- mCurrentTutorialStep = mTutorialSteps[mCurrentStep];
- mFragment = TutorialFragment.newInstance(
- mCurrentTutorialStep, /* gestureComplete= */ false);
+ launchTutorialStep(mTutorialSteps[mCurrentStep], false);
+ mCurrentStep++;
+ }
+
+ private TutorialFragment makeTutorialFragment(
+ @NonNull TutorialType tutorialType, boolean gestureComplete, boolean fromMenu) {
+ return TutorialFragment.newInstance(tutorialType, gestureComplete, fromMenu);
+ }
+
+ /**
+ * Launches the given gesture nav tutorial step.
+ *
+ * If the step is being launched from the gesture nav tutorial menu, then that step will launch
+ * the menu when complete.
+ */
+ public void launchTutorialStep(@NonNull TutorialType tutorialType, boolean fromMenu) {
+ mFragment = makeTutorialFragment(tutorialType, false, fromMenu);
getSupportFragmentManager().beginTransaction()
.replace(R.id.gesture_tutorial_fragment_container, mFragment)
.runOnCommit(() -> mFragment.onAttachedToWindow())
.commit();
- mCurrentStep++;
+ }
+
+ /** Launches the gesture nav tutorial menu page */
+ public void launchTutorialMenu() {
+ mFragment = new MenuFragment();
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.gesture_tutorial_fragment_container, mFragment)
+ .commit();
}
private String[] getTutorialStepNames() {
+ if (mTutorialSteps == null) {
+ return new String[0];
+ }
String[] tutorialStepNames = new String[mTutorialSteps.length];
int i = 0;
@@ -160,18 +205,19 @@ public class GestureSandboxActivity extends FragmentActivity {
}
private TutorialType[] getTutorialSteps(Bundle extras) {
- TutorialType[] defaultSteps = new TutorialType[] {TutorialType.BACK_NAVIGATION};
+ TutorialType[] defaultSteps = new TutorialType[] {
+ TutorialType.HOME_NAVIGATION,
+ TutorialType.BACK_NAVIGATION,
+ TutorialType.OVERVIEW_NAVIGATION};
mCurrentStep = 1;
- mNumSteps = 1;
+ mNumSteps = defaultSteps.length;
if (extras == null || !extras.containsKey(KEY_TUTORIAL_STEPS)) {
return defaultSteps;
}
- Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
- int currentStep = extras.getInt(KEY_CURRENT_STEP, -1);
String[] savedStepsNames;
-
+ Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
if (savedSteps instanceof String) {
savedStepsNames = TextUtils.isEmpty((String) savedSteps)
? null : ((String) savedSteps).split(",");
@@ -181,7 +227,7 @@ public class GestureSandboxActivity extends FragmentActivity {
return defaultSteps;
}
- if (savedStepsNames == null) {
+ if (savedStepsNames == null || savedStepsNames.length == 0) {
return defaultSteps;
}
@@ -190,7 +236,7 @@ public class GestureSandboxActivity extends FragmentActivity {
tutorialSteps[i] = TutorialType.valueOf(savedStepsNames[i]);
}
- mCurrentStep = Math.max(currentStep, 1);
+ mCurrentStep = Math.max(extras.getInt(KEY_CURRENT_STEP, -1), 1);
mNumSteps = tutorialSteps.length;
return tutorialSteps;
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java
new file mode 100644
index 0000000000..d52f19a2b5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.app.Activity;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+
+/** Displays one page of the gesture nav tutorial. */
+public abstract class GestureSandboxFragment extends Fragment {
+
+ void onAttachedToWindow() {}
+
+ void onDetachedFromWindow() {}
+
+ boolean shouldDisableSystemGestures() {
+ return true;
+ }
+
+ void close() {
+ FragmentActivity activity = getActivity();
+ if (activity != null) {
+ activity.setResult(Activity.RESULT_OK);
+ activity.finish();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 99d417e3b4..98b8d98dce 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -99,7 +99,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
case HOME_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
@@ -138,7 +138,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
break;
case HOME_NAVIGATION_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 95eafdae33..bced8c4aef 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -33,7 +33,13 @@ import java.util.ArrayList;
/** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment {
- public HomeGestureTutorialFragment() {}
+ public HomeGestureTutorialFragment() {
+ this(false);
+ }
+
+ public HomeGestureTutorialFragment(boolean fromTutorialMenu) {
+ super(fromTutorialMenu);
+ }
@Nullable
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/MenuFragment.java b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java
new file mode 100644
index 0000000000..ccff30d319
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_GESTURE_COMPLETE;
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_TUTORIAL_TYPE;
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_USE_TUTORIAL_MENU;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+/** Displays the gesture nav tutorial menu. */
+public final class MenuFragment extends GestureSandboxFragment {
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View root = inflater.inflate(
+ R.layout.gesture_tutorial_step_menu, container, false);
+
+ root.findViewById(R.id.gesture_tutorial_menu_home_button).setOnClickListener(
+ v -> launchTutorialStep(TutorialController.TutorialType.HOME_NAVIGATION));
+ root.findViewById(R.id.gesture_tutorial_menu_back_button).setOnClickListener(
+ v -> launchTutorialStep(TutorialController.TutorialType.BACK_NAVIGATION));
+ root.findViewById(R.id.gesture_tutorial_menu_overview_button).setOnClickListener(
+ v -> launchTutorialStep(TutorialController.TutorialType.OVERVIEW_NAVIGATION));
+ root.findViewById(R.id.gesture_tutorial_menu_done_button).setOnClickListener(
+ v -> close());
+
+ return root;
+ }
+
+ @Override
+ boolean shouldDisableSystemGestures() {
+ return false;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ savedInstanceState.putBoolean(KEY_USE_TUTORIAL_MENU, true);
+ savedInstanceState.remove(KEY_TUTORIAL_TYPE);
+ savedInstanceState.remove(KEY_GESTURE_COMPLETE);
+ super.onSaveInstanceState(savedInstanceState);
+ }
+
+ private void launchTutorialStep(@NonNull TutorialController.TutorialType tutorialType) {
+ ((GestureSandboxActivity) getActivity()).launchTutorialStep(tutorialType, true);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index c017341a37..1b7aee6b7b 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -116,7 +116,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
case OVERVIEW_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
@@ -178,7 +178,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
break;
case OVERVIEW_NAVIGATION_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
- mTutorialFragment.closeTutorial();
+ mTutorialFragment.close();
}
break;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index 6b70d5a059..c471a13869 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -33,7 +33,13 @@ import java.util.ArrayList;
/** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment {
- public OverviewGestureTutorialFragment() {}
+ public OverviewGestureTutorialFragment() {
+ this(false);
+ }
+
+ public OverviewGestureTutorialFragment(boolean fromTutorialMenu) {
+ super(fromTutorialMenu);
+ }
@Nullable
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
index 5183e2c961..7bd52f750d 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
@@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the general navigation gesture sandbox environment. */
public class SandboxModeTutorialFragment extends TutorialFragment {
- public SandboxModeTutorialFragment() {}
+ public SandboxModeTutorialFragment(boolean fromTutorialMenu) {
+ super(fromTutorialMenu);
+ }
@Override
TutorialController createController(TutorialType type) {
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 545ce4460c..6f50e3e4a5 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -703,66 +703,65 @@ abstract class TutorialController implements BackGestureAttemptCallback,
}
private AlertDialog createSkipTutorialDialog() {
- if (mContext instanceof GestureSandboxActivity) {
- GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
- View contentView = View.inflate(
- sandboxActivity, R.layout.gesture_tutorial_dialog, null);
- AlertDialog tutorialDialog = new AlertDialog
- .Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
- .setView(contentView)
- .create();
-
- PackageManager packageManager = mContext.getPackageManager();
- CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
-
- try {
- tipsAppName = packageManager.getApplicationLabel(
- packageManager.getApplicationInfo(
- PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG,
- "Could not find app label for package name: "
- + PIXEL_TIPS_APP_PACKAGE_NAME
- + ". Defaulting to 'Pixel Tips.'",
- e);
- }
-
- TextView subtitleTextView = (TextView) contentView.findViewById(
- R.id.gesture_tutorial_dialog_subtitle);
- if (subtitleTextView != null) {
- subtitleTextView.setText(
- mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
- } else {
- Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
- }
-
- Button cancelButton = (Button) contentView.findViewById(
- R.id.gesture_tutorial_dialog_cancel_button);
- if (cancelButton != null) {
- cancelButton.setOnClickListener(
- v -> tutorialDialog.dismiss());
- } else {
- Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
- }
+ if (!(mContext instanceof GestureSandboxActivity)) {
+ return null;
+ }
+ GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
+ View contentView = View.inflate(
+ sandboxActivity, R.layout.gesture_tutorial_dialog, null);
+ AlertDialog tutorialDialog = new AlertDialog
+ .Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
+ .setView(contentView)
+ .create();
+
+ PackageManager packageManager = mContext.getPackageManager();
+ CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
+
+ try {
+ tipsAppName = packageManager.getApplicationLabel(
+ packageManager.getApplicationInfo(
+ PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG,
+ "Could not find app label for package name: "
+ + PIXEL_TIPS_APP_PACKAGE_NAME
+ + ". Defaulting to 'Pixel Tips.'",
+ e);
+ }
- Button confirmButton = contentView.findViewById(
- R.id.gesture_tutorial_dialog_confirm_button);
- if (confirmButton != null) {
- confirmButton.setOnClickListener(v -> {
- mTutorialFragment.closeTutorial(true);
- tutorialDialog.dismiss();
- });
- } else {
- Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
- }
+ TextView subtitleTextView = (TextView) contentView.findViewById(
+ R.id.gesture_tutorial_dialog_subtitle);
+ if (subtitleTextView != null) {
+ subtitleTextView.setText(
+ mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
+ } else {
+ Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
+ }
- tutorialDialog.getWindow().setBackgroundDrawable(
- new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
+ Button cancelButton = (Button) contentView.findViewById(
+ R.id.gesture_tutorial_dialog_cancel_button);
+ if (cancelButton != null) {
+ cancelButton.setOnClickListener(
+ v -> tutorialDialog.dismiss());
+ } else {
+ Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
+ }
- return tutorialDialog;
+ Button confirmButton = contentView.findViewById(
+ R.id.gesture_tutorial_dialog_confirm_button);
+ if (confirmButton != null) {
+ confirmButton.setOnClickListener(v -> {
+ mTutorialFragment.closeTutorialStep(true);
+ tutorialDialog.dismiss();
+ });
+ } else {
+ Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
}
- return null;
+ tutorialDialog.getWindow().setBackgroundDrawable(
+ new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
+
+ return tutorialDialog;
}
protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index cdcf867fe2..3faa7e477a 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -18,11 +18,13 @@ package com.android.quickstep.interaction;
import static android.view.View.NO_ID;
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_GESTURE_COMPLETE;
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_TUTORIAL_TYPE;
+import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_USE_TUTORIAL_MENU;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Insets;
@@ -43,8 +45,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -54,16 +54,17 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.Set;
-abstract class TutorialFragment extends Fragment implements OnTouchListener {
+/** Displays a gesture nav tutorial step. */
+abstract class TutorialFragment extends GestureSandboxFragment implements OnTouchListener {
private static final String LOG_TAG = "TutorialFragment";
- static final String KEY_TUTORIAL_TYPE = "tutorial_type";
- static final String KEY_GESTURE_COMPLETE = "gesture_complete";
private static final String TUTORIAL_SKIPPED_PREFERENCE_KEY = "pref_gestureTutorialSkipped";
private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY =
"pref_completedTutorialSteps";
+ private final boolean mFromTutorialMenu;
+
TutorialType mTutorialType;
boolean mGestureComplete = false;
@Nullable TutorialController mTutorialController = null;
@@ -85,10 +86,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
private boolean mIsFoldable;
public static TutorialFragment newInstance(
- TutorialType tutorialType, boolean gestureComplete) {
- TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
+ TutorialType tutorialType, boolean gestureComplete, boolean fromTutorialMenu) {
+ TutorialFragment fragment = getFragmentForTutorialType(tutorialType, fromTutorialMenu);
if (fragment == null) {
- fragment = new BackGestureTutorialFragment();
+ fragment = new BackGestureTutorialFragment(fromTutorialMenu);
tutorialType = TutorialType.BACK_NAVIGATION;
}
@@ -99,23 +100,28 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
return fragment;
}
+ TutorialFragment(boolean fromTutorialMenu) {
+ mFromTutorialMenu = fromTutorialMenu;
+ }
+
@Nullable
- private static TutorialFragment getFragmentForTutorialType(TutorialType tutorialType) {
+ private static TutorialFragment getFragmentForTutorialType(
+ TutorialType tutorialType, boolean fromTutorialMenu) {
switch (tutorialType) {
case BACK_NAVIGATION:
case BACK_NAVIGATION_COMPLETE:
- return new BackGestureTutorialFragment();
+ return new BackGestureTutorialFragment(fromTutorialMenu);
case HOME_NAVIGATION:
case HOME_NAVIGATION_COMPLETE:
- return new HomeGestureTutorialFragment();
+ return new HomeGestureTutorialFragment(fromTutorialMenu);
case OVERVIEW_NAVIGATION:
case OVERVIEW_NAVIGATION_COMPLETE:
- return new OverviewGestureTutorialFragment();
+ return new OverviewGestureTutorialFragment(fromTutorialMenu);
case ASSISTANT:
case ASSISTANT_COMPLETE:
- return new AssistantGestureTutorialFragment();
+ return new AssistantGestureTutorialFragment(fromTutorialMenu);
case SANDBOX_MODE:
- return new SandboxModeTutorialFragment();
+ return new SandboxModeTutorialFragment(fromTutorialMenu);
default:
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
}
@@ -202,6 +208,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
mFakePreviousTaskView = mRootView.findViewById(
R.id.gesture_tutorial_fake_previous_task_view);
+
return mRootView;
}
@@ -355,6 +362,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
| mNavBarGestureHandler.onInterceptTouch(motionEvent);
}
+ @Override
void onAttachedToWindow() {
StatsLogManager statsLogManager = getStatsLogManager();
if (statsLogManager != null) {
@@ -363,6 +371,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
mEdgeBackGestureHandler.setViewGroupParent(getRootView());
}
+ @Override
void onDetachedFromWindow() {
mEdgeBackGestureHandler.setViewGroupParent(null);
}
@@ -385,6 +394,8 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putSerializable(KEY_TUTORIAL_TYPE, mTutorialType);
+ savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, isGestureComplete());
+ savedInstanceState.putBoolean(KEY_USE_TUTORIAL_MENU, mFromTutorialMenu);
super.onSaveInstanceState(savedInstanceState);
}
@@ -410,17 +421,18 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
if (gestureSandboxActivity == null) {
- closeTutorial();
+ close();
return;
}
gestureSandboxActivity.continueTutorial();
}
- void closeTutorial() {
- closeTutorial(false);
+ @Override
+ void close() {
+ closeTutorialStep(false);
}
- void closeTutorial(boolean tutorialSkipped) {
+ void closeTutorialStep(boolean tutorialSkipped) {
if (tutorialSkipped) {
SharedPreferences sharedPrefs = getSharedPreferences();
if (sharedPrefs != null) {
@@ -432,11 +444,12 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED);
}
}
- FragmentActivity activity = getActivity();
- if (activity != null) {
- activity.setResult(Activity.RESULT_OK);
- activity.finish();
+ GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
+ if (mFromTutorialMenu && gestureSandboxActivity != null) {
+ gestureSandboxActivity.launchTutorialMenu();
+ return;
}
+ super.close();
}
void startSystemNavigationSetting() {
@@ -470,9 +483,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
@Nullable
private GestureSandboxActivity getGestureSandboxActivity() {
- Context context = getContext();
+ Activity activity = getActivity();
- return context instanceof GestureSandboxActivity ? (GestureSandboxActivity) context : null;
+ return activity instanceof GestureSandboxActivity
+ ? (GestureSandboxActivity) activity : null;
}
@Nullable