diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index 96e39c4146..2f84ac904d 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -190,7 +190,7 @@ public interface TaskShortcutFactory { } if (options != null && ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId, - options)) { + options)) { final Runnable animStartedListener = () -> { // Hide the task view and wait for the window to be resized // TODO: Consider animating in launcher and do an in-place start activity @@ -216,12 +216,13 @@ public interface TaskShortcutFactory { AppTransitionAnimationSpecsFuture future = new AppTransitionAnimationSpecsFuture(mHandler) { - @Override - public List composeSpecs() { - return Collections.singletonList(new AppTransitionAnimationSpecCompat( - taskId, thumbnail, taskBounds)); - } - }; + @Override + public List composeSpecs() { + return Collections.singletonList( + new AppTransitionAnimationSpecCompat( + taskId, thumbnail, taskBounds)); + } + }; overridePendingAppTransitionMultiThumbFuture( future, animStartedListener, mHandler, true /* scaleUp */, taskKey.displayId); @@ -264,38 +265,35 @@ public interface TaskShortcutFactory { /** * Does NOT add split options in the following scenarios: - * * The taskView to add split options is already showing split screen tasks - * * There aren't at least 2 tasks in overview to show split options for - * * Split isn't supported by the task itself (non resizable activity) - * * We aren't currently in multi-window - * * The taskView to show split options for is the focused task AND we haven't started - * scrolling in overview (if we haven't scrolled, there's a split overview action button so - * we don't need this menu option) + * * 1. Taskbar is not present AND aren't at least 2 tasks in overview to show split options for + * * 2. Split isn't supported by the task itself (non resizable activity) + * * 3. We aren't currently in multi-window + * * 4. The taskView to show split options for is the focused task AND we haven't started + * * scrolling in overview (if we haven't scrolled, there's a split overview action button so + * * we don't need this menu option) */ TaskShortcutFactory SPLIT_SELECT = new TaskShortcutFactory() { @Override public List getShortcuts(BaseDraggingActivity activity, TaskIdAttributeContainer taskContainer) { DeviceProfile deviceProfile = activity.getDeviceProfile(); - final Task task = taskContainer.getTask(); + final Task task = taskContainer.getTask(); final int intentFlags = task.key.baseIntent.getFlags(); final TaskView taskView = taskContainer.getTaskView(); final RecentsView recentsView = taskView.getRecentsView(); final PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); - boolean notEnoughTasksToSplit = recentsView.getTaskViewCount() < 2; - boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask(); - boolean isTaskInExpectedScrollPosition = - recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView)); + boolean notEnoughTasksToSplit = + !deviceProfile.isTaskbarPresent && recentsView.getTaskViewCount() < 2; boolean isTaskSplitNotSupported = !task.isDockable || (intentFlags & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0; boolean hideForExistingMultiWindow = activity.getDeviceProfile().isMultiWindowMode; + boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask(); + boolean isTaskInExpectedScrollPosition = + recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView)); - if (taskView.containsMultipleTasks() - || notEnoughTasksToSplit - || isTaskSplitNotSupported - || hideForExistingMultiWindow + if (notEnoughTasksToSplit || isTaskSplitNotSupported || hideForExistingMultiWindow || (isFocusedTask && isTaskInExpectedScrollPosition)) { return null; } @@ -333,7 +331,7 @@ public interface TaskShortcutFactory { @Override public List getShortcuts(BaseDraggingActivity activity, TaskIdAttributeContainer taskContainer) { - final Task task = taskContainer.getTask(); + final Task task = taskContainer.getTask(); if (!task.isDockable) { return null; } @@ -349,8 +347,8 @@ public interface TaskShortcutFactory { private boolean isAvailable(BaseDraggingActivity activity, int displayId) { return Settings.Global.getInt( - activity.getContentResolver(), - Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0 + activity.getContentResolver(), + Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0 && !isDesktopModeSupported(); } }; @@ -389,7 +387,8 @@ public interface TaskShortcutFactory { @Override public void onClick(View view) { if (mTaskView.launchTaskAnimated() != null) { - SystemUiProxy.INSTANCE.get(mTarget).startScreenPinning(mTaskView.getTask().key.id); + SystemUiProxy.INSTANCE.get(mTarget).startScreenPinning( + mTaskView.getTask().key.id); } dismissTaskMenuView(mTarget); mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getItemInfo()) @@ -405,7 +404,7 @@ public interface TaskShortcutFactory { return InstantAppResolver.newInstance(activity).isInstantApp( t.getTopComponent().getPackageName(), t.getKey().userId) ? Collections.singletonList(new SystemShortcut.Install(activity, - taskContainer.getItemInfo(), taskContainer.getTaskView())) + taskContainer.getItemInfo(), taskContainer.getTaskView())) : null; } }; @@ -425,9 +424,10 @@ public interface TaskShortcutFactory { @Override public List getShortcuts(BaseDraggingActivity activity, TaskIdAttributeContainer taskContainer) { - SystemShortcut screenshotShortcut = taskContainer.getThumbnailView().getTaskOverlay() - .getScreenshotShortcut(activity, taskContainer.getItemInfo(), - taskContainer.getTaskView()); + SystemShortcut screenshotShortcut = + taskContainer.getThumbnailView().getTaskOverlay() + .getScreenshotShortcut(activity, taskContainer.getItemInfo(), + taskContainer.getTaskView()); return createSingletonShortcutList(screenshotShortcut); } }; diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java index ee0fbb81b0..adc96478fc 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java @@ -29,6 +29,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.launcher3.tapl.Overview; +import com.android.launcher3.tapl.Taskbar; +import com.android.launcher3.tapl.TaskbarAppIcon; import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.TestStabilityRule; @@ -139,6 +142,31 @@ public class TaplTestsSplitscreen extends AbstractQuickStepTest { .hasMenuItem("Save app pair")); } + @Test + public void testSplitSingleTaskFromTaskbar() { + // Currently only tablets have Taskbar in Overview, so test is only active on tablets + assumeTrue(mLauncher.isTablet()); + + if (!mLauncher.getRecentTasks().isEmpty()) { + // Clear all recent tasks + mLauncher.goHome().switchToOverview().dismissAllTasks(); + } + + startAppFast(getAppPackageName()); + + Overview overview = mLauncher.goHome().switchToOverview(); + if (mLauncher.isGridOnlyOverviewEnabled()) { + overview.getCurrentTask().tapMenu().tapSplitMenuItem(); + } else { + overview.getOverviewActions().clickSplit(); + } + + Taskbar taskbar = overview.getTaskbar(); + String firstAppName = taskbar.getIconNames().get(0); + TaskbarAppIcon firstApp = taskbar.getAppIcon(firstAppName); + firstApp.launchIntoSplitScreen(); + } + private void createAndLaunchASplitPair() { startTestActivity(2); startTestActivity(3); diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 770fe147eb..fa5a7b320f 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -16,9 +16,12 @@ package com.android.launcher3.tapl; +import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID; + import android.graphics.Rect; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; @@ -322,6 +325,22 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.getOverviewObjectSelector("clear_all")); } + /** + * Returns the taskbar if it's a tablet, or {@code null} otherwise. + */ + @Nullable + public Taskbar getTaskbar() { + if (!mLauncher.isTablet()) { + return null; + } + try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "want to get the taskbar")) { + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID); + + return new Taskbar(mLauncher); + } + } + protected boolean isActionsViewVisible() { if (!hasTasks() || isClearAllVisible()) { return false;