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

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

Change-Id: If33478ed5e5f5a52469565094e3b12612eff0412
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Schneider Victor-tulias
2023-03-30 20:45:59 +00:00
committed by Automerger Merge Worker
32 changed files with 963 additions and 143 deletions
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -18,4 +18,14 @@
<!-- All Set page --> <!-- All Set page -->
<dimen name="allset_page_margin_horizontal">48dp</dimen> <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> </resources>
@@ -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>
+4 -3
View File
@@ -43,13 +43,14 @@
<color name="gesture_tutorial_taskbar_color">#E8EAED</color> <color name="gesture_tutorial_taskbar_color">#E8EAED</color>
<!-- Redesigned gesture navigation tutorial --> <!-- 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_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_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_tutorial_swipe_rect">#7E44AD</color>
<color name="gesture_overview_background">#BFC8CB</color> <color name="gesture_overview_background">#BFC8CB</color>
<color name="gesture_tutorial_menu_background">#1C1B1F</color>
<!-- Mock hotseat --> <!-- Mock hotseat -->
<color name="mock_app_icon">#BDC1C6</color> <color name="mock_app_icon">#BDC1C6</color>
+12
View File
@@ -124,6 +124,18 @@
<dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen> <dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen>
<dimen name="gesture_tutorial_back_gesture_end_corner_radius">36dp</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 --> <!-- Gesture Tutorial mock conversations -->
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen> <dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
<dimen name="gesture_tutorial_message_icon_corner_radius">100dp</dimen> <dimen name="gesture_tutorial_message_icon_corner_radius">100dp</dimen>
+7
View File
@@ -47,6 +47,13 @@
<item name="android:lineHeight">44sp</item> <item name="android:lineHeight">44sp</item>
</style> </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" <style name="TextAppearance.GestureTutorial.Feedback.Title.AllSet"
parent="TextAppearance.GestureTutorial.Feedback.Title"> parent="TextAppearance.GestureTutorial.Feedback.Title">
<item name="android:letterSpacing">0.03</item> <item name="android:letterSpacing">0.03</item>
@@ -294,17 +294,27 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
} }
PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox"); PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
sandboxCategory.setSummary("Learn and practice navigation gestures"); 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); Preference launchOnboardingTutorialPreference = new Preference(context);
launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial"); launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial"); launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures."); launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> { launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] { .putExtra("tutorial_steps",
"HOME_NAVIGATION", new String[] {
"BACK_NAVIGATION", "HOME_NAVIGATION",
"OVERVIEW_NAVIGATION"})); "BACK_NAVIGATION",
"OVERVIEW_NAVIGATION"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchOnboardingTutorialPreference); sandboxCategory.addPreference(launchOnboardingTutorialPreference);
@@ -313,9 +323,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchBackTutorialPreference.setTitle("Launch Back Tutorial"); launchBackTutorialPreference.setTitle("Launch Back Tutorial");
launchBackTutorialPreference.setSummary("Learn how to use the Back gesture"); launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
launchBackTutorialPreference.setOnPreferenceClickListener(preference -> { launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] {"BACK_NAVIGATION"})); .putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchBackTutorialPreference); sandboxCategory.addPreference(launchBackTutorialPreference);
@@ -324,9 +334,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchHomeTutorialPreference.setTitle("Launch Home Tutorial"); launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture"); launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> { launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] {"HOME_NAVIGATION"})); .putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchHomeTutorialPreference); sandboxCategory.addPreference(launchHomeTutorialPreference);
@@ -335,9 +345,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial"); launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture"); launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> { launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] {"OVERVIEW_NAVIGATION"})); .putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchOverviewTutorialPreference); sandboxCategory.addPreference(launchOverviewTutorialPreference);
@@ -346,9 +356,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchAssistantTutorialPreference.setTitle("Launch Assistant Tutorial"); launchAssistantTutorialPreference.setTitle("Launch Assistant Tutorial");
launchAssistantTutorialPreference.setSummary("Learn how to use the Assistant gesture"); launchAssistantTutorialPreference.setSummary("Learn how to use the Assistant gesture");
launchAssistantTutorialPreference.setOnPreferenceClickListener(preference -> { launchAssistantTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] {"ASSISTANT"})); .putExtra("tutorial_steps", new String[] {"ASSISTANT"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchAssistantTutorialPreference); sandboxCategory.addPreference(launchAssistantTutorialPreference);
@@ -357,9 +367,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode"); launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures"); launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> { launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
startActivity(launchSandboxIntent.putExtra( startActivity(launchSandboxIntent
"tutorial_steps", .putExtra("use_tutorial_menu", false)
new String[] {"SANDBOX_MODE"})); .putExtra("tutorial_steps", new String[] {"SANDBOX_MODE"}));
return true; return true;
}); });
sandboxCategory.addPreference(launchSandboxModeTutorialPreference); sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
@@ -15,8 +15,6 @@
*/ */
package com.android.quickstep.interaction; package com.android.quickstep.interaction;
import static com.android.quickstep.interaction.TutorialController.TutorialType.ASSISTANT_COMPLETE;
import android.graphics.PointF; import android.graphics.PointF;
import com.android.launcher3.R; import com.android.launcher3.R;
@@ -47,7 +45,7 @@ final class AssistantGestureTutorialController extends TutorialController {
case ASSISTANT_COMPLETE: case ASSISTANT_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) { || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -81,7 +79,7 @@ final class AssistantGestureTutorialController extends TutorialController {
break; break;
case ASSISTANT_COMPLETE: case ASSISTANT_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) { if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the Home gesture interactive tutorial. */ /** Shows the Home gesture interactive tutorial. */
public class AssistantGestureTutorialFragment extends TutorialFragment { public class AssistantGestureTutorialFragment extends TutorialFragment {
public AssistantGestureTutorialFragment() {} public AssistantGestureTutorialFragment(boolean fromTutorialMenu) {
super(fromTutorialMenu);
}
@Override @Override
TutorialController createController(TutorialType type) { TutorialController createController(TutorialType type) {
@@ -109,7 +109,7 @@ final class BackGestureTutorialController extends TutorialController {
case BACK_NAVIGATION_COMPLETE: case BACK_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) { || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -191,7 +191,7 @@ final class BackGestureTutorialController extends TutorialController {
} }
if (mTutorialType == BACK_NAVIGATION_COMPLETE) { if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) { if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
} else if (mTutorialType == BACK_NAVIGATION) { } else if (mTutorialType == BACK_NAVIGATION) {
switch (result) { switch (result) {
@@ -34,7 +34,13 @@ import java.util.ArrayList;
/** Shows the Back gesture interactive tutorial. */ /** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment { public class BackGestureTutorialFragment extends TutorialFragment {
public BackGestureTutorialFragment() {} public BackGestureTutorialFragment() {
this(false);
}
public BackGestureTutorialFragment(boolean fromTutorialMenu) {
super(fromTutorialMenu);
}
@Nullable @Nullable
@Override @Override
@@ -26,10 +26,12 @@ import android.view.View;
import android.view.Window; import android.view.Window;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.TouchInteractionService.TISBinder; import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType; 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_TUTORIAL_STEPS = "tutorial_steps";
private static final String KEY_CURRENT_STEP = "current_step"; 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; @Nullable private TutorialType[] mTutorialSteps;
private TutorialType mCurrentTutorialStep; private GestureSandboxFragment mFragment;
private TutorialFragment mFragment;
private int mCurrentStep; private int mCurrentStep;
private int mNumSteps; private int mNumSteps;
@@ -67,10 +70,26 @@ public class GestureSandboxActivity extends FragmentActivity {
mStatsLogManager = StatsLogManager.newInstance(getApplicationContext()); mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState; Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
mTutorialSteps = getTutorialSteps(args);
mCurrentTutorialStep = mTutorialSteps[mCurrentStep - 1]; boolean gestureComplete = args != null && args.getBoolean(KEY_GESTURE_COMPLETE, false);
mFragment = TutorialFragment.newInstance( if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
mCurrentTutorialStep, args.getBoolean(KEY_GESTURE_COMPLETE, false)); && 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() getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment) .add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit(); .commit();
@@ -81,7 +100,9 @@ public class GestureSandboxActivity extends FragmentActivity {
@Override @Override
public void onAttachedToWindow() { public void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
disableSystemGestures(); if (mFragment.shouldDisableSystemGestures()) {
disableSystemGestures();
}
mFragment.onAttachedToWindow(); mFragment.onAttachedToWindow();
} }
@@ -103,7 +124,7 @@ public class GestureSandboxActivity extends FragmentActivity {
protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) { protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames()); savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep); savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep);
savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, mFragment.isGestureComplete()); mFragment.onSaveInstanceState(savedInstanceState);
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
@@ -134,21 +155,45 @@ public class GestureSandboxActivity extends FragmentActivity {
* If there is no following step, the tutorial is closed. * If there is no following step, the tutorial is closed.
*/ */
public void continueTutorial() { public void continueTutorial() {
if (isTutorialComplete()) { if (isTutorialComplete() || mTutorialSteps == null) {
mFragment.closeTutorial(); mFragment.close();
return; return;
} }
mCurrentTutorialStep = mTutorialSteps[mCurrentStep]; launchTutorialStep(mTutorialSteps[mCurrentStep], false);
mFragment = TutorialFragment.newInstance( mCurrentStep++;
mCurrentTutorialStep, /* gestureComplete= */ false); }
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() getSupportFragmentManager().beginTransaction()
.replace(R.id.gesture_tutorial_fragment_container, mFragment) .replace(R.id.gesture_tutorial_fragment_container, mFragment)
.runOnCommit(() -> mFragment.onAttachedToWindow()) .runOnCommit(() -> mFragment.onAttachedToWindow())
.commit(); .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() { private String[] getTutorialStepNames() {
if (mTutorialSteps == null) {
return new String[0];
}
String[] tutorialStepNames = new String[mTutorialSteps.length]; String[] tutorialStepNames = new String[mTutorialSteps.length];
int i = 0; int i = 0;
@@ -160,18 +205,19 @@ public class GestureSandboxActivity extends FragmentActivity {
} }
private TutorialType[] getTutorialSteps(Bundle extras) { 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; mCurrentStep = 1;
mNumSteps = 1; mNumSteps = defaultSteps.length;
if (extras == null || !extras.containsKey(KEY_TUTORIAL_STEPS)) { if (extras == null || !extras.containsKey(KEY_TUTORIAL_STEPS)) {
return defaultSteps; return defaultSteps;
} }
Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
int currentStep = extras.getInt(KEY_CURRENT_STEP, -1);
String[] savedStepsNames; String[] savedStepsNames;
Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
if (savedSteps instanceof String) { if (savedSteps instanceof String) {
savedStepsNames = TextUtils.isEmpty((String) savedSteps) savedStepsNames = TextUtils.isEmpty((String) savedSteps)
? null : ((String) savedSteps).split(","); ? null : ((String) savedSteps).split(",");
@@ -181,7 +227,7 @@ public class GestureSandboxActivity extends FragmentActivity {
return defaultSteps; return defaultSteps;
} }
if (savedStepsNames == null) { if (savedStepsNames == null || savedStepsNames.length == 0) {
return defaultSteps; return defaultSteps;
} }
@@ -190,7 +236,7 @@ public class GestureSandboxActivity extends FragmentActivity {
tutorialSteps[i] = TutorialType.valueOf(savedStepsNames[i]); tutorialSteps[i] = TutorialType.valueOf(savedStepsNames[i]);
} }
mCurrentStep = Math.max(currentStep, 1); mCurrentStep = Math.max(extras.getInt(KEY_CURRENT_STEP, -1), 1);
mNumSteps = tutorialSteps.length; mNumSteps = tutorialSteps.length;
return tutorialSteps; return tutorialSteps;
@@ -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();
}
}
}
@@ -100,7 +100,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
case HOME_NAVIGATION_COMPLETE: case HOME_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) { || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -139,7 +139,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
break; break;
case HOME_NAVIGATION_COMPLETE: case HOME_NAVIGATION_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) { if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -33,7 +33,13 @@ import java.util.ArrayList;
/** Shows the Home gesture interactive tutorial. */ /** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment { public class HomeGestureTutorialFragment extends TutorialFragment {
public HomeGestureTutorialFragment() {} public HomeGestureTutorialFragment() {
this(false);
}
public HomeGestureTutorialFragment(boolean fromTutorialMenu) {
super(fromTutorialMenu);
}
@Nullable @Nullable
@Override @Override
@@ -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);
}
}
@@ -116,7 +116,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
case OVERVIEW_NAVIGATION_COMPLETE: case OVERVIEW_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) { || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -178,7 +178,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
break; break;
case OVERVIEW_NAVIGATION_COMPLETE: case OVERVIEW_NAVIGATION_COMPLETE:
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) { if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
mTutorialFragment.closeTutorial(); mTutorialFragment.close();
} }
break; break;
} }
@@ -33,7 +33,13 @@ import java.util.ArrayList;
/** Shows the Overview gesture interactive tutorial. */ /** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment { public class OverviewGestureTutorialFragment extends TutorialFragment {
public OverviewGestureTutorialFragment() {} public OverviewGestureTutorialFragment() {
this(false);
}
public OverviewGestureTutorialFragment(boolean fromTutorialMenu) {
super(fromTutorialMenu);
}
@Nullable @Nullable
@Override @Override
@@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the general navigation gesture sandbox environment. */ /** Shows the general navigation gesture sandbox environment. */
public class SandboxModeTutorialFragment extends TutorialFragment { public class SandboxModeTutorialFragment extends TutorialFragment {
public SandboxModeTutorialFragment() {} public SandboxModeTutorialFragment(boolean fromTutorialMenu) {
super(fromTutorialMenu);
}
@Override @Override
TutorialController createController(TutorialType type) { TutorialController createController(TutorialType type) {
@@ -703,66 +703,65 @@ abstract class TutorialController implements BackGestureAttemptCallback,
} }
private AlertDialog createSkipTutorialDialog() { private AlertDialog createSkipTutorialDialog() {
if (mContext instanceof GestureSandboxActivity) { if (!(mContext instanceof GestureSandboxActivity)) {
GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext; return null;
View contentView = View.inflate( }
sandboxActivity, R.layout.gesture_tutorial_dialog, null); GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
AlertDialog tutorialDialog = new AlertDialog View contentView = View.inflate(
.Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert) sandboxActivity, R.layout.gesture_tutorial_dialog, null);
.setView(contentView) AlertDialog tutorialDialog = new AlertDialog
.create(); .Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
.setView(contentView)
.create();
PackageManager packageManager = mContext.getPackageManager(); PackageManager packageManager = mContext.getPackageManager();
CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME; CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
try { try {
tipsAppName = packageManager.getApplicationLabel( tipsAppName = packageManager.getApplicationLabel(
packageManager.getApplicationInfo( packageManager.getApplicationInfo(
PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA)); PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Log.e(LOG_TAG, Log.e(LOG_TAG,
"Could not find app label for package name: " "Could not find app label for package name: "
+ PIXEL_TIPS_APP_PACKAGE_NAME + PIXEL_TIPS_APP_PACKAGE_NAME
+ ". Defaulting to 'Pixel Tips.'", + ". Defaulting to 'Pixel Tips.'",
e); 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;
} }
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() { protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
@@ -18,11 +18,13 @@ package com.android.quickstep.interaction;
import static android.view.View.NO_ID; import static android.view.View.NO_ID;
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL; 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.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Insets; import android.graphics.Insets;
@@ -43,8 +45,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile;
@@ -54,16 +54,17 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.Set; 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"; 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 TUTORIAL_SKIPPED_PREFERENCE_KEY = "pref_gestureTutorialSkipped";
private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY = private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY =
"pref_completedTutorialSteps"; "pref_completedTutorialSteps";
private final boolean mFromTutorialMenu;
TutorialType mTutorialType; TutorialType mTutorialType;
boolean mGestureComplete = false; boolean mGestureComplete = false;
@Nullable TutorialController mTutorialController = null; @Nullable TutorialController mTutorialController = null;
@@ -85,10 +86,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
private boolean mIsFoldable; private boolean mIsFoldable;
public static TutorialFragment newInstance( public static TutorialFragment newInstance(
TutorialType tutorialType, boolean gestureComplete) { TutorialType tutorialType, boolean gestureComplete, boolean fromTutorialMenu) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType); TutorialFragment fragment = getFragmentForTutorialType(tutorialType, fromTutorialMenu);
if (fragment == null) { if (fragment == null) {
fragment = new BackGestureTutorialFragment(); fragment = new BackGestureTutorialFragment(fromTutorialMenu);
tutorialType = TutorialType.BACK_NAVIGATION; tutorialType = TutorialType.BACK_NAVIGATION;
} }
@@ -99,23 +100,28 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
return fragment; return fragment;
} }
TutorialFragment(boolean fromTutorialMenu) {
mFromTutorialMenu = fromTutorialMenu;
}
@Nullable @Nullable
private static TutorialFragment getFragmentForTutorialType(TutorialType tutorialType) { private static TutorialFragment getFragmentForTutorialType(
TutorialType tutorialType, boolean fromTutorialMenu) {
switch (tutorialType) { switch (tutorialType) {
case BACK_NAVIGATION: case BACK_NAVIGATION:
case BACK_NAVIGATION_COMPLETE: case BACK_NAVIGATION_COMPLETE:
return new BackGestureTutorialFragment(); return new BackGestureTutorialFragment(fromTutorialMenu);
case HOME_NAVIGATION: case HOME_NAVIGATION:
case HOME_NAVIGATION_COMPLETE: case HOME_NAVIGATION_COMPLETE:
return new HomeGestureTutorialFragment(); return new HomeGestureTutorialFragment(fromTutorialMenu);
case OVERVIEW_NAVIGATION: case OVERVIEW_NAVIGATION:
case OVERVIEW_NAVIGATION_COMPLETE: case OVERVIEW_NAVIGATION_COMPLETE:
return new OverviewGestureTutorialFragment(); return new OverviewGestureTutorialFragment(fromTutorialMenu);
case ASSISTANT: case ASSISTANT:
case ASSISTANT_COMPLETE: case ASSISTANT_COMPLETE:
return new AssistantGestureTutorialFragment(); return new AssistantGestureTutorialFragment(fromTutorialMenu);
case SANDBOX_MODE: case SANDBOX_MODE:
return new SandboxModeTutorialFragment(); return new SandboxModeTutorialFragment(fromTutorialMenu);
default: default:
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name()); 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); mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
mFakePreviousTaskView = mRootView.findViewById( mFakePreviousTaskView = mRootView.findViewById(
R.id.gesture_tutorial_fake_previous_task_view); R.id.gesture_tutorial_fake_previous_task_view);
return mRootView; return mRootView;
} }
@@ -355,6 +362,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
| mNavBarGestureHandler.onInterceptTouch(motionEvent); | mNavBarGestureHandler.onInterceptTouch(motionEvent);
} }
@Override
void onAttachedToWindow() { void onAttachedToWindow() {
StatsLogManager statsLogManager = getStatsLogManager(); StatsLogManager statsLogManager = getStatsLogManager();
if (statsLogManager != null) { if (statsLogManager != null) {
@@ -363,6 +371,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
mEdgeBackGestureHandler.setViewGroupParent(getRootView()); mEdgeBackGestureHandler.setViewGroupParent(getRootView());
} }
@Override
void onDetachedFromWindow() { void onDetachedFromWindow() {
mEdgeBackGestureHandler.setViewGroupParent(null); mEdgeBackGestureHandler.setViewGroupParent(null);
} }
@@ -385,6 +394,8 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
@Override @Override
public void onSaveInstanceState(Bundle savedInstanceState) { public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putSerializable(KEY_TUTORIAL_TYPE, mTutorialType); savedInstanceState.putSerializable(KEY_TUTORIAL_TYPE, mTutorialType);
savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, isGestureComplete());
savedInstanceState.putBoolean(KEY_USE_TUTORIAL_MENU, mFromTutorialMenu);
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
@@ -410,17 +421,18 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity(); GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
if (gestureSandboxActivity == null) { if (gestureSandboxActivity == null) {
closeTutorial(); close();
return; return;
} }
gestureSandboxActivity.continueTutorial(); gestureSandboxActivity.continueTutorial();
} }
void closeTutorial() { @Override
closeTutorial(false); void close() {
closeTutorialStep(false);
} }
void closeTutorial(boolean tutorialSkipped) { void closeTutorialStep(boolean tutorialSkipped) {
if (tutorialSkipped) { if (tutorialSkipped) {
SharedPreferences sharedPrefs = getSharedPreferences(); SharedPreferences sharedPrefs = getSharedPreferences();
if (sharedPrefs != null) { if (sharedPrefs != null) {
@@ -432,11 +444,12 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED); StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED);
} }
} }
FragmentActivity activity = getActivity(); GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
if (activity != null) { if (mFromTutorialMenu && gestureSandboxActivity != null) {
activity.setResult(Activity.RESULT_OK); gestureSandboxActivity.launchTutorialMenu();
activity.finish(); return;
} }
super.close();
} }
void startSystemNavigationSetting() { void startSystemNavigationSetting() {
@@ -470,9 +483,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
@Nullable @Nullable
private GestureSandboxActivity getGestureSandboxActivity() { private GestureSandboxActivity getGestureSandboxActivity() {
Context context = getContext(); Activity activity = getActivity();
return context instanceof GestureSandboxActivity ? (GestureSandboxActivity) context : null; return activity instanceof GestureSandboxActivity
? (GestureSandboxActivity) activity : null;
} }
@Nullable @Nullable