Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
index 7cf8201..c65fa5f 100644
--- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
+++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
@@ -19,6 +19,8 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
 import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
@@ -115,13 +117,19 @@
 
             PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration());
             RectF startingTaskRect = new RectF();
-            FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget,
-                    source.view, null /* thumbnail */,
-                    source.drawable, startingTaskRect);
+            final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget,
+                    source.view, null /* thumbnail */, source.drawable, startingTaskRect);
             floatingTaskView.setAlpha(1);
             floatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect,
                     false /* fadeWithThumbnail */, true /* isStagedTask */);
             controller.setFirstFloatingTaskView(floatingTaskView);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mTarget.getDragLayer().removeView(floatingTaskView);
+                    controller.resetState();
+                }
+            });
             anim.buildAnim().start();
         }
     }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 19ffd2a..3d8ffc4 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1204,7 +1204,6 @@
         final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
                 isFling, isCancel);
 
-        setClampScrollOffset(false);
         // Set the state, but don't notify until the animation completes
         mGestureState.setEndTarget(endTarget, false /* isAtomic */);
         mAnimationFactory.setEndTarget(endTarget);
@@ -1282,13 +1281,16 @@
 
         // Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
         // or resumeLastTask().
+        Runnable onPageTransitionEnd = () -> {
+            mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED);
+            setClampScrollOffset(false);
+        };
         if (mRecentsView != null) {
             ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent
                     .SET_ON_PAGE_TRANSITION_END_CALLBACK);
-            mRecentsView.setOnPageTransitionEndCallback(
-                    () -> mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED));
+            mRecentsView.setOnPageTransitionEndCallback(onPageTransitionEnd);
         } else {
-            mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED);
+            onPageTransitionEnd.run();
         }
 
         animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 0ef4597..0a155cb 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -342,6 +342,10 @@
                 return;
             }
 
+            if (mItemInfo == null) {
+                return;
+            }
+
             if (mItemInfo.container < 0 || appState == null) {
                 // Write log on the model thread so that logs do not go out of order
                 // (for eg: drop comes after drag)
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index e8a4b0a..e5c74dc 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -19,21 +19,39 @@
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Intent;
+import android.graphics.Rect;
+import android.graphics.RectF;
 import android.view.View;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.quickstep.views.FloatingTaskView;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 
 /** Handles when the stage split lands on the home screen. */
 public class SplitToWorkspaceController {
 
     private final Launcher mLauncher;
+    private final DeviceProfile mDP;
     private final SplitSelectStateController mController;
 
+    private final int mHalfDividerSize;
+
     public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) {
         mLauncher = launcher;
+        mDP = mLauncher.getDeviceProfile();
         mController = controller;
+
+        mHalfDividerSize = mLauncher.getResources().getDimensionPixelSize(
+                R.dimen.multi_window_task_divider_size) / 2;
     }
 
     /**
@@ -48,19 +66,74 @@
         }
         Object tag = view.getTag();
         Intent intent;
+        BitmapInfo bitmapInfo;
         if (tag instanceof WorkspaceItemInfo) {
             final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) tag;
             intent = workspaceItemInfo.intent;
+            bitmapInfo = workspaceItemInfo.bitmap;
         } else if (tag instanceof com.android.launcher3.model.data.AppInfo) {
             final com.android.launcher3.model.data.AppInfo appInfo =
                     (com.android.launcher3.model.data.AppInfo) tag;
             intent = appInfo.intent;
+            bitmapInfo = appInfo.bitmap;
         } else {
             return false;
         }
+
         mController.setSecondTask(intent);
-        mController.launchSplitTasks(aBoolean -> mLauncher.getDragLayer().removeView(
-                mController.getFirstFloatingTaskView()));
+
+        boolean isTablet = mLauncher.getDeviceProfile().isTablet;
+        SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet);
+        PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration());
+
+        Rect firstTaskStartingBounds = new Rect();
+        Rect firstTaskEndingBounds = new Rect();
+        RectF secondTaskStartingBounds = new RectF();
+        Rect secondTaskEndingBounds = new Rect();
+
+        RecentsView recentsView = mLauncher.getOverviewPanel();
+        recentsView.getPagedOrientationHandler().getFinalSplitPlaceholderBounds(mHalfDividerSize,
+                mDP, mController.getActiveSplitStagePosition(), firstTaskEndingBounds,
+                secondTaskEndingBounds);
+
+        FloatingTaskView firstFloatingTaskView = mController.getFirstFloatingTaskView();
+        firstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
+        firstFloatingTaskView.addConfirmAnimation(pendingAnimation,
+                new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
+                false /* fadeWithThumbnail */, true /* isStagedTask */);
+
+        FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher,
+                view, null /* thumbnail */, bitmapInfo.newIcon(mLauncher),
+                secondTaskStartingBounds);
+        secondFloatingTaskView.setAlpha(1);
+        secondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
+                secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
+
+        pendingAnimation.addListener(new AnimatorListenerAdapter() {
+            private boolean mIsCancelled = false;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mIsCancelled = true;
+                cleanUp();
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!mIsCancelled) {
+                    mController.launchSplitTasks(aBoolean -> cleanUp());
+                    InteractionJankMonitorWrapper.end(
+                            InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
+                }
+            }
+
+            private void cleanUp() {
+                mLauncher.getDragLayer().removeView(firstFloatingTaskView);
+                mLauncher.getDragLayer().removeView(secondFloatingTaskView);
+                mController.resetState();
+            }
+        });
+        pendingAnimation.buildAnim().start();
         return true;
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index b476c12..1515c5b 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -320,6 +320,7 @@
 
             // mIsRecentsRtl is the inverse of TaskView RTL.
             boolean isRtlEnabled = !mIsRecentsRtl;
+            mPositionHelper.setTaskbarInApp(mDp.isTaskbarPresentInApps);
             mPositionHelper.updateThumbnailMatrix(
                     mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(),
                     mDp.widthPx, mDp.heightPx, mDp.taskbarSize, mDp.isTablet,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index dc1b885..8b406ec 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -5072,15 +5072,15 @@
      * Returns how many pixels the page is offset on the currently laid out dominant axis.
      */
     public int getScrollOffset(int pageIndex) {
-        int unboundedOffset = getUnclampedScrollOffset(pageIndex);
+        int unclampedOffset = getUnclampedScrollOffset(pageIndex);
         if (!mShouldClampScrollOffset) {
-            return unboundedOffset;
+            return unclampedOffset;
         }
-        if (Math.abs(unboundedOffset) < mClampedScrollOffsetBound) {
+        if (Math.abs(unclampedOffset) < mClampedScrollOffsetBound) {
             return 0;
         }
-        return unboundedOffset
-                - Math.round(Math.signum(unboundedOffset) * mClampedScrollOffsetBound);
+        return unclampedOffset
+                - Math.round(Math.signum(unclampedOffset) * mClampedScrollOffsetBound);
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 904c944..ab1198a 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -464,6 +464,8 @@
     }
 
     private void updateThumbnailMatrix() {
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        mPreviewPositionHelper.setTaskbarInApp(dp.isTaskbarPresentInApps);
         mPreviewPositionHelper.setOrientationChanged(false);
         if (mBitmapShader != null && mThumbnailData != null) {
             mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
@@ -471,7 +473,6 @@
             int currentRotation = getTaskView().getRecentsView().getPagedViewOrientedState()
                     .getRecentsActivityRotation();
             boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-            DeviceProfile dp = mActivity.getDeviceProfile();
             mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
                     getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx,
                     dp.taskbarSize, dp.isTablet, currentRotation, isRtl);
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index 0c96539..7f58818 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -21,6 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.launcher3.DeviceProfileBaseTest
 import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
 import com.android.quickstep.views.TaskView.FullscreenDrawParams
 import com.android.systemui.shared.recents.model.ThumbnailData
 import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
@@ -104,6 +105,33 @@
     }
 
     @Test
+    fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromTopForTablets_splitPortrait() {
+        initializeVarsForTablet()
+        val dp = newDP()
+        val previewRect = Rect(0, 0, 100, 100)
+        val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
+        val canvasHeight = (dp.heightPx * TASK_SCALE / 2).roundToInt()
+        val currentRotation = 0
+        val isRtl = false
+        // portrait/vertical split apps
+        val dividerSize = 10
+        val splitBounds = SplitBounds(
+                Rect(0, 0, dp.widthPx, (dp.heightPx - dividerSize) / 2),
+                Rect(0, (dp.heightPx + dividerSize) / 2, dp.widthPx, dp.heightPx),
+                0 /*lefTopTaskId*/, 0 /*rightBottomTaskId*/)
+        mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_TOP_OR_LEFT)
+
+        mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth,
+                canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation,
+                isRtl)
+        params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
+                /* taskViewScale= */ 1.0f,  /* previewWidth= */ 0, dp, mPreviewPositionHelper)
+
+        assertThat(params.mCurrentDrawnInsets.bottom)
+                .isWithin(1f).of((0f))
+    }
+
+    @Test
     fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitLandscape() {
         initializeVarsForTablet(isLandscape = true)
         val dp = newDP()
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index d0d82d4..f8a871a 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -25,34 +25,5 @@
     android:focusable="false"
     android:saveEnabled="false">
 
-    <include
-        layout="@layout/all_apps_bottom_sheet_background"
-        android:visibility="gone" />
-
-    <include
-        layout="@layout/search_results_rv_layout"
-        android:visibility="gone" />
-
-    <include
-        layout="@layout/all_apps_rv_layout"
-        android:visibility="gone" />
-
-    <com.android.launcher3.allapps.FloatingHeaderView
-        android:id="@+id/all_apps_header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:clipToPadding="false"
-        android:paddingTop="@dimen/all_apps_header_top_padding"
-        android:paddingBottom="@dimen/all_apps_header_bottom_padding"
-        android:orientation="vertical" >
-
-        <include layout="@layout/floating_header_content" />
-
-        <include layout="@layout/all_apps_personal_work_tabs" />
-
-    </com.android.launcher3.allapps.FloatingHeaderView>
-
-    <include layout="@layout/search_container_all_apps" />
-
-    <include layout="@layout/all_apps_fast_scroller" />
+    <include layout="@layout/all_apps_content" />
 </com.android.launcher3.allapps.LauncherAllAppsContainerView>
\ No newline at end of file
diff --git a/res/layout/all_apps_content.xml b/res/layout/all_apps_content.xml
new file mode 100644
index 0000000..b33029f
--- /dev/null
+++ b/res/layout/all_apps_content.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2022 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.
+-->
+<!-- This file is used by multiple all_apps.xml. Layout consists of all contents
+     showed in all apps screen
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <include
+        layout="@layout/all_apps_bottom_sheet_background"
+        android:visibility="gone" />
+
+    <include
+        layout="@layout/search_results_rv_layout"
+        android:visibility="gone" />
+
+    <include
+        layout="@layout/all_apps_rv_layout"
+        android:visibility="gone" />
+
+    <com.android.launcher3.allapps.FloatingHeaderView
+        android:id="@+id/all_apps_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:clipToPadding="false"
+        android:paddingTop="@dimen/all_apps_header_top_padding"
+        android:paddingBottom="@dimen/all_apps_header_bottom_padding"
+        android:orientation="vertical" >
+
+        <include layout="@layout/floating_header_content" />
+
+        <include layout="@layout/all_apps_personal_work_tabs" />
+
+    </com.android.launcher3.allapps.FloatingHeaderView>
+
+    <include layout="@layout/search_container_all_apps" />
+
+    <include layout="@layout/all_apps_fast_scroller" />
+
+</merge>
\ No newline at end of file
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 3e1c0eb..88654b7 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -301,10 +301,6 @@
             "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", false,
             "Use local overrides for search request timeout");
 
-    public static final BooleanFlag ENABLE_RICH_ANSWER = new DeviceFlag(
-            "ENABLE_RICH_ANSWER", false,
-            "Enable rich answer new UI for web answer search results");
-
     public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(
             "CONTINUOUS_VIEW_TREE_CAPTURE", false, "Capture View tree every frame");
 
diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
index 57731d0..93329fa 100644
--- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
@@ -35,6 +35,8 @@
 import com.android.launcher3.tapl.HomeAppIconMenuItem;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 
 import org.junit.Test;
 
@@ -109,6 +111,7 @@
     }
 
     @Test
+    @ScreenRecord // b/260722220
     public void testShortcutIconWithTheme() throws Exception {
         setThemeEnabled(true);
         TaplTestsLauncher3.initialize(this);
@@ -128,6 +131,13 @@
     }
 
     private void verifyIconTheme(String title, ViewGroup parent, boolean isThemed) {
+        // Wait for Launcher model to be completed
+        try {
+            Executors.MODEL_EXECUTOR.submit(() -> { }).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
         // Find the app icon
         Queue<View> viewQueue = new ArrayDeque<>();
         viewQueue.add(parent);