Merge "Use widget picker color surface for WidgetsBottomSheet" into sc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index fe81b4c..fb47b0a 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -125,6 +125,22 @@
   // Folder's label is empty(i.e., title == "").
   // Not eligible for auto-labeling.
   EMPTY_LABEL = 12;
+
+  ALL_APPS_SEARCH_RESULT_APPLICATION = 13;
+  ALL_APPS_SEARCH_RESULT_SHORTCUT = 14;
+  ALL_APPS_SEARCH_RESULT_PEOPLE = 15;
+  ALL_APPS_SEARCH_RESULT_ACTION = 16;
+  ALL_APPS_SEARCH_RESULT_SETTING = 17;
+  ALL_APPS_SEARCH_RESULT_SCREENSHOT = 18;
+  ALL_APPS_SEARCH_RESULT_SLICE = 19;
+  ALL_APPS_SEARCH_RESULT_WIDGETS = 20;
+  ALL_APPS_SEARCH_RESULT_PLAY = 21;
+  ALL_APPS_SEARCH_RESULT_SUGGEST = 22;
+  ALL_APPS_SEARCH_RESULT_ASSISTANT = 23;
+  ALL_APPS_SEARCH_RESULT_CHROMETAB = 24;
+  ALL_APPS_SEARCH_RESULT_NAVVYSITE = 25;
+  ALL_APPS_SEARCH_RESULT_TIPS = 26;
+  ALL_APPS_SEARCH_RESULT_PEOPLE_TILE = 27;
 }
 
 // Main app icons
diff --git a/quickstep/res/layout/task_menu.xml b/quickstep/res/layout/task_menu.xml
index 3916ff9..a219bca 100644
--- a/quickstep/res/layout/task_menu.xml
+++ b/quickstep/res/layout/task_menu.xml
@@ -16,7 +16,7 @@
 -->
 <com.android.quickstep.views.TaskMenuView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:animateLayoutChanges="true"
     android:background="@drawable/task_menu_bg"
@@ -35,12 +35,10 @@
 
     <LinearLayout
         android:id="@+id/menu_option_layout"
-        style="@style/TaskMenu"
-        android:divider="@drawable/all_apps_divider"
-        android:showDividers="beginning"
-        android:paddingStart="@dimen/task_card_menu_horizontal_padding"
-        android:paddingEnd="@dimen/task_card_menu_horizontal_padding"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:divider="@drawable/all_apps_divider"
+        android:showDividers="beginning" />
 
 </com.android.quickstep.views.TaskMenuView>
\ No newline at end of file
diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml
index 102ae9b..a7d6e89 100644
--- a/quickstep/res/layout/task_view_menu_option.xml
+++ b/quickstep/res/layout/task_view_menu_option.xml
@@ -16,9 +16,8 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/TaskMenu.Option"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center"
     android:orientation="vertical"
     android:paddingTop="@dimen/task_card_menu_option_vertical_padding"
     android:paddingBottom="@dimen/task_card_menu_option_vertical_padding"
@@ -29,22 +28,19 @@
       android:id="@+id/icon"
       android:layout_width="@dimen/system_shortcut_icon_size"
       android:layout_height="@dimen/system_shortcut_icon_size"
-      android:layout_marginTop="@dimen/system_shortcut_header_icon_padding"
-      android:layout_marginBottom="@dimen/deep_shortcut_drawable_padding"
+      android:layout_marginStart="@dimen/task_menu_option_start_margin"
       android:layout_gravity="center_horizontal"
       android:backgroundTint="?android:attr/textColorTertiary"/>
 
     <TextView
         style="@style/BaseIcon"
         android:id="@+id/text"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingBottom="@dimen/popup_padding_end"
+        android:layout_marginStart="@dimen/task_menu_option_start_margin"
         android:textSize="12sp"
         android:textColor="?android:attr/textColorPrimary"
         android:fontFamily="sans-serif"
-        android:gravity="center_horizontal"
-        android:layout_gravity="center_horizontal"
         android:focusable="false" />
 
 </LinearLayout>
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index 7cb01f6..668aea2 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -15,7 +15,5 @@
      limitations under the License.
 -->
 <resources>
-    <dimen name="task_card_menu_horizontal_padding">24dp</dimen>
-
     <dimen name="overview_task_margin">8dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/quickstep/res/values-land/styles.xml b/quickstep/res/values-land/styles.xml
deleted file mode 100644
index 0824b4f..0000000
--- a/quickstep/res/values-land/styles.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2018 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>
-    <!-- Task Menu layout styles. -->
-    <style name="TaskMenu">
-        <item name="android:orientation">horizontal</item>
-    </style>
-
-    <!-- Task Menu Option layout styles. -->
-    <style name="TaskMenu.Option">
-        <item name="android:layout_width">0dp</item>
-        <item name="android:layout_weight">1</item>
-    </style>
-</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 99be502..9c0a083 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -67,7 +67,7 @@
          in various configurations -->
     <dimen name="task_card_menu_option_vertical_padding">8dp</dimen>
     <dimen name="task_card_menu_shadow_height">3dp</dimen>
-    <dimen name="task_card_menu_horizontal_padding">0dp</dimen>
+    <dimen name="task_menu_option_start_margin">12dp</dimen>
     <!-- Copied from framework resource:
        docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
     <dimen name="multi_window_task_divider_size">10dp</dimen>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 82a91a7..7c7d20a 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -15,16 +15,6 @@
      limitations under the License.
 -->
 <resources>
-    <!-- Task Menu layout styles. -->
-    <style name="TaskMenu">
-        <item name="android:orientation">vertical</item>
-    </style>
-
-    <!-- Task Menu Option layout styles. -->
-    <style name="TaskMenu.Option">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">wrap_content</item>
-    </style>
 
     <style name="TextAppearance.GestureTutorial"
         parent="android:TextAppearance.Material.Body1" />
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 9c79c32..61803aa 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -150,6 +150,9 @@
     protected Runnable mGestureEndCallback;
     protected MultiStateCallback mStateCallback;
     protected boolean mCanceled;
+    // One time flag set when onConsumerAboutToBeSwitched() is called, indicating that certain
+    // shared animations should not be canceled when this handler is invalidated
+    private boolean mConsumerIsSwitching;
     private boolean mRecentsViewScrollLinked = false;
 
     private static int getFlagForIndex(int index, String name) {
@@ -1002,7 +1005,14 @@
         animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
     }
 
-    private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
+    private int getLogGestureTaskIndex(@Nullable TaskView targetTask) {
+        return mRecentsView == null || targetTask == null
+                ? LOG_NO_OP_PAGE_INDEX
+                : mRecentsView.indexOfChild(targetTask);
+    }
+
+    private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask,
+            int pageIndex) {
         StatsLogManager.EventEnum event;
         switch (endTarget) {
             case HOME:
@@ -1031,9 +1041,6 @@
             // We probably never received an animation controller, skip logging.
             return;
         }
-        int pageIndex = endTarget == LAST_TASK
-                ? LOG_NO_OP_PAGE_INDEX
-                : mRecentsView.getNextPage();
         // TODO: set correct container using the pageIndex
         logger.log(event);
     }
@@ -1278,18 +1285,18 @@
     }
 
     public void onConsumerAboutToBeSwitched() {
+        mConsumerIsSwitching = true;
         if (mActivity != null) {
             // In the off chance that the gesture ends before Launcher is started, we should clear
             // the callback here so that it doesn't update with the wrong state
             mActivity.clearRunOnceOnStartCallback();
-            resetLauncherListeners();
         }
         if (mGestureState.getEndTarget() != null && !mGestureState.isRunningAnimationToLauncher()) {
             cancelCurrentAnimation();
         } else {
             mStateCallback.setStateOnUiThread(STATE_FINISH_WITH_NO_END);
-            reset();
         }
+        reset();
     }
 
     public boolean isCanceled() {
@@ -1300,13 +1307,14 @@
     private void resumeLastTask() {
         mRecentsAnimationController.finish(false /* toRecents */, null);
         ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
-        doLogGesture(LAST_TASK, null);
+        doLogGesture(LAST_TASK, null, getLogGestureTaskIndex(null));
         reset();
     }
 
     @UiThread
     private void startNewTask() {
         TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
+        int taskPageIndex = getLogGestureTaskIndex(taskToLaunch);
         startNewTask(success -> {
             if (!success) {
                 reset();
@@ -1315,7 +1323,7 @@
                 endLauncherTransitionController();
                 updateSysUiFlags(1 /* windowProgress == overview */);
             }
-            doLogGesture(NEW_TASK, taskToLaunch);
+            doLogGesture(NEW_TASK, taskToLaunch, taskPageIndex);
         });
     }
 
@@ -1349,32 +1357,38 @@
     }
 
     private void invalidateHandler() {
-        if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
-                || mGestureState.getEndTarget() != RECENTS) {
-            mInputConsumerProxy.destroy();
-            mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+        if (!mConsumerIsSwitching) {
+            if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
+                    || mGestureState.getEndTarget() != RECENTS) {
+                mInputConsumerProxy.destroy();
+                mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+            }
+            endRunningWindowAnim(false /* cancel */);
+
+            if (mGestureEndCallback != null) {
+                mGestureEndCallback.run();
+            }
         }
+
         mInputConsumerProxy.unregisterCallback();
-        endRunningWindowAnim(false /* cancel */);
-
-        if (mGestureEndCallback != null) {
-            mGestureEndCallback.run();
-        }
-
         mActivityInitListener.unregister();
         ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
         mTaskSnapshot = null;
         mHandler.post(() -> {
             // Defer clearing the activity since invalidation can happen over multiple callbacks
+            // ie. invalidateHandlerWithLauncher()
             mActivity = null;
+            mRecentsView = null;
         });
     }
 
     private void invalidateHandlerWithLauncher() {
-        endLauncherTransitionController();
+        if (!mConsumerIsSwitching) {
+            endLauncherTransitionController();
+            mRecentsView.onGestureAnimationEnd();
+        }
 
         mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
-        mRecentsView.onGestureAnimationEnd();
         resetLauncherListeners();
     }
 
@@ -1499,7 +1513,8 @@
                     () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
         }
         ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
-        doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
+        TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView();
+        doLogGesture(HOME, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
     }
 
     /**
@@ -1530,7 +1545,8 @@
         }
 
         SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
-        doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView());
+        TaskView taskToLaunch = mRecentsView.getCurrentPageTaskView();
+        doLogGesture(RECENTS, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
         reset();
     }
 
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 4560735..78da311 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -25,6 +25,7 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.RunnableList;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -43,6 +44,8 @@
 
     private boolean mUseLauncherSysBarFlags = false;
     private boolean mSplitScreenMinimized = false;
+    private boolean mFinishRequested = false;
+    private RunnableList mPendingFinishCallbacks = new RunnableList();
 
     public RecentsAnimationController(RecentsAnimationControllerCompat controller,
             boolean allowMinimizeSplitScreen,
@@ -132,14 +135,22 @@
 
     @UiThread
     public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
+        if (mFinishRequested) {
+            // If finishing, add to pending finish callbacks, otherwise, if finished, adding to the
+            // destroyed RunnableList will just trigger the callback to be called immediately
+            mPendingFinishCallbacks.add(callback);
+            return;
+        }
+
+        // Finish not yet requested
+        mFinishRequested = true;
         mOnFinishedListener.accept(this);
+        mPendingFinishCallbacks.add(callback);
         UI_HELPER_EXECUTOR.execute(() -> {
             mController.finish(toRecents, sendUserLeaveHint);
             InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
             InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
-            if (callback != null) {
-                MAIN_EXECUTOR.execute(callback);
-            }
+            MAIN_EXECUTOR.execute(mPendingFinishCallbacks::executeAllAndDestroy);
         });
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index f55cdac..32cd367 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -201,12 +201,13 @@
     }
 
     private void addMenuOption(SystemShortcut menuOption) {
-        ViewGroup menuOptionView = (ViewGroup) mActivity.getLayoutInflater().inflate(
+        LinearLayout menuOptionView = (LinearLayout) mActivity.getLayoutInflater().inflate(
                 R.layout.task_view_menu_option, this, false);
         menuOption.setIconAndLabelFor(
                 menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
         LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
-        mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp);
+        mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp,
+                menuOptionView, mActivity.getDeviceProfile());
         menuOptionView.setEnabled(menuOption.isEnabled());
         menuOptionView.setAlpha(menuOption.isEnabled() ? 1 : 0.5f);
         menuOptionView.setOnClickListener(view -> {
@@ -228,16 +229,15 @@
         mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
         Rect insets = mActivity.getDragLayer().getInsets();
         BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
+        // TODO(b/186583656) Move the entire menu to the center/make smaller than thumbnail width
         params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail());
         // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
         params.gravity = Gravity.LEFT;
         setLayoutParams(params);
         setScaleX(taskView.getScaleX());
         setScaleY(taskView.getScaleY());
-        boolean canActivityRotate = taskView.getRecentsView()
-            .mOrientationState.isRecentsActivityRotationAllowed();
-        mOptionLayout.setOrientation(orientationHandler
-                .getTaskMenuLayoutOrientation(canActivityRotate, mOptionLayout));
+        orientationHandler.setTaskMenuLayoutOrientation(
+                mActivity.getDeviceProfile(), mOptionLayout);
         setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0);
     }
 
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 9089a64..93d88c2 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -80,7 +80,8 @@
         <attr name="ambientShadowBlur" format="dimension" />
         <attr name="keyShadowColor" format="color" />
         <attr name="keyShadowBlur" format="dimension" />
-        <attr name="keyShadowOffset" format="dimension" />
+        <attr name="keyShadowOffsetX" format="dimension" />
+        <attr name="keyShadowOffsetY" format="dimension" />
     </declare-styleable>
 
     <!-- PagedView specific attributes. These attributes are used to customize
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8d46f1c..5ae4e3f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -42,8 +42,8 @@
         <item name="isWorkspaceDarkText">false</item>
         <item name="workspaceTextColor">@color/workspace_text_color_light</item>
         <item name="workspaceShadowColor">#B0000000</item>
-        <item name="workspaceAmbientShadowColor">#33000000</item>
-        <item name="workspaceKeyShadowColor">#44000000</item>
+        <item name="workspaceAmbientShadowColor">#00000000</item>
+        <item name="workspaceKeyShadowColor">#89000000</item>
         <item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
         <item name="widgetsTheme">@style/WidgetContainerTheme</item>
         <item name="folderDotColor">?android:attr/colorPrimary</item>
@@ -243,8 +243,9 @@
         <item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
         <item name="ambientShadowBlur">2.5dp</item>
         <item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
-        <item name="keyShadowBlur">1dp</item>
-        <item name="keyShadowOffset">.5dp</item>
+        <item name="keyShadowBlur">.5dp</item>
+        <item name="keyShadowOffsetX">.5dp</item>
+        <item name="keyShadowOffsetY">.5dp</item>
     </style>
 
     <!-- Theme for the popup container -->
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 3312915..a799b4a 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -65,6 +65,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.animation.Interpolator;
+import android.widget.LinearLayout;
 
 import androidx.core.graphics.ColorUtils;
 import androidx.core.os.BuildCompat;
@@ -752,6 +753,16 @@
                 ColorUtils.blendARGB(0, color, tintAmount));
     }
 
+    /**
+     * Sets start margin on the provided {@param view} to be {@param margin}.
+     * Assumes {@param view} is a child of {@link LinearLayout}
+     */
+    public static void setStartMarginForView(View view, int margin) {
+        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams();
+        lp.setMarginStart(margin);
+        view.setLayoutParams(lp);
+    }
+
     private static class FixedSizeEmptyDrawable extends ColorDrawable {
 
         private final int mSize;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 7d5ed60..bad8704 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -151,7 +151,7 @@
             "ENABLE_OVERVIEW_SHARE", false, "Show Share button in Overview Actions");
 
     public static final BooleanFlag ENABLE_OVERVIEW_SHARING_TO_PEOPLE = getDebugFlag(
-            "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", false,
+            "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", true,
             "Show indicators for content on Overview to share with top people. ");
 
     public static final BooleanFlag ENABLE_OVERVIEW_CONTENT_PUSH = getDebugFlag(
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 767fffe..5ddf84f 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -50,6 +50,8 @@
  */
 public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
 
+    private static final boolean DRAW_SHADOW = false;
+
     private static final int CONSUMPTION_ANIMATION_DURATION = 100;
 
     private final PorterDuffXfermode mShadowPorterDuffXfermode
@@ -163,13 +165,15 @@
         // Stroke width is 1dp
         mStrokeWidth = context.getResources().getDisplayMetrics().density;
 
-        float radius = getScaledRadius();
-        float shadowRadius = radius + mStrokeWidth;
-        int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
-        mShadowShader = new RadialGradient(0, 0, 1,
-                new int[] {shadowColor, Color.TRANSPARENT},
-                new float[] {radius / shadowRadius, 1},
-                Shader.TileMode.CLAMP);
+        if (DRAW_SHADOW) {
+            float radius = getScaledRadius();
+            float shadowRadius = radius + mStrokeWidth;
+            int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
+            mShadowShader = new RadialGradient(0, 0, 1,
+                    new int[]{shadowColor, Color.TRANSPARENT},
+                    new float[]{radius / shadowRadius, 1},
+                    Shader.TileMode.CLAMP);
+        }
 
         invalidate();
     }
@@ -239,6 +243,9 @@
     }
 
     public void drawShadow(Canvas canvas) {
+        if (!DRAW_SHADOW) {
+            return;
+        }
         if (mShadowShader == null) {
             return;
         }
@@ -277,6 +284,9 @@
     }
 
     public void fadeInBackgroundShadow() {
+        if (!DRAW_SHADOW) {
+            return;
+        }
         if (mShadowAnimator != null) {
             mShadowAnimator.cancel();
         }
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 05fd77d..e388965 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -366,7 +366,7 @@
         return itemBuilder.build();
     }
 
-    LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
+    protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
         LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
         itemBuilder.setIsWork(user != Process.myUserHandle());
         return itemBuilder;
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 2254ab3..2fd5efc 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -254,16 +254,21 @@
     }
 
     @Override
-    public int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate,
+    public void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile,
         LinearLayout taskMenuLayout) {
-        return LinearLayout.HORIZONTAL;
+        taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
     }
 
     @Override
-    public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
+    public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+            LinearLayout viewGroup, DeviceProfile deviceProfile) {
+        // Phone fake landscape
+        viewGroup.setOrientation(LinearLayout.VERTICAL);
         lp.width = 0;
         lp.height = WRAP_CONTENT;
         lp.weight = 1;
+        Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+        Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
     }
 
     /* ---------- The following are only used by TaskViewTouchHandler. ---------- */
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index c9149ff..6c2f17e 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -101,8 +101,9 @@
     float getTaskMenuX(float x, View thumbnailView, int overScroll);
     float getTaskMenuY(float y, View thumbnailView, int overScroll);
     int getTaskMenuWidth(View view);
-    int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate, LinearLayout taskMenuLayout);
-    void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp);
+    void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile, LinearLayout taskMenuLayout);
+    void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+            LinearLayout viewGroup, DeviceProfile deviceProfile);
     int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect);
     List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp);
     FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 31586e7..f6a6448 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -253,14 +253,34 @@
     }
 
     @Override
-    public int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate,
+    public void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile,
         LinearLayout taskMenuLayout) {
-        return canRecentsActivityRotate ? taskMenuLayout.getOrientation() : LinearLayout.VERTICAL;
+        if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+            // Phone landscape
+            taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
+        } else {
+            // Phone Portrait, LargeScreen Landscape/Portrait
+            taskMenuLayout.setOrientation(LinearLayout.VERTICAL);
+        }
     }
 
     @Override
-    public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
-        // no-op, defaults are fine
+    public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+            LinearLayout viewGroup, DeviceProfile deviceProfile) {
+        if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+            // Phone landscape
+            viewGroup.setOrientation(LinearLayout.VERTICAL);
+            lp.width = 0;
+            lp.weight = 1;
+            Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+            Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
+        } else {
+            // Phone Portrait, LargeScreen Landscape/Portrait
+            viewGroup.setOrientation(LinearLayout.HORIZONTAL);
+            lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;
+        }
+
+        lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
     }
 
     /* ---------- The following are only used by TaskViewTouchHandler. ---------- */
diff --git a/src/com/android/launcher3/util/RunnableList.java b/src/com/android/launcher3/util/RunnableList.java
index 55add14..644537b 100644
--- a/src/com/android/launcher3/util/RunnableList.java
+++ b/src/com/android/launcher3/util/RunnableList.java
@@ -29,6 +29,9 @@
      * Ads a runnable to this list
      */
     public void add(Runnable runnable) {
+        if (runnable == null) {
+            return;
+        }
         if (mDestroyed) {
             runnable.run();
             return;
diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
index d89e7f8..a309e6e 100644
--- a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
+++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
@@ -60,7 +60,7 @@
 
         // We enhance the shadow by drawing the shadow twice
         getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
-                setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha));
+                getTextShadowColor(mShadowInfo.ambientShadowColor, alpha));
 
         drawWithoutDot(canvas);
         canvas.save();
@@ -68,8 +68,11 @@
                 getScrollX() + getWidth(),
                 getScrollY() + getHeight());
 
-        getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
-                setColorAlphaBound(mShadowInfo.keyShadowColor, alpha));
+        getPaint().setShadowLayer(
+                mShadowInfo.keyShadowBlur,
+                mShadowInfo.keyShadowOffsetX,
+                mShadowInfo.keyShadowOffsetY,
+                getTextShadowColor(mShadowInfo.keyShadowColor, alpha));
         drawWithoutDot(canvas);
         canvas.restore();
 
@@ -81,7 +84,8 @@
         public final int ambientShadowColor;
 
         public final float keyShadowBlur;
-        public final float keyShadowOffset;
+        public final float keyShadowOffsetX;
+        public final float keyShadowOffsetY;
         public final int keyShadowColor;
 
         public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
@@ -89,11 +93,13 @@
             TypedArray a = c.obtainStyledAttributes(
                     attrs, R.styleable.ShadowInfo, defStyle, 0);
 
-            ambientShadowBlur = a.getDimension(R.styleable.ShadowInfo_ambientShadowBlur, 0);
+            ambientShadowBlur = a.getDimensionPixelSize(
+                    R.styleable.ShadowInfo_ambientShadowBlur, 0);
             ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
 
-            keyShadowBlur = a.getDimension(R.styleable.ShadowInfo_keyShadowBlur, 0);
-            keyShadowOffset = a.getDimension(R.styleable.ShadowInfo_keyShadowOffset, 0);
+            keyShadowBlur = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowBlur, 0);
+            keyShadowOffsetX = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetX, 0);
+            keyShadowOffsetY = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetY, 0);
             keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
             a.recycle();
         }
@@ -105,17 +111,26 @@
             if (textAlpha == 0 || (keyShadowAlpha == 0 && ambientShadowAlpha == 0)) {
                 textView.getPaint().clearShadowLayer();
                 return true;
-            } else if (ambientShadowAlpha > 0) {
+            } else if (ambientShadowAlpha > 0 && keyShadowAlpha == 0) {
                 textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
-                        setColorAlphaBound(ambientShadowColor, textAlpha));
+                        getTextShadowColor(ambientShadowColor, textAlpha));
                 return true;
-            } else if (keyShadowAlpha > 0) {
-                textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
-                        setColorAlphaBound(keyShadowColor, textAlpha));
+            } else if (keyShadowAlpha > 0 && ambientShadowAlpha == 0) {
+                textView.getPaint().setShadowLayer(
+                        keyShadowBlur,
+                        keyShadowOffsetX,
+                        keyShadowOffsetY,
+                        getTextShadowColor(keyShadowColor, textAlpha));
                 return true;
             } else {
                 return false;
             }
         }
     }
+
+    // Multiplies the alpha of shadowColor by textAlpha.
+    private static int getTextShadowColor(int shadowColor, int textAlpha) {
+        return setColorAlphaBound(shadowColor,
+                Math.round(Color.alpha(shadowColor) * textAlpha / 255f));
+    }
 }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 8f5d4dc..b4d4856 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -28,7 +28,6 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
@@ -473,10 +472,6 @@
         WidgetsRecommendationTableLayout table =
                 mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable;
         if (recommendedWidgets.size() > 0) {
-            // TODO(b/185508758): Revert the following log after debugging.
-            if (getHeaderViewHeight() == 0) {
-                Log.d(TAG, "Header view height is 0 when inflating recommended widgets");
-            }
             float maxTableHeight =
                     (mLauncher.getDeviceProfile().availableHeightPx - mTabsHeight
                             - getHeaderViewHeight()) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 2d3f1a0..62ef4ff 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -93,9 +93,6 @@
         mRecommendationTableMaxHeight = recommendationTableMaxHeight;
         RecommendationTableData data = fitRecommendedWidgetsToTableSpace(/* previewScale= */ 1f,
                 recommendedWidgets);
-        // TODO(b/185508758): Revert the following logs after debugging.
-        Log.d(TAG, "Recommended widgets section max height: " + recommendationTableMaxHeight);
-        Log.d(TAG, "Recommended widget down scale: " + data.mPreviewScale);
         bindData(data);
     }