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");
+ }
+ }
+ }
+}