Merge "App Pairs (behind flag): Add Overview menu item, icon, tests" into udc-dev
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M13.329,2.305H4.242C2.751,2.305 1.542,3.514 1.542,5.005V13.005C1.542,14.496 2.751,15.705 4.242,15.705H7.875V19.011C7.875,20.502 9.084,21.711 10.575,21.711H19.662C21.153,21.711 22.362,20.502 22.362,19.011V10.011C22.362,8.52 21.153,7.311 19.662,7.311H16.029V5.005C16.029,3.514 14.821,2.305 13.329,2.305ZM14.329,7.311V5.005C14.329,4.452 13.882,4.005 13.329,4.005H4.242C3.69,4.005 3.242,4.452 3.242,5.005V13.005C3.242,13.557 3.69,14.005 4.242,14.005H7.875V10.011C7.875,8.52 9.084,7.311 10.575,7.311H14.329ZM9.575,14.005V10.011C9.575,9.611 9.81,9.266 10.15,9.106C10.285,9.037 10.438,8.999 10.6,8.999H19.687C20.239,8.999 20.687,9.447 20.687,9.999V18.999C20.687,19.399 20.452,19.744 20.113,19.904C19.977,19.972 19.824,20.011 19.662,20.011H10.575C10.023,20.011 9.575,19.563 9.575,19.011V15.705H9.6V14.005H9.575ZM15.542,11.996V14H17.588V15H15.542V16.996H14.542V15H12.464V14H14.542V11.996H15.542Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
@@ -129,7 +129,8 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
TaskShortcutFactory.PIN,
|
||||
TaskShortcutFactory.INSTALL,
|
||||
TaskShortcutFactory.FREE_FORM,
|
||||
TaskShortcutFactory.WELLBEING
|
||||
TaskShortcutFactory.WELLBEING,
|
||||
TaskShortcutFactory.SAVE_APP_PAIR
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
|
||||
import com.android.launcher3.model.WellbeingModel;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
@@ -63,7 +64,8 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Represents a system shortcut that can be shown for a recent task.
|
||||
* Represents a system shortcut that can be shown for a recent task. Appears as a single entry in
|
||||
* the dropdown menu that shows up when you tap an app icon in Overview.
|
||||
*/
|
||||
public interface TaskShortcutFactory {
|
||||
@Nullable
|
||||
@@ -122,6 +124,26 @@ public interface TaskShortcutFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A menu item, "Save app pair", that allows the user to preserve the current app combination as
|
||||
* a single persistent icon on the Home screen, allowing for quick split screen initialization.
|
||||
*/
|
||||
class SaveAppPairSystemShortcut extends SystemShortcut {
|
||||
|
||||
private final TaskView mTaskView;
|
||||
|
||||
public SaveAppPairSystemShortcut(BaseDraggingActivity target, TaskView taskView) {
|
||||
super(R.drawable.ic_save_app_pair, R.string.save_app_pair, target,
|
||||
taskView.getItemInfo(), taskView);
|
||||
mTaskView = taskView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// TODO (b/274189428): Call "saveAppPair" function in new AppPairController class
|
||||
}
|
||||
}
|
||||
|
||||
class FreeformSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
|
||||
private static final String TAG = "FreeformSystemShortcut";
|
||||
|
||||
@@ -257,9 +279,6 @@ public interface TaskShortcutFactory {
|
||||
final PagedOrientationHandler orientationHandler =
|
||||
recentsView.getPagedOrientationHandler();
|
||||
|
||||
int[] taskViewTaskIds = taskView.getTaskIds();
|
||||
boolean taskViewHasMultipleTasks = taskViewTaskIds[0] != -1 &&
|
||||
taskViewTaskIds[1] != -1;
|
||||
boolean notEnoughTasksToSplit = recentsView.getTaskViewCount() < 2;
|
||||
boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
|
||||
boolean isTaskInExpectedScrollPosition =
|
||||
@@ -267,11 +286,11 @@ public interface TaskShortcutFactory {
|
||||
boolean isTaskSplitNotSupported = !task.isDockable;
|
||||
boolean hideForExistingMultiWindow = activity.getDeviceProfile().isMultiWindowMode;
|
||||
|
||||
if (taskViewHasMultipleTasks ||
|
||||
notEnoughTasksToSplit ||
|
||||
isTaskSplitNotSupported ||
|
||||
hideForExistingMultiWindow ||
|
||||
(isFocusedTask && isTaskInExpectedScrollPosition)) {
|
||||
if (taskView.containsMultipleTasks()
|
||||
|| notEnoughTasksToSplit
|
||||
|| isTaskSplitNotSupported
|
||||
|| hideForExistingMultiWindow
|
||||
|| (isFocusedTask && isTaskInExpectedScrollPosition)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -283,6 +302,26 @@ public interface TaskShortcutFactory {
|
||||
}
|
||||
};
|
||||
|
||||
TaskShortcutFactory SAVE_APP_PAIR = new TaskShortcutFactory() {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
final TaskView taskView = taskContainer.getTaskView();
|
||||
|
||||
if (!FeatureFlags.ENABLE_APP_PAIRS.get() || !taskView.containsMultipleTasks()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Collections.singletonList(new SaveAppPairSystemShortcut(activity, taskView));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showForSplitscreen() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TaskShortcutFactory FREE_FORM = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
|
||||
@@ -186,35 +186,6 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
|
||||
actionsView.clickAndDismissScreenshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PortraitLandscape
|
||||
public void testSplitFromOverview() {
|
||||
assumeTrue(!mLauncher.isTablet());
|
||||
|
||||
startTestActivity(2);
|
||||
startTestActivity(3);
|
||||
|
||||
mLauncher.goHome().switchToOverview().getCurrentTask()
|
||||
.tapMenu()
|
||||
.tapSplitMenuItem()
|
||||
.getCurrentTask()
|
||||
.open();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PortraitLandscape
|
||||
public void testSplitFromOverviewForTablet() {
|
||||
assumeTrue(mLauncher.isTablet());
|
||||
|
||||
startTestActivity(2);
|
||||
startTestActivity(3);
|
||||
|
||||
mLauncher.goHome().switchToOverview().getOverviewActions()
|
||||
.clickSplit()
|
||||
.getTestActivityTask(2)
|
||||
.open();
|
||||
}
|
||||
|
||||
private int getCurrentOverviewPage(Launcher launcher) {
|
||||
return launcher.<RecentsView>getOverviewPanel().getCurrentPage();
|
||||
}
|
||||
|
||||
@@ -15,14 +15,18 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
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;
|
||||
|
||||
@@ -37,13 +41,6 @@ public class TaplTestsSplitscreen extends AbstractQuickStepTest {
|
||||
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();
|
||||
@@ -57,15 +54,30 @@ public class TaplTestsSplitscreen extends AbstractQuickStepTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@PortraitLandscape
|
||||
public void testSplitFromOverview() {
|
||||
createAndLaunchASplitPair();
|
||||
}
|
||||
|
||||
@Test
|
||||
// TODO (b/270201357): When this test is proven stable, remove this TestStabilityRule and
|
||||
// introduce into presubmit as well.
|
||||
// introduce into presubmit as well.
|
||||
@TestStabilityRule.Stability(
|
||||
flavors = TestStabilityRule.LOCAL | TestStabilityRule.PLATFORM_POSTSUBMIT)
|
||||
@PortraitLandscape
|
||||
@TaskbarModeSwitch
|
||||
public void testSplitAppFromHomeWithItself() throws Exception {
|
||||
Assume.assumeTrue(mLauncher.isTablet());
|
||||
// Currently only tablets have Taskbar in Overview, so test is only active on tablets
|
||||
assumeTrue(mLauncher.isTablet());
|
||||
|
||||
mLauncher.getWorkspace()
|
||||
.deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
|
||||
.switchToAllApps()
|
||||
.getAppIcon(CALCULATOR_APP_NAME)
|
||||
.dragToHotseat(0);
|
||||
|
||||
startAppFast(CALCULATOR_APP_PACKAGE);
|
||||
|
||||
mLauncher.goHome()
|
||||
.switchToAllApps()
|
||||
@@ -79,4 +91,50 @@ public class TaplTestsSplitscreen extends AbstractQuickStepTest {
|
||||
.getAppIcon(CALCULATOR_APP_NAME)
|
||||
.launchIntoSplitScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAppPairMenuItemExistsOnSplitPair() throws Exception {
|
||||
assumeTrue(FeatureFlags.ENABLE_APP_PAIRS.get());
|
||||
|
||||
createAndLaunchASplitPair();
|
||||
|
||||
assertTrue("Save app pair menu item is missing",
|
||||
mLauncher.goHome()
|
||||
.switchToOverview()
|
||||
.getCurrentTask()
|
||||
.tapMenu()
|
||||
.hasMenuItem("Save app pair"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAppPairMenuItemDoesNotExistOnSingleTask() throws Exception {
|
||||
assumeTrue(FeatureFlags.ENABLE_APP_PAIRS.get());
|
||||
|
||||
startAppFast(CALCULATOR_APP_PACKAGE);
|
||||
|
||||
assertFalse("Save app pair menu item is erroneously appearing on single task",
|
||||
mLauncher.goHome()
|
||||
.switchToOverview()
|
||||
.getCurrentTask()
|
||||
.tapMenu()
|
||||
.hasMenuItem("Save app pair"));
|
||||
}
|
||||
|
||||
private void createAndLaunchASplitPair() {
|
||||
startTestActivity(2);
|
||||
startTestActivity(3);
|
||||
|
||||
if (mLauncher.isTablet()) {
|
||||
mLauncher.goHome().switchToOverview().getOverviewActions()
|
||||
.clickSplit()
|
||||
.getTestActivityTask(2)
|
||||
.open();
|
||||
} else {
|
||||
mLauncher.goHome().switchToOverview().getCurrentTask()
|
||||
.tapMenu()
|
||||
.tapSplitMenuItem()
|
||||
.getCurrentTask()
|
||||
.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
<string name="recent_task_option_split_screen">Split screen</string>
|
||||
<string name="split_app_info_accessibility">App info for %1$s</string>
|
||||
|
||||
<!-- App pairs -->
|
||||
<string name="save_app_pair">Save app pair</string>
|
||||
|
||||
<!-- Widgets -->
|
||||
<!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
|
||||
<string name="long_press_widget_to_add">Touch & hold to move a widget.</string>
|
||||
|
||||
@@ -49,4 +49,10 @@ public class OverviewTaskMenu {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if an item matching the given string is present in the menu. */
|
||||
public boolean hasMenuItem(String expectedMenuItemText) {
|
||||
UiObject2 menuItem = mLauncher.findObjectInContainer(mMenu, By.text(expectedMenuItemText));
|
||||
return menuItem != null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user