Merge "Add the gesture nav tutorial menu page" into tm-qpr-dev am: 1db2fcbd19 am: cafab1d7cc

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/22119029

Change-Id: Id6121e8c572666f182e0b2d0ca250c636236f19f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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 0000000..0f2650b
--- /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 0000000..4cccd09
--- /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 0000000..7011f6c
--- /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 0000000..02f6ff9
--- /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 0000000..5becb8b
--- /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 0000000..7143089
--- /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 0000000..68c5eb1
--- /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 0000000..698cba1
--- /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 0000000..1ab776b
--- /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 0000000..cc2c491
--- /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 0000000..39c7e73
--- /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 0000000..2836259
--- /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 4ee388a..9853140 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 0000000..1d02ab5
--- /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 b747ff2..3cc9c15 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 93fb65d..3df5d57 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 952de70..8eea37f 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 9384a89..67ea1af 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 @@
         }
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 2f3a912..40c600f 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 @@
             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 @@
                 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 f440638..90a1c36 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
@@ -26,7 +26,9 @@
 /** 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 30546b0..920b32d 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -109,7 +109,7 @@
             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 @@
         }
         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 37253e2..a16b239 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -34,7 +34,13 @@
 /** 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 4a70120..1ac0742 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.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 @@
 
     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 @@
         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 @@
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
-        disableSystemGestures();
+        if (mFragment.shouldDisableSystemGestures()) {
+            disableSystemGestures();
+        }
         mFragment.onAttachedToWindow();
     }
 
@@ -103,7 +124,7 @@
     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 @@
      * 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 @@
     }
 
     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 @@
             return defaultSteps;
         }
 
-        if (savedStepsNames == null) {
+        if (savedStepsNames == null || savedStepsNames.length == 0) {
             return defaultSteps;
         }
 
@@ -190,7 +236,7 @@
             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 0000000..d52f19a
--- /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 73a08c3..91d337f 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -100,7 +100,7 @@
             case HOME_NAVIGATION_COMPLETE:
                 if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
                         || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
-                    mTutorialFragment.closeTutorial();
+                    mTutorialFragment.close();
                 }
                 break;
         }
@@ -139,7 +139,7 @@
                 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 95eafda..bced8c4 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -33,7 +33,13 @@
 /** 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 0000000..ccff30d
--- /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 c017341..1b7aee6 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -116,7 +116,7 @@
             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 @@
                 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 6b70d5a..c471a13 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -33,7 +33,13 @@
 /** 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 5183e2c..7bd52f7 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
@@ -26,7 +26,9 @@
 /** 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 545ce44..6f50e3e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -703,66 +703,65 @@
     }
 
     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();
+        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;
+        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.");
-            }
-
-            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.");
-            }
-
-            tutorialDialog.getWindow().setBackgroundDrawable(
-                    new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
-
-            return tutorialDialog;
+        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);
         }
 
-        return null;
+        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.");
+        }
+
+        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.");
+        }
+
+        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 cdcf867..3faa7e4 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -18,11 +18,13 @@
 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 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 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 @@
     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 @@
         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 @@
         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 @@
                 | mNavBarGestureHandler.onInterceptTouch(motionEvent);
     }
 
+    @Override
     void onAttachedToWindow() {
         StatsLogManager statsLogManager = getStatsLogManager();
         if (statsLogManager != null) {
@@ -363,6 +371,7 @@
         mEdgeBackGestureHandler.setViewGroupParent(getRootView());
     }
 
+    @Override
     void onDetachedFromWindow() {
         mEdgeBackGestureHandler.setViewGroupParent(null);
     }
@@ -385,6 +394,8 @@
     @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 @@
 
         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 @@
                         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 @@
 
     @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