Merge "Don't do full anomaly check after every gesture" into ub-launcher3-rvc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index f0ecba3..036fb02 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -25,7 +25,7 @@
     Application application = 1;
     Task task = 2;
     Shortcut shortcut = 3;
-    Widget widget = 4;    
+    Widget widget = 4;
   }
   // When used for launch event, stores the global predictive rank
   optional int32 rank = 5;
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 79b4002..908e1f4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -151,6 +151,7 @@
 
         return () -> {
             overview.setFreezeViewVisibility(false);
+            overview.setTranslationY(0);
             mLauncher.getStateManager().reapplyState();
         };
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/IconView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/IconView.java
index eb8da6e..7cc00b7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/IconView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/IconView.java
@@ -21,12 +21,12 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+
 import com.android.launcher3.FastBitmapDrawable;
 
 import java.util.ArrayList;
 
-import androidx.annotation.NonNull;
-
 /**
  * A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
  * when the drawable changes.
@@ -130,4 +130,14 @@
             mScaleListeners.remove(listener);
         }
     }
+
+    @Override
+    public void setAlpha(float alpha) {
+        super.setAlpha(alpha);
+        if (alpha > 0) {
+            setVisibility(VISIBLE);
+        } else {
+            setVisibility(INVISIBLE);
+        }
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 955cf5a..fae0df0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -638,7 +638,7 @@
             case MotionEvent.ACTION_DOWN:
                 // Touch down anywhere but the deadzone around the visible clear all button and
                 // between the task views will start home on touch up
-                if (!isHandlingTouch()) {
+                if (!isHandlingTouch() && !isModal()) {
                     if (mShowEmptyMessage) {
                         mTouchDownToStartHome = true;
                     } else {
@@ -666,7 +666,7 @@
     @Override
     protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
         // Enables swiping to the left or right only if the task overlay is not modal.
-        if (mTaskModalness == 0f) {
+        if (!isModal()) {
             super.determineScrollingStart(ev, touchSlopScale);
         }
     }
@@ -737,6 +737,10 @@
         updateEnabledOverlays();
     }
 
+    private boolean isModal() {
+        return mTaskModalness > 0;
+    }
+
     private void removeTasksViewsAndClearAllButton() {
         for (int i = getTaskViewCount() - 1; i >= 0; i--) {
             removeView(getTaskViewAt(i));
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index ac2200d..2d51732 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -57,11 +57,6 @@
     }
 
     @Override
-    public void log(LauncherEvent eventId, LauncherAtom.ItemInfo item) {
-        // Call StatsLog method
-    }
-
-    @Override
     public void verify() {
         if (!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS
                 && StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND
@@ -88,17 +83,17 @@
             ArrayList<LauncherAppWidgetInfo> appWidgets = (ArrayList) dataModel.appWidgets.clone();
 
             for (ItemInfo info : workspaceItems) {
-                LauncherAtom.ItemInfo atomInfo = info.buildProto(null, null);
+                LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
                 // call StatsLog method
             }
             for (FolderInfo fInfo : folders) {
                 for (ItemInfo info : fInfo.contents) {
-                    LauncherAtom.ItemInfo atomInfo = info.buildProto(null, fInfo);
+                    LauncherAtom.ItemInfo atomInfo = info.buildProto(fInfo);
                     // call StatsLog method
                 }
             }
             for (ItemInfo info : appWidgets) {
-                LauncherAtom.ItemInfo atomInfo = info.buildProto(null, null);
+                LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
                 // call StatsLog method
             }
         }
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index db69341..09fe64a 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -185,7 +185,7 @@
             getUserEventDispatcher().logAppLaunch(v, intent, user);
 
             getStatsLogManager().log(APP_LAUNCH_TAP, item == null ? null
-                    : item.buildProto(null, null));
+                    : item.buildProto(null));
             return true;
         } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index bbdadee..359190c 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1068,7 +1068,7 @@
     private int getSpringOverScroll(int amount) {
         if (mScroller.isSpringing()) {
             return amount < 0
-                    ? mScroller.getCurrPos()
+                    ? mScroller.getCurrPos() - mMinScroll
                     : Math.max(0, mScroller.getCurrPos() - mMaxScroll);
         } else {
             return 0;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 10c05d3..2111162 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -79,6 +79,8 @@
 import com.android.launcher3.graphics.DragPreviewProvider;
 import com.android.launcher3.graphics.PreloadIconDrawable;
 import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
 import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.FolderInfo;
@@ -409,6 +411,10 @@
 
         // Always enter the spring loaded mode
         mLauncher.getStateManager().goToState(SPRING_LOADED);
+        StatsLogManager.newInstance(getContext())
+                .log(
+                    LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED,
+                    dragObject.originalDragInfo.buildProto(null));
     }
 
     public void deferRemoveExtraEmptyScreen() {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 071c03d..ab556f2 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -230,6 +230,8 @@
                     hasAllAppsContent, setter, headerFade, allAppsFade);
         } else {
             setter.setViewAlpha(mPluginContent, hasAllAppsContent ? 1 : 0, allAppsFade);
+            setter.setViewAlpha(mAppsView.getContentView(), 0, allAppsFade);
+            setter.setViewAlpha(mAppsView.getScrollBar(), 0, allAppsFade);
         }
         mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
 
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 2829951..05dd473 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.logging;
 
 import android.content.Context;
+import android.util.Log;
 
 import com.android.launcher3.R;
 import com.android.launcher3.logger.LauncherAtom;
@@ -28,6 +29,8 @@
  */
 public class StatsLogManager implements ResourceBasedOverride {
 
+    private static final String TAG = "StatsLogManager";
+
     interface EventEnum {
         int getId();
     }
@@ -40,7 +43,9 @@
         @LauncherUiEvent(doc = "Task launched from overview using SWIPE DOWN")
         TASK_LAUNCH_SWIPE_DOWN(2),
         @LauncherUiEvent(doc = "TASK dismissed from overview using SWIPE UP")
-        TASK_DISMISS_SWIPE_UP(3);
+        TASK_DISMISS_SWIPE_UP(3),
+        @LauncherUiEvent(doc = "User dragged a launcher item")
+        LAUNCHER_ITEM_DRAG_STARTED(383);
         // ADD MORE
 
         private final int mId;
@@ -54,6 +59,13 @@
 
     protected LogStateProvider mStateProvider;
 
+    /**
+     * Creates a new instance of {@link StatsLogManager} based on provided context.
+     */
+    public static StatsLogManager newInstance(Context context) {
+        return newInstance(context, null);
+    }
+
     public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) {
         StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
                 context.getApplicationContext(), R.string.stats_log_manager_class);
@@ -65,7 +77,10 @@
     /**
      * Logs an event and accompanying {@link ItemInfo}
      */
-    public void log(LauncherEvent eventId, LauncherAtom.ItemInfo itemInfo) { }
+    public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) {
+        Log.d(TAG, String.format("%s\n%s", event.name(), itemInfo));
+        // Call StatsLog method
+    }
 
     /**
      * Logs snapshot, or impression of the current workspace.
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 7ee2090..561b4ed 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -18,6 +18,7 @@
 
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
@@ -123,6 +124,12 @@
      */
     public CharSequence contentDescription;
 
+    /**
+     * When the instance is created using {@link #copyFrom}, this field is used to keep track of
+     * original {@link ComponentName}.
+     */
+    private ComponentName mComponentName;
+
     public UserHandle user;
 
     public ItemInfo() {
@@ -145,6 +152,7 @@
         container = info.container;
         user = info.user;
         contentDescription = info.contentDescription;
+        mComponentName = info.getTargetComponent();
     }
 
     public Intent getIntent() {
@@ -153,12 +161,7 @@
 
     @Nullable
     public ComponentName getTargetComponent() {
-        Intent intent = getIntent();
-        if (intent != null) {
-            return intent.getComponent();
-        } else {
-            return null;
-        }
+        return Optional.ofNullable(getIntent()).map(Intent::getComponent).orElse(mComponentName);
     }
 
     public void writeToValues(ContentWriter writer) {
@@ -247,8 +250,7 @@
     /**
      * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
      */
-    public LauncherAtom.ItemInfo buildProto(Intent intent, FolderInfo fInfo) {
-
+    public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
         LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
         itemBuilder.setIsWork(user != Process.myUserHandle());
         Optional<ComponentName> nullableComponent = Optional.ofNullable(getTargetComponent());
@@ -270,7 +272,14 @@
                                 .orElse(LauncherAtom.Shortcut.newBuilder()));
                 break;
             case ITEM_TYPE_APPWIDGET:
-                setItemBuilder(itemBuilder);
+                itemBuilder
+                        .setWidget(nullableComponent
+                                .map(component -> LauncherAtom.Widget.newBuilder()
+                                        .setComponentName(component.flattenToShortString())
+                                        .setPackageName(component.getPackageName()))
+                                .orElse(LauncherAtom.Widget.newBuilder())
+                                .setSpanX(spanX)
+                                .setSpanY(spanY));
                 break;
             default:
                 break;
@@ -282,6 +291,7 @@
 
             switch (fInfo.container) {
                 case CONTAINER_HOTSEAT:
+                case CONTAINER_HOTSEAT_PREDICTION:
                     folderBuilder.setHotseat(LauncherAtom.HotseatContainer.newBuilder()
                             .setIndex(fInfo.screenId));
                     break;
@@ -295,6 +305,7 @@
         } else {
             switch (container) {
                 case CONTAINER_HOTSEAT:
+                case CONTAINER_HOTSEAT_PREDICTION:
                     itemBuilder.setContainerInfo(
                             ContainerInfo.newBuilder().setHotseat(
                                     LauncherAtom.HotseatContainer.newBuilder().setIndex(screenId)));
diff --git a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
index adb97dc..b0d19a6 100644
--- a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
@@ -21,6 +21,8 @@
 import android.content.Intent;
 import android.os.Process;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.AppWidgetResizeFrame;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherSettings;
@@ -142,6 +144,12 @@
         return appWidgetId <= CUSTOM_WIDGET_ID;
     }
 
+    @Nullable
+    @Override
+    public ComponentName getTargetComponent() {
+        return providerName;
+    }
+
     @Override
     public void onAddToDatabase(ContentWriter writer) {
         super.onAddToDatabase(writer);
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
index 478141a..1a8e11b 100644
--- a/src/com/android/launcher3/views/ClipIconView.java
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -101,7 +101,6 @@
     private @Nullable Drawable mForeground;
     private @Nullable Drawable mBackground;
 
-    private boolean mIsVerticalBarLayout = false;
     private boolean mIsAdaptiveIcon = false;
 
     private ValueAnimator mRevealAnimator;
@@ -145,7 +144,8 @@
     }
 
     void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
-            boolean isOpening, float scale, float minSize, LayoutParams parentLp) {
+            boolean isOpening, float scale, float minSize, LayoutParams parentLp,
+            boolean isVerticalBarLayout) {
         DeviceProfile dp = mLauncher.getDeviceProfile();
         float dX = mIsRtl
                 ? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
@@ -158,7 +158,7 @@
                 Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax,
                 LINEAR), 0, 1);
 
-        if (mIsVerticalBarLayout) {
+        if (isVerticalBarLayout) {
             mOutline.right = (int) (rect.width() / scale);
         } else {
             mOutline.bottom = (int) (rect.height() / scale);
@@ -183,16 +183,16 @@
                 mRevealAnimator.setCurrentFraction(shapeRevealProgress);
             }
 
-            float drawableScale = (mIsVerticalBarLayout ? mOutline.width() : mOutline.height())
+            float drawableScale = (isVerticalBarLayout ? mOutline.width() : mOutline.height())
                     / minSize;
-            setBackgroundDrawableBounds(drawableScale);
+            setBackgroundDrawableBounds(drawableScale, isVerticalBarLayout);
             if (isOpening) {
                 // Center align foreground
                 int height = mFinalDrawableBounds.height();
                 int width = mFinalDrawableBounds.width();
-                int diffY = mIsVerticalBarLayout ? 0
+                int diffY = isVerticalBarLayout ? 0
                         : (int) (((height * drawableScale) - height) / 2);
-                int diffX = mIsVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
+                int diffX = isVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
                         : 0;
                 sTmpRect.set(mFinalDrawableBounds);
                 sTmpRect.offset(diffX, diffY);
@@ -210,11 +210,11 @@
         invalidateOutline();
     }
 
-    private void setBackgroundDrawableBounds(float scale) {
+    private void setBackgroundDrawableBounds(float scale, boolean isVerticalBarLayout) {
         sTmpRect.set(mFinalDrawableBounds);
         Utilities.scaleRectAboutCenter(sTmpRect, scale);
         // Since the drawable is at the top of the view, we need to offset to keep it centered.
-        if (mIsVerticalBarLayout) {
+        if (isVerticalBarLayout) {
             sTmpRect.offsetTo((int) (mFinalDrawableBounds.left * scale), sTmpRect.top);
         } else {
             sTmpRect.offsetTo(sTmpRect.left, (int) (mFinalDrawableBounds.top * scale));
@@ -228,7 +228,8 @@
         }
     }
 
-    void setIcon(@Nullable Drawable drawable, int iconOffset, LayoutParams lp, boolean isOpening) {
+    void setIcon(@Nullable Drawable drawable, int iconOffset, LayoutParams lp, boolean isOpening,
+            boolean isVerticalBarLayout) {
         mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
         if (mIsAdaptiveIcon) {
             boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
@@ -264,7 +265,7 @@
             }
 
             float aspectRatio = mLauncher.getDeviceProfile().aspectRatio;
-            if (mIsVerticalBarLayout) {
+            if (isVerticalBarLayout) {
                 lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
             } else {
                 lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
@@ -285,7 +286,7 @@
                 bgDrawableStartScale = scale;
                 mOutline.set(0, 0, lp.width, lp.height);
             }
-            setBackgroundDrawableBounds(bgDrawableStartScale);
+            setBackgroundDrawableBounds(bgDrawableStartScale, isVerticalBarLayout);
             mEndRevealRect.set(0, 0, lp.width, lp.height);
             setOutlineProvider(new ViewOutlineProvider() {
                 @Override
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 6e21512..bd12e06 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -161,7 +161,7 @@
         float scale = Math.max(1f, Math.min(scaleX, scaleY));
 
         mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale,
-                minSize, lp);
+                minSize, lp, mIsVerticalBarLayout);
 
         setPivotX(0);
         setPivotY(0);
@@ -335,7 +335,7 @@
         final InsettableFrameLayout.LayoutParams lp =
                 (InsettableFrameLayout.LayoutParams) getLayoutParams();
         mBadge = badge;
-        mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening);
+        mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening, mIsVerticalBarLayout);
         if (drawable instanceof AdaptiveIconDrawable) {
             final int originalHeight = lp.height;
             final int originalWidth = lp.width;