Merge "Align fallback result query with result text" into ub-launcher3-master
diff --git a/protos/launcher_trace.proto b/protos/launcher_trace.proto
index c6f3543..65fcfe5 100644
--- a/protos/launcher_trace.proto
+++ b/protos/launcher_trace.proto
@@ -28,4 +28,40 @@
 message TouchInteractionServiceProto {
 
     optional bool service_connected = 1;
+    optional OverviewComponentObserverProto overview_component_obvserver = 2;
+    optional InputConsumerProto input_consumer = 3;
+}
+
+message OverviewComponentObserverProto {
+
+    optional bool overview_activity_started = 1;
+    optional bool overview_activity_resumed = 2;
+}
+
+message InputConsumerProto {
+
+    optional string name = 1;
+    optional SwipeHandlerProto swipe_handler = 2;
+}
+
+message SwipeHandlerProto {
+
+    optional GestureStateProto gesture_state = 1;
+    optional bool is_recents_attached_to_app_window = 2;
+    optional int32 scroll_offset = 3;
+    // Swipe up progress from 0 (app) to 1 (overview); can be > 1 if swiping past overview.
+    optional float app_to_overview_progress = 4;
+}
+
+message GestureStateProto {
+
+    optional GestureEndTarget endTarget = 1 [default = UNSET];
+
+    enum GestureEndTarget {
+        UNSET = 0;
+        HOME = 1;
+        RECENTS = 2;
+        NEW_TASK = 3;
+        LAST_TASK = 4;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index dbf75fa..b43d63b 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -81,6 +81,8 @@
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.tracing.InputConsumerProto;
+import com.android.launcher3.tracing.SwipeHandlerProto;
 import com.android.launcher3.util.TraceHelper;
 import com.android.launcher3.util.VibratorWrapper;
 import com.android.launcher3.util.WindowBounds;
@@ -92,6 +94,7 @@
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.util.InputConsumerProxy;
 import com.android.quickstep.util.MotionPauseDetector;
+import com.android.quickstep.util.ProtoTracer;
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.quickstep.util.SurfaceTransactionApplier;
 import com.android.quickstep.util.TransformParams;
@@ -1608,6 +1611,27 @@
             }
             mTaskViewSimulator.apply(mTransformParams);
         }
+        ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
+    }
+
+    /**
+     * Used for winscope tracing, see launcher_trace.proto
+     * @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
+     * @param inputConsumerProto The parent of this proto message.
+     */
+    public void writeToProto(InputConsumerProto.Builder inputConsumerProto) {
+        SwipeHandlerProto.Builder swipeHandlerProto = SwipeHandlerProto.newBuilder();
+
+        mGestureState.writeToProto(swipeHandlerProto);
+
+        swipeHandlerProto.setIsRecentsAttachedToAppWindow(
+                mAnimationFactory.isRecentsAttachedToAppWindow());
+        swipeHandlerProto.setScrollOffset(mRecentsView == null
+                ? 0
+                : mRecentsView.getScrollOffset());
+        swipeHandlerProto.setAppToOverviewProgress(mCurrentShift.value);
+
+        inputConsumerProto.setSwipeHandler(swipeHandlerProto);
     }
 
     public interface Factory {
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index d35e270..9089ae5 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -297,6 +297,10 @@
          * @param animate Whether to animate recents to/from its new attached state.
          */
         default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
+
+        default boolean isRecentsAttachedToAppWindow() {
+            return false;
+        }
     }
 
     class DefaultAnimationFactory implements AnimationFactory {
@@ -388,6 +392,11 @@
             fadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0).start();
         }
 
+        @Override
+        public boolean isRecentsAttachedToAppWindow() {
+            return mIsAttachedToWindow;
+        }
+
         protected void createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa) {
             //  Scale down recents from being full screen to being in overview.
             RecentsView recentsView = activity.getOverviewPanel();
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 9c23c83..f788996 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -26,6 +26,8 @@
 import android.os.Build;
 
 import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.tracing.GestureStateProto;
+import com.android.launcher3.tracing.SwipeHandlerProto;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -46,19 +48,22 @@
      * Defines the end targets of a gesture and the associated state.
      */
     public enum GestureEndTarget {
-        HOME(true, LAUNCHER_STATE_HOME, false),
+        HOME(true, LAUNCHER_STATE_HOME, false, GestureStateProto.GestureEndTarget.HOME),
 
-        RECENTS(true, LAUNCHER_STATE_OVERVIEW, true),
+        RECENTS(true, LAUNCHER_STATE_OVERVIEW, true, GestureStateProto.GestureEndTarget.RECENTS),
 
-        NEW_TASK(false, LAUNCHER_STATE_BACKGROUND, true),
+        NEW_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
+                GestureStateProto.GestureEndTarget.NEW_TASK),
 
-        LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true);
+        LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
+                GestureStateProto.GestureEndTarget.LAST_TASK);
 
-        GestureEndTarget(boolean isLauncher, int containerType,
-                boolean recentsAttachedToAppWindow) {
+        GestureEndTarget(boolean isLauncher, int containerType, boolean recentsAttachedToAppWindow,
+                GestureStateProto.GestureEndTarget protoEndTarget) {
             this.isLauncher = isLauncher;
             this.containerType = containerType;
             this.recentsAttachedToAppWindow = recentsAttachedToAppWindow;
+            this.protoEndTarget = protoEndTarget;
         }
 
         /** Whether the target is in the launcher activity. Implicitly, if the end target is going
@@ -68,6 +73,8 @@
         public final int containerType;
         /** Whether RecentsView should be attached to the window as we animate to this target */
         public final boolean recentsAttachedToAppWindow;
+        /** The GestureStateProto enum value, used for winscope tracing. See launcher_trace.proto */
+        public final GestureStateProto.GestureEndTarget protoEndTarget;
     }
 
     private static final String TAG = "GestureState";
@@ -345,4 +352,17 @@
         pw.println("  lastStartedTaskId=" + mLastStartedTaskId);
         pw.println("  isRecentsAnimationRunning=" + isRecentsAnimationRunning());
     }
+
+    /**
+     * Used for winscope tracing, see launcher_trace.proto
+     * @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
+     * @param swipeHandlerProto The parent of this proto message.
+     */
+    public void writeToProto(SwipeHandlerProto.Builder swipeHandlerProto) {
+        GestureStateProto.Builder gestureStateProto = GestureStateProto.newBuilder();
+        gestureStateProto.setEndTarget(mEndTarget == null
+                ? GestureStateProto.GestureEndTarget.UNSET
+                : mEndTarget.protoEndTarget);
+        swipeHandlerProto.setGestureState(gestureStateProto);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/InputConsumer.java b/quickstep/src/com/android/quickstep/InputConsumer.java
index 67711c0..0b2a057 100644
--- a/quickstep/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/src/com/android/quickstep/InputConsumer.java
@@ -21,6 +21,9 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import com.android.launcher3.tracing.InputConsumerProto;
+import com.android.launcher3.tracing.TouchInteractionServiceProto;
+
 @TargetApi(Build.VERSION_CODES.O)
 public interface InputConsumer {
 
@@ -116,4 +119,21 @@
         }
         return name.toString();
     }
+
+    /**
+     * Used for winscope tracing, see launcher_trace.proto
+     * @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
+     * @param serviceProto The parent of this proto message.
+     */
+    default void writeToProto(TouchInteractionServiceProto.Builder serviceProto) {
+        InputConsumerProto.Builder inputConsumerProto = InputConsumerProto.newBuilder();
+        inputConsumerProto.setName(getName());
+        writeToProtoInternal(inputConsumerProto);
+        serviceProto.setInputConsumer(inputConsumerProto);
+    }
+
+    /**
+     * @see #writeToProto - allows subclasses to write additional info to the proto.
+     */
+    default void writeToProtoInternal(InputConsumerProto.Builder inputConsumerProto) {}
 }
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index b1b9396..9f7871a 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -35,6 +35,7 @@
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.systemui.shared.system.LatencyTrackerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
@@ -174,6 +175,9 @@
                 return;
             }
 
+            InteractionJankMonitorWrapper.begin(
+                    InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH, 2000 /* ms timout */);
+
             // Otherwise, start overview.
             mListener = mActivityInterface.createActivityInitListener(this::onActivityReady);
             mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 07f838b..49feef0 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -35,6 +35,8 @@
 import android.content.pm.ResolveInfo;
 import android.util.SparseIntArray;
 
+import com.android.launcher3.tracing.OverviewComponentObserverProto;
+import com.android.launcher3.tracing.TouchInteractionServiceProto;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.systemui.shared.system.PackageManagerWrapper;
 
@@ -262,4 +264,17 @@
         pw.println("  overviewIntent=" + mOverviewIntent);
         pw.println("  homeIntent=" + mCurrentHomeIntent);
     }
+
+    /**
+     * Used for winscope tracing, see launcher_trace.proto
+     * @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
+     * @param serviceProto The parent of this proto message.
+     */
+    public void writeToProto(TouchInteractionServiceProto.Builder serviceProto) {
+        OverviewComponentObserverProto.Builder overviewComponentObserver =
+                OverviewComponentObserverProto.newBuilder();
+        overviewComponentObserver.setOverviewActivityStarted(mActivityInterface.isStarted());
+        overviewComponentObserver.setOverviewActivityResumed(mActivityInterface.isResumed());
+        serviceProto.setOverviewComponentObvserver(overviewComponentObserver);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 7299c38..5520ef7 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -44,6 +44,7 @@
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PendingAnimation;
@@ -58,6 +59,7 @@
 import com.android.quickstep.views.TaskThumbnailView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 /**
@@ -135,6 +137,8 @@
             RemoteAnimationTargetCompat[] appTargets,
             RemoteAnimationTargetCompat[] wallpaperTargets, DepthController depthController,
             PendingAnimation out) {
+        boolean isQuickSwitch = v.isEndQuickswitchCuj();
+        v.setEndQuickswitchCuj(false);
 
         SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
         final RemoteAnimationTargets targets =
@@ -232,10 +236,19 @@
             });
         }
 
-        out.addListener(new AnimatorListenerAdapter() {
+        out.addListener(new AnimationSuccessListener() {
+            @Override
+            public void onAnimationSuccess(Animator animator) {
+                if (isQuickSwitch) {
+                    InteractionJankMonitorWrapper.end(
+                            InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+                }
+            }
+
             @Override
             public void onAnimationEnd(Animator animation) {
                 targets.release();
+                super.onAnimationEnd(animation);
             }
         });
 
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index d3c4f55..eebb0de 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -893,6 +893,12 @@
         TouchInteractionServiceProto.Builder serviceProto =
             TouchInteractionServiceProto.newBuilder();
         serviceProto.setServiceConnected(true);
+
+        if (mOverviewComponentObserver != null) {
+            mOverviewComponentObserver.writeToProto(serviceProto);
+        }
+        mConsumer.writeToProto(serviceProto);
+
         proto.setTouchInteractionService(serviceProto);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
index 67a15a7..8da2fd3 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
@@ -4,6 +4,7 @@
 
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.tracing.InputConsumerProto;
 import com.android.quickstep.InputConsumer;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
@@ -53,4 +54,9 @@
         mDelegate.onMotionEvent(event);
         event.recycle();
     }
+
+    @Override
+    public void writeToProtoInternal(InputConsumerProto.Builder inputConsumerProto) {
+        mDelegate.writeToProtoInternal(inputConsumerProto);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 35dbee9..82f489f 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -51,6 +51,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.tracing.InputConsumerProto;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.AbsSwipeUpHandler;
@@ -478,4 +479,11 @@
     public boolean allowInterceptByParent() {
         return !mPassedPilferInputSlop || mGestureState.hasState(STATE_OVERSCROLL_WINDOW_CREATED);
     }
+
+    @Override
+    public void writeToProtoInternal(InputConsumerProto.Builder inputConsumerProto) {
+        if (mInteractionHandler != null) {
+            mInteractionHandler.writeToProto(inputConsumerProto);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7a8e11d..65a445b 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -539,6 +539,9 @@
     @Override
     protected void onWindowVisibilityChanged(int visibility) {
         super.onWindowVisibilityChanged(visibility);
+        if (visibility == GONE && ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            finishRecentsAnimation(true /* toRecents */, null);
+        }
         updateTaskStackListenerState();
     }
 
@@ -1292,19 +1295,26 @@
     }
 
     public void showNextTask() {
-        TaskView runningTaskView = getRunningTaskView();
+        final TaskView runningTaskView = getRunningTaskView();
+        final TaskView targetTask;
+
         if (runningTaskView == null) {
             // Launch the first task
             if (getTaskViewCount() > 0) {
-                getTaskViewAt(0).launchTask(true);
+                targetTask = getTaskViewAt(0);
+            } else {
+                return;
             }
         } else {
-            if (getNextTaskView() != null) {
-                getNextTaskView().launchTask(true);
+            final TaskView nextTask = getNextTaskView();
+            if (nextTask != null) {
+                targetTask = nextTask;
             } else {
-                runningTaskView.launchTask(true);
+                targetTask = runningTaskView;
             }
         }
+        targetTask.setEndQuickswitchCuj(true);
+        targetTask.launchTask(true);
     }
 
     public void setRunningTaskIconScaledDown(boolean isScaledDown) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 686f878..54a793c 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -189,6 +189,8 @@
     private CancellableTask mThumbnailLoadRequest;
     private CancellableTask mIconLoadRequest;
 
+    private boolean mEndQuickswitchCuj;
+
     // Order in which the footers appear. Lower order appear below higher order.
     public static final int INDEX_DIGITAL_WELLBEING_TOAST = 0;
     private final FooterWrapper[] mFooters = new FooterWrapper[2];
@@ -807,6 +809,14 @@
         return false;
     }
 
+    public boolean isEndQuickswitchCuj() {
+        return mEndQuickswitchCuj;
+    }
+
+    public void setEndQuickswitchCuj(boolean endQuickswitchCuj) {
+        mEndQuickswitchCuj = endQuickswitchCuj;
+    }
+
     private static final class TaskOutlineProvider extends ViewOutlineProvider {
 
         private final int mMarginTop;