Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index c165750..9bcc804 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -77,13 +77,14 @@
 
     /**
      * Creates an animation to animate the taskbar for the given state (but does not start it).
-     * Currently this animation just force stashes the taskbar in Overview.
      */
     public Animator createAnimToRecentsState(RecentsState toState, long duration) {
-        boolean useStashedLauncherState = toState.hasOverviewActions();
-        boolean stashedLauncherState =
-                useStashedLauncherState && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
-                        && toState == RecentsState.MODAL_TASK;
+        // Force stash the taskbar in overview modal state or when going home.
+        boolean useStashedLauncherState =
+                toState.hasOverviewActions() || toState == RecentsState.HOME;
+        boolean stashedLauncherState = useStashedLauncherState && (
+                (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get() && toState == RecentsState.MODAL_TASK)
+                        || toState == RecentsState.HOME);
         TaskbarStashController stashController = mControllers.taskbarStashController;
         // Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected.
         // For all other states, just use the current stashed-in-app setting (e.g. if long clicked).
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 1b05fd2..84f6b55 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -33,6 +33,7 @@
 
 import com.android.launcher3.R;
 import com.android.launcher3.testing.shared.ResourceUtils;
+import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.DisplayController.Info;
 import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.window.CachedDisplayInfo;
@@ -119,7 +120,7 @@
     }
 
     void setNavigationMode(NavigationMode newMode, Info info, Resources newRes) {
-        if (DEBUG) {
+        if (enableLog()) {
             Log.d(TAG, "setNavigationMode new: " + newMode + " oldMode: " + mMode + " " + this);
         }
         if (mMode == newMode) {
@@ -206,7 +207,7 @@
      * Ok to call multiple times.
      */
     private void resetSwipeRegions(Info region) {
-        if (DEBUG) {
+        if (enableLog()) {
             Log.d(TAG, "clearing all regions except rotation: " + mCachedDisplayInfo.rotation);
         }
 
@@ -230,9 +231,11 @@
     }
 
     private OrientationRectF createRegionForDisplay(Info display) {
-        if (DEBUG) {
+        if (enableLog()) {
             Log.d(TAG, "creating rotation region for: " + mCachedDisplayInfo.rotation
-            + " with mode: " + mMode + " displayRotation: " + display.rotation);
+            + " with mode: " + mMode + " displayRotation: " + display.rotation +
+                    " displaySize: " + display.currentSize +
+                    " navBarHeight: " + mNavBarGesturalHeight);
         }
 
         Point size = display.currentSize;
@@ -296,9 +299,8 @@
     }
 
     boolean touchInValidSwipeRegions(float x, float y) {
-        if (DEBUG) {
-            Log.d(TAG, "touchInValidSwipeRegions " + x + "," + y + " in "
-                    + mLastRectTouched + " this: " + this);
+        if (enableLog()) {
+            Log.d(TAG, "touchInValidSwipeRegions " + x + "," + y + " in " + mLastRectTouched);
         }
         if (mLastRectTouched != null) {
             return mLastRectTouched.contains(x, y);
@@ -357,11 +359,17 @@
             }
             case ACTION_POINTER_DOWN:
             case ACTION_DOWN: {
+                if (enableLog()) {
+                    Log.d(TAG, "ACTION_DOWN mLastRectTouched: " + mLastRectTouched);
+                }
                 if (mLastRectTouched != null) {
                     return;
                 }
 
                 for (OrientationRectF rect : mSwipeTouchRegions.values()) {
+                    if (enableLog()) {
+                        Log.d(TAG, "ACTION_DOWN rect: " + rect);
+                    }
                     if (rect == null) {
                         continue;
                     }
@@ -376,7 +384,7 @@
                             mQuickStepStartingRotation = mLastRectTouched.getRotation();
                             resetSwipeRegions();
                         }
-                        if (DEBUG) {
+                        if (enableLog()) {
                             Log.d(TAG, "set active region: " + rect);
                         }
                         return;
@@ -387,6 +395,10 @@
         }
     }
 
+    private boolean enableLog() {
+        return DEBUG || TestProtocol.sDebugTracing;
+    }
+
     public void dump(PrintWriter pw) {
         pw.println("OrientationTouchTransformerState: ");
         pw.println("  currentActiveRotation=" + getCurrentActiveRotation());
diff --git a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
index 2a8bfa2..ad11b7e 100644
--- a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
@@ -86,6 +86,7 @@
     }
 
     private void clearRegisteredViews() {
+        restoreClippings();
         mMoveFromCenterAnimation.clearRegisteredViews();
 
         mOriginalClipChildren.clear();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 4ba0276..7c0cc2d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -147,6 +147,8 @@
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.touch.OverScroll;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DynamicResource;
@@ -4497,6 +4499,7 @@
      * Attempts to initiate split with an existing taskView, if one exists
      */
     public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
+        TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "enterSplitSelect");
         mSplitSelectSource = splitSelectSource;
         mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
         mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
new file mode 100644
index 0000000..d3fbe93
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+package com.android.quickstep;
+
+import android.content.Intent;
+
+import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.launcher3.util.rule.TestStabilityRule;
+import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
+
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TaplTestsSplitscreen extends AbstractQuickStepTest {
+    private static final String CALCULATOR_APP_NAME = "Calculator";
+    private static final String CALCULATOR_APP_PACKAGE =
+            resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        TaplTestsLauncher3.initialize(this);
+
+        mLauncher.getWorkspace()
+                .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
+                .switchToAllApps()
+                .getAppIcon(CALCULATOR_APP_NAME)
+                .dragToHotseat(0);
+
+        startAppFast(CALCULATOR_APP_PACKAGE);
+        if (mLauncher.isTablet()) {
+            mLauncher.enableBlockTimeout(true);
+            mLauncher.showTaskbarIfHidden();
+        }
+    }
+
+    @After
+    public void tearDown() {
+        if (mLauncher.isTablet()) {
+            mLauncher.enableBlockTimeout(false);
+        }
+    }
+
+    @Test
+    // TODO (b/270201357): When this test is proven stable, remove this TestStabilityRule and
+    // introduce into presubmit as well.
+    @TestStabilityRule.Stability(
+            flavors = TestStabilityRule.LOCAL | TestStabilityRule.PLATFORM_POSTSUBMIT)
+    @PortraitLandscape
+    @TaskbarModeSwitch
+    public void testSplitAppFromHomeWithItself() throws Exception {
+        Assume.assumeTrue(mLauncher.isTablet());
+
+        mLauncher.goHome()
+                .switchToAllApps()
+                .getAppIcon(CALCULATOR_APP_NAME)
+                .openMenu()
+                .getSplitScreenMenuItem()
+                .click();
+
+        mLauncher.getLaunchedAppState()
+                .getTaskbar()
+                .getAppIcon(CALCULATOR_APP_NAME)
+                .launchIntoSplitScreen();
+    }
+}
diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml
index 91897e9..0763d48 100644
--- a/res/layout/notification_content.xml
+++ b/res/layout/notification_content.xml
@@ -17,7 +17,7 @@
 <com.android.launcher3.notification.NotificationMainView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/notification_container_height"
     android:orientation="vertical">
 
     <!-- header -->
@@ -25,14 +25,14 @@
         android:id="@+id/header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingEnd="@dimen/notification_padding"
-        android:paddingStart="@dimen/notification_padding">
+        android:paddingEnd="@dimen/notification_padding_end"
+        android:paddingTop="@dimen/notification_padding_header_top"
+        android:paddingStart="@dimen/notification_header_padding_start">
         <TextView
             android:id="@+id/notification_text"
-            android:paddingTop="@dimen/notification_padding"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="bottom|start"
+            android:layout_gravity="top|start"
             android:text="@string/notifications_header"
             android:textColor="?android:attr/textColorPrimary"
             android:textSize="@dimen/notification_header_text_size"
@@ -42,7 +42,7 @@
             android:layout_width="@dimen/notification_circle_icon_size"
             android:layout_height="@dimen/notification_circle_icon_size"
             android:background="@drawable/notification_circle"
-            android:layout_gravity="bottom|end"
+            android:layout_gravity="top|end"
             android:gravity="center"
             android:textColor="?android:attr/textColorPrimary"
             android:textSize="@dimen/notification_header_count_text_size"
@@ -54,6 +54,8 @@
         android:id="@+id/main_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:paddingTop="@dimen/notification_padding_top"
+        android:paddingBottom="@dimen/notification_padding_bottom"
         android:focusable="true" >
 
         <LinearLayout
@@ -62,9 +64,7 @@
             android:layout_height="match_parent"
             android:gravity="center_vertical"
             android:orientation="vertical"
-            android:paddingTop="@dimen/notification_padding"
-            android:paddingBottom="@dimen/notification_padding"
-            android:paddingEnd="@dimen/notification_padding"
+            android:paddingEnd="@dimen/notification_padding_end"
             android:paddingStart="@dimen/notification_main_text_padding_start">
             <TextView
                 android:id="@+id/title"
@@ -91,9 +91,8 @@
             android:id="@+id/popup_item_icon"
             android:layout_width="@dimen/notification_icon_size"
             android:layout_height="@dimen/notification_icon_size"
-            android:layout_gravity="start"
-            android:layout_marginTop="@dimen/notification_padding"
-            android:layout_marginStart="@dimen/notification_icon_padding" />
+            android:layout_gravity="start|center_vertical"
+            android:layout_marginStart="@dimen/notification_icon_padding_start"/>
 
     </FrameLayout>
 </com.android.launcher3.notification.NotificationMainView>
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml
index 5a81f70..92522aa 100644
--- a/res/layout/system_shortcut_icon_only.xml
+++ b/res/layout/system_shortcut_icon_only.xml
@@ -18,8 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
     android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
-    android:background="?android:attr/selectableItemBackgroundBorderless"
     android:tint="?attr/iconOnlyShortcutColor"
     android:tintMode="src_in"
     android:padding="@dimen/system_shortcut_header_icon_padding"
-    android:theme="@style/PopupItem" />
+    android:theme="@style/PopupItemIconOnly" />
diff --git a/res/layout/system_shortcut_icon_only_end.xml b/res/layout/system_shortcut_icon_only_end.xml
new file mode 100644
index 0000000..b5b5f02
--- /dev/null
+++ b/res/layout/system_shortcut_icon_only_end.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
+    android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
+    android:tint="?attr/iconOnlyShortcutColor"
+    android:tintMode="src_in"
+    android:padding="@dimen/system_shortcut_header_icon_padding"
+    android:paddingStart="@dimen/system_shortcut_header_icon_padding_inner"
+    android:paddingEnd="@dimen/system_shortcut_header_icon_padding_outer"
+    android:theme="@style/PopupItemIconOnly" />
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icon_only_start.xml b/res/layout/system_shortcut_icon_only_start.xml
new file mode 100644
index 0000000..33a6b17
--- /dev/null
+++ b/res/layout/system_shortcut_icon_only_start.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
+    android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
+    android:tint="?attr/iconOnlyShortcutColor"
+    android:tintMode="src_in"
+    android:padding="@dimen/system_shortcut_header_icon_padding"
+    android:paddingStart="@dimen/system_shortcut_header_icon_padding_outer"
+    android:paddingEnd="@dimen/system_shortcut_header_icon_padding_inner"
+    android:theme="@style/PopupItemIconOnly" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index aa84d2b..21f614f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -281,7 +281,7 @@
     <dimen name="deep_shortcuts_elevation">2dp</dimen>
     <dimen name="bg_popup_padding">2dp</dimen>
     <dimen name="bg_popup_item_width">216dp</dimen>
-    <dimen name="bg_popup_item_height">56dp</dimen>
+    <dimen name="bg_popup_item_height">52dp</dimen>
     <dimen name="bg_popup_item_vertical_padding">12dp</dimen>
     <dimen name="pre_drag_view_scale">6dp</dimen>
     <!-- an icon with shortcuts must be dragged this far before the container is removed. -->
@@ -290,10 +290,10 @@
     <dimen name="popup_margin">2dp</dimen>
     <dimen name="popup_single_item_radius">100dp</dimen>
     <dimen name="popup_smaller_radius">4dp</dimen>
-    <dimen name="deep_shortcut_drawable_padding">12dp</dimen>
+    <dimen name="deep_shortcut_drawable_padding">16dp</dimen>
     <dimen name="deep_shortcut_drag_handle_size">16dp</dimen>
     <dimen name="popup_padding_start">10dp</dimen>
-    <dimen name="popup_padding_end">16dp</dimen>
+    <dimen name="popup_padding_end">14dp</dimen>
     <dimen name="popup_vertical_padding">4dp</dimen>
     <dimen name="popup_arrow_width">12dp</dimen>
     <dimen name="popup_arrow_height">10dp</dimen>
@@ -301,32 +301,40 @@
     <!-- popup_padding_start + deep_shortcut_icon_size / 2 -->
     <dimen name="popup_arrow_horizontal_center_offset">26dp</dimen>
     <dimen name="popup_arrow_corner_radius">2dp</dimen>
-    <!-- popup_padding_start + deep_shortcut_icon_size + 10dp -->
-    <dimen name="deep_shortcuts_text_padding_start">52dp</dimen>
+    <!-- popup_padding_start + deep_shortcut_icon_size + 12dp -->
+    <dimen name="deep_shortcuts_text_padding_start">54dp</dimen>
     <dimen name="system_shortcut_icon_size">20dp</dimen>
     <!-- popup_arrow_horizontal_center_offset - system_shortcut_icon_size / 2 -->
     <dimen name="system_shortcut_margin_start">16dp</dimen>
-    <dimen name="system_shortcut_header_height">56dp</dimen>
+    <dimen name="system_shortcut_header_height">52dp</dimen>
     <dimen name="system_shortcut_header_icon_touch_size">48dp</dimen>
     <!-- (system_shortcut_header_icon_touch_size - system_shortcut_icon_size) / 2 -->
     <dimen name="system_shortcut_header_icon_padding">14dp</dimen>
+    <!-- side of start/end icon near to container edge -->
+    <dimen name="system_shortcut_header_icon_padding_outer">16dp</dimen>
+    <!-- side of start/end icon far from container edge -->
+    <dimen name="system_shortcut_header_icon_padding_inner">12dp</dimen>
+
 
     <!-- Notifications -->
     <dimen name="bg_round_rect_radius">8dp</dimen>
+    <dimen name="notification_container_height">104dp</dimen>
     <dimen name="notification_max_trans">8dp</dimen>
     <dimen name="notification_space">8dp</dimen>
-    <dimen name="notification_padding">16dp</dimen>
-    <dimen name="notification_padding_top">18dp</dimen>
+    <dimen name="notification_padding_end">16dp</dimen>
+    <dimen name="notification_padding_bottom">12dp</dimen>
+    <dimen name="notification_padding_top">12dp</dimen>
+    <dimen name="notification_padding_header_top">16dp</dimen>
+    <dimen name="notification_header_padding_start">14dp</dimen>
     <dimen name="notification_header_text_size">14sp</dimen>
     <dimen name="notification_header_count_text_size">12sp</dimen>
     <dimen name="notification_main_title_size">14sp</dimen>
     <dimen name="notification_main_text_size">14sp</dimen>
     <dimen name="notification_circle_icon_size">24dp</dimen>
     <dimen name="notification_icon_size">32dp</dimen>
-    <!-- Space between edge and icon and icon and text -->
-    <dimen name="notification_icon_padding">12dp</dimen>
+    <dimen name="notification_icon_padding_start">10dp</dimen>
     <!-- notification_icon_padding + notification_icon_size + notification_icon_padding -->
-    <dimen name="notification_main_text_padding_start">56dp</dimen>
+    <dimen name="notification_main_text_padding_start">54dp</dimen>
     <dimen name="horizontal_ellipsis_size">18dp</dimen>
 
     <!-- Overview -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 65d215f..5dc4f0a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -249,6 +249,11 @@
         <item name="android:colorControlHighlight">?attr/popupColorTertiary</item>
     </style>
 
+    <style name="PopupItemIconOnly">
+        <item name="android:colorControlHighlight">?attr/popupColorTertiary</item>
+        <item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
+    </style>
+
     <!-- Drop targets -->
     <style name="DropTargetButtonBase" parent="@android:style/TextAppearance.DeviceDefault.Medium">
         <item name="android:drawablePadding">@dimen/drop_target_button_drawable_padding</item>
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 43ca2a6..a7265a7 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -264,14 +264,7 @@
                     shortcuts.get(0), false);
             return;
         }
-        mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
-        for (int i = 0; i < shortcuts.size(); i++) {
-            initializeSystemShortcut(
-                    R.layout.system_shortcut_icon_only,
-                    mSystemShortcutContainer,
-                    shortcuts.get(i),
-                    i < shortcuts.size() - 1);
-        }
+        addSystemShortcutsIconsOnly(shortcuts);
     }
 
     @TargetApi(Build.VERSION_CODES.P)
@@ -404,9 +397,7 @@
         List<SystemShortcut> nonWidgetSystemShortcuts =
                 getNonWidgetSystemShortcuts(systemShortcuts);
         // If total shortcuts over threshold, collapse system shortcuts to single row
-        addSystemShortcutsMaterialU(nonWidgetSystemShortcuts,
-                R.layout.system_shortcut_icons_container_material_u,
-                R.layout.system_shortcut_icon_only);
+        addSystemShortcutsIconsOnly(nonWidgetSystemShortcuts);
         // May need to recalculate row width
         mContainerWidth = Math.max(mContainerWidth,
                 nonWidgetSystemShortcuts.size() * getResources()
@@ -473,6 +464,33 @@
         }
     }
 
+    private void addSystemShortcutsIconsOnly(List<SystemShortcut> systemShortcuts) {
+        if (systemShortcuts.size() == 0) {
+            return;
+        }
+
+        mSystemShortcutContainer = ENABLE_MATERIAL_U_POPUP.get()
+                ? inflateAndAdd(R.layout.system_shortcut_icons_container_material_u, this)
+                : inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
+
+        for (int i = 0; i < systemShortcuts.size(); i++) {
+            @LayoutRes int shortcutIconLayout = R.layout.system_shortcut_icon_only;
+            boolean shouldAppendSpacer = true;
+
+            if (i == 0) {
+                shortcutIconLayout = R.layout.system_shortcut_icon_only_start;
+            } else if (i == systemShortcuts.size() - 1) {
+                shortcutIconLayout = R.layout.system_shortcut_icon_only_end;
+                shouldAppendSpacer = false;
+            }
+            initializeSystemShortcut(
+                    shortcutIconLayout,
+                    mSystemShortcutContainer,
+                    systemShortcuts.get(i),
+                    shouldAppendSpacer);
+        }
+    }
+
     /**
      * Inflates and adds [deepShortcutCount] number of DeepShortcutView for the  to a new container
      * @param deepShortcutCount number of DeepShortcutView instances to add
@@ -552,13 +570,13 @@
      * @param resId Resource id to use for SystemShortcut View.
      * @param container ViewGroup to add the shortcut View to as a parent
      * @param info The SystemShortcut instance to create a View for.
-     * @param shouldAddSpacer If True, will add a spacer after the shortcut, when showing the
+     * @param shouldAppendSpacer If True, will add a spacer after the shortcut, when showing the
      *                        SystemShortcut as an icon only. Used to space the shortcut icons
      *                        evenly.
      * @return The view inflated for the SystemShortcut
      */
     protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info,
-            boolean shouldAddSpacer) {
+            boolean shouldAppendSpacer) {
         View view = inflateAndAdd(resId, container);
         if (view instanceof DeepShortcutView) {
             // System shortcut takes entire row with icon and text
@@ -567,7 +585,7 @@
         } else if (view instanceof ImageView) {
             // System shortcut is just an icon
             info.setIconAndContentDescriptionFor((ImageView) view);
-            if (shouldAddSpacer) inflateAndAdd(R.layout.system_shortcut_spacer, container);
+            if (shouldAppendSpacer) inflateAndAdd(R.layout.system_shortcut_spacer, container);
             view.setTooltipText(view.getContentDescription());
         }
         view.setTag(info);
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 82d9630..667290f 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -54,5 +54,14 @@
         return createMenuItem(menuItem);
     }
 
+    /**
+     * Returns a menu item that matches the text "Split screen". Fails if it doesn't exist.
+     */
+    public SplitScreenMenuItem getSplitScreenMenuItem() {
+        final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
+                AppIcon.getAppIconSelector("Split screen", mLauncher));
+        return new SplitScreenMenuItem(mLauncher, menuItem);
+    }
+
     protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 3dcb437..48e327f 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -76,6 +76,27 @@
         }
     }
 
+    /**
+     * Clicks a launcher object to initiate splitscreen, where the selected app will be one of two
+     * apps running on the screen. Should be called when Launcher is in a "split staging" state
+     * and is waiting for the user's selection of a second app. Expects a SPLIT_START_EVENT to be
+     * fired when the click is executed.
+     */
+    public LaunchedAppState launchIntoSplitScreen() {
+        try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+                "want to launch split tasks from " + launchableType())) {
+            LauncherInstrumentation.log("Launchable.launch before click "
+                    + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+
+            mLauncher.clickLauncherObject(mObject);
+
+            try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
+                return new LaunchedAppState(mLauncher);
+            }
+        }
+    }
+
     protected LaunchedAppState assertAppLaunched(BySelector selector) {
         mLauncher.assertTrue(
                 "App didn't start: (" + selector + ")",
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index adc993d..90f3d13 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -37,10 +37,9 @@
 public final class OverviewTask {
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
 
-    static final Pattern TASK_START_EVENT =
-            Pattern.compile("startActivityFromRecentsAsync");
-    static final Pattern SPLIT_START_EVENT =
-            Pattern.compile("launchSplitTasks");
+    static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
+    static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
+    static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
     private final LauncherInstrumentation mLauncher;
     private final UiObject2 mTask;
     private final BaseOverview mOverview;
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
new file mode 100644
index 0000000..47cf20b
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package com.android.launcher3.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+import com.android.launcher3.testing.shared.TestProtocol;
+
+/**
+ * A class representing the "Split screen" menu item in the app long-press menu. Used for TAPL
+ * testing in a similar way as other menu items {@link AppIconMenuItem}, but unlike AppIconMenuItem,
+ * the split screen command does not trigger an app launch. Instead, it causes Launcher to shift to
+ * a different state (OverviewSplitSelect).
+ */
+public final class SplitScreenMenuItem {
+    private final LauncherInstrumentation mLauncher;
+    private final UiObject2 mObject;
+
+    SplitScreenMenuItem(LauncherInstrumentation launcher, UiObject2 object) {
+        mLauncher = launcher;
+        mObject = object;
+    }
+
+    /**
+     * Executes a click command on this menu item. Expects a SPLIT_SELECT_EVENT to be fired.
+     */
+    public void click() {
+        try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+                "want to enter split select from app long-press menu")) {
+            LauncherInstrumentation.log("clicking on split screen menu item "
+                    + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+
+            mLauncher.clickLauncherObject(mObject);
+
+            try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_SELECT_EVENT);
+                mLauncher.waitForLauncherObject("split_placeholder");
+            }
+        }
+    }
+}