Merge "Search query method should support multiple consumers" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 6862f07..5c81e5f 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -104,7 +104,13 @@
                         hideFeedback();
                         hideHandCoachingAnimation();
                         showRippleEffect(
-                                () -> mTutorialFragment.changeController(ASSISTANT_COMPLETE));
+                                () -> {
+                                    if (mTutorialFragment.isTutorialComplete()) {
+                                        mTutorialFragment.changeController(ASSISTANT_COMPLETE);
+                                    } else {
+                                        mTutorialFragment.continueTutorial();
+                                    }
+                                });
                         break;
                     case ASSISTANT_NOT_STARTED_BAD_ANGLE:
                         showFeedback(R.string.assistant_gesture_feedback_swipe_not_diagonal);
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 921e568..161e015 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -130,7 +130,13 @@
                 hideFeedback();
                 hideHandCoachingAnimation();
                 showRippleEffect(
-                        () -> mTutorialFragment.changeController(BACK_NAVIGATION_COMPLETE));
+                        () -> {
+                            if (mTutorialFragment.isTutorialComplete()) {
+                                mTutorialFragment.changeController(BACK_NAVIGATION_COMPLETE);
+                            } else {
+                                mTutorialFragment.continueTutorial();
+                            }
+                        });
                 break;
             case BACK_CANCELLED_FROM_LEFT:
                 showFeedback(R.string.back_gesture_feedback_cancelled_left_edge);
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index f8d9d8d..8b6777b 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -15,8 +15,6 @@
  */
 package com.android.quickstep.interaction;
 
-import static com.android.quickstep.interaction.TutorialFragment.KEY_TUTORIAL_TYPE;
-
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -25,11 +23,14 @@
 import android.view.View;
 import android.view.Window;
 
+import androidx.annotation.NonNull;
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.launcher3.R;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
 
+import java.util.ArrayDeque;
+import java.util.Deque;
 import java.util.List;
 
 /** Shows the gesture interactive sandbox in full screen mode. */
@@ -37,6 +38,9 @@
 
     private static final String LOG_TAG = "GestureSandboxActivity";
 
+    private static final String KEY_TUTORIAL_STEPS = "tutorial_steps";
+
+    private Deque<TutorialType> mTutorialSteps;
     private TutorialFragment mFragment;
 
     @Override
@@ -45,7 +49,9 @@
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.gesture_tutorial_activity);
 
-        mFragment = TutorialFragment.newInstance(getTutorialType(getIntent().getExtras()));
+        Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
+        mTutorialSteps = getTutorialSteps(args);
+        mFragment = TutorialFragment.newInstance(mTutorialSteps.pop());
         getSupportFragmentManager().beginTransaction()
                 .add(R.id.gesture_tutorial_fragment_container, mFragment)
                 .commit();
@@ -72,17 +78,65 @@
         }
     }
 
-    private TutorialType getTutorialType(Bundle extras) {
-        TutorialType defaultType = TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
+        savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
+        super.onSaveInstanceState(savedInstanceState);
+    }
 
-        if (extras == null || !extras.containsKey(KEY_TUTORIAL_TYPE)) {
-            return defaultType;
+    /** Returns true iff there aren't anymore tutorial types to display to the user. */
+    public boolean isTutorialComplete() {
+        return mTutorialSteps.isEmpty();
+    }
+
+    /**
+     * Replaces the current TutorialFragment, continuing to the next tutorial step if there is one.
+     *
+     * If there is no following step, the tutorial is closed.
+     */
+    public void continueTutorial() {
+        if (isTutorialComplete()) {
+            mFragment.closeTutorial();
+            return;
         }
-        try {
-            return TutorialType.valueOf(extras.getString(KEY_TUTORIAL_TYPE, ""));
-        } catch (IllegalArgumentException e) {
-            return defaultType;
+        mFragment = TutorialFragment.newInstance(mTutorialSteps.pop());
+        getSupportFragmentManager().beginTransaction()
+            .replace(R.id.gesture_tutorial_fragment_container, mFragment)
+            .runOnCommit(() -> mFragment.onAttachedToWindow())
+            .commit();
+    }
+
+    private String[] getTutorialStepNames() {
+        String[] tutorialStepNames = new String[mTutorialSteps.size()];
+
+        int i = 0;
+        for (TutorialType tutorialStep : mTutorialSteps) {
+            tutorialStepNames[i++] = tutorialStep.name();
         }
+
+        return tutorialStepNames;
+    }
+
+    private Deque<TutorialType> getTutorialSteps(Bundle extras) {
+        Deque<TutorialType> defaultSteps = new ArrayDeque<>();
+        defaultSteps.push(TutorialType.RIGHT_EDGE_BACK_NAVIGATION);
+
+        if (extras == null || !extras.containsKey(KEY_TUTORIAL_STEPS)) {
+            return defaultSteps;
+        }
+
+        String[] tutorialStepNames = extras.getStringArray(KEY_TUTORIAL_STEPS);
+
+        if (tutorialStepNames == null) {
+            return defaultSteps;
+        }
+
+        Deque<TutorialType> tutorialSteps = new ArrayDeque<>();
+        for (String tutorialStepName : tutorialStepNames) {
+            tutorialSteps.addLast(TutorialType.valueOf(tutorialStepName));
+        }
+
+        return tutorialSteps;
     }
 
     private void hideSystemUI() {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 0edabd4..95352d1 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -94,8 +94,13 @@
             case HOME_NAVIGATION:
                 switch (result) {
                     case HOME_GESTURE_COMPLETED: {
-                        animateFakeTaskViewHome(finalVelocity, () ->
-                                mTutorialFragment.changeController(HOME_NAVIGATION_COMPLETE));
+                        animateFakeTaskViewHome(finalVelocity, () -> {
+                            if (mTutorialFragment.isTutorialComplete()) {
+                                mTutorialFragment.changeController(HOME_NAVIGATION_COMPLETE);
+                            } else {
+                                mTutorialFragment.continueTutorial();
+                            }
+                        });
                         break;
                     }
                     case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index c636eba..45cbd0b 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -104,8 +104,13 @@
                         showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
                         break;
                     case OVERVIEW_GESTURE_COMPLETED:
-                        fadeOutFakeTaskView(true, () ->
-                                mTutorialFragment.changeController(OVERVIEW_NAVIGATION_COMPLETE));
+                        fadeOutFakeTaskView(true, () -> {
+                            if (mTutorialFragment.isTutorialComplete()) {
+                                mTutorialFragment.changeController(OVERVIEW_NAVIGATION_COMPLETE);
+                            } else {
+                                mTutorialFragment.continueTutorial();
+                            }
+                        });
                         break;
                     case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
                     case HOME_OR_OVERVIEW_CANCELLED:
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index f297d5a..608fe72 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -54,6 +54,7 @@
             fragment = new BackGestureTutorialFragment();
             tutorialType = TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
         }
+
         Bundle args = new Bundle();
         args.putSerializable(KEY_TUTORIAL_TYPE, tutorialType);
         fragment.setArguments(args);
@@ -197,6 +198,20 @@
         return mHandCoachingAnimation;
     }
 
+    void continueTutorial() {
+        if (!(getContext() instanceof GestureSandboxActivity)) {
+            closeTutorial();
+            return;
+        }
+        GestureSandboxActivity gestureSandboxActivity = (GestureSandboxActivity) getContext();
+
+        if (gestureSandboxActivity == null) {
+            closeTutorial();
+            return;
+        }
+        gestureSandboxActivity.continueTutorial();
+    }
+
     void closeTutorial() {
         FragmentActivity activity = getActivity();
         if (activity != null) {
@@ -207,4 +222,13 @@
     void startSystemNavigationSetting() {
         startActivity(new Intent("com.android.settings.GESTURE_NAVIGATION_SETTINGS"));
     }
+
+    boolean isTutorialComplete() {
+        if (!(getContext() instanceof GestureSandboxActivity)) {
+            return true;
+        }
+        GestureSandboxActivity gestureSandboxActivity = (GestureSandboxActivity) getContext();
+
+        return gestureSandboxActivity == null || gestureSandboxActivity.isTutorialComplete();
+    }
 }
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index f4b059d..47d214d 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -275,7 +275,8 @@
         launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
         launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
             startActivity(launchSandboxIntent.putExtra(
-                    "tutorial_type", "RIGHT_EDGE_BACK_NAVIGATION"));
+                    "tutorial_steps",
+                    new String[] {"RIGHT_EDGE_BACK_NAVIGATION"}));
             return true;
         });
         sandboxCategory.addPreference(launchBackTutorialPreference);
@@ -284,7 +285,9 @@
         launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
         launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
         launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
-            startActivity(launchSandboxIntent.putExtra("tutorial_type", "HOME_NAVIGATION"));
+            startActivity(launchSandboxIntent.putExtra(
+                    "tutorial_steps",
+                    new String[] {"HOME_NAVIGATION"}));
             return true;
         });
         sandboxCategory.addPreference(launchHomeTutorialPreference);
@@ -293,7 +296,9 @@
         launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
         launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
         launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
-            startActivity(launchSandboxIntent.putExtra("tutorial_type", "OVERVIEW_NAVIGATION"));
+            startActivity(launchSandboxIntent.putExtra(
+                    "tutorial_steps",
+                    new String[] {"OVERVIEW_NAVIGATION"}));
             return true;
         });
         sandboxCategory.addPreference(launchOverviewTutorialPreference);
@@ -302,7 +307,9 @@
         launchAssistantTutorialPreference.setTitle("Launch Assistant Tutorial");
         launchAssistantTutorialPreference.setSummary("Learn how to use the Assistant gesture");
         launchAssistantTutorialPreference.setOnPreferenceClickListener(preference -> {
-            startActivity(launchSandboxIntent.putExtra("tutorial_type", "ASSISTANT"));
+            startActivity(launchSandboxIntent.putExtra(
+                    "tutorial_steps",
+                    new String[] {"ASSISTANT"}));
             return true;
         });
         sandboxCategory.addPreference(launchAssistantTutorialPreference);
@@ -311,7 +318,9 @@
         launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
         launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
         launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
-            startActivity(launchSandboxIntent.putExtra("tutorial_type", "SANDBOX_MODE"));
+            startActivity(launchSandboxIntent.putExtra(
+                    "tutorial_steps",
+                    new String[] {"SANDBOX_MODE"}));
             return true;
         });
         sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java
index 5fb36b9..fe904ff 100644
--- a/src/com/android/launcher3/views/SearchResultIconRow.java
+++ b/src/com/android/launcher3/views/SearchResultIconRow.java
@@ -121,7 +121,7 @@
             prepareUsingRemoteAction(searchTarget.getRemoteAction(),
                     searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
                     searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
-                    type.equals(TARGET_TYPE_SUGGEST));
+                    type.equals(TARGET_TYPE_REMOTE_ACTION));
 
         } else if (type.equals(TARGET_TYPE_SHORTCUT)) {
             prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));