Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4a161ee authored by András Klöczl's avatar András Klöczl Committed by Android (Google) Code Review
Browse files

Merge "Add TAPL tests for two panel workspace" into sc-v2-dev

parents a21e47c9 c820151a
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -80,12 +80,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
        assertTrue(message, failed);
    }

    private int pagesPerScreen() {
        return mLauncher.isTwoPanels() ? 2 : 1;
    }

    private boolean isWorkspaceScrollable(Launcher launcher) {
        return launcher.getWorkspace().getPageCount() > pagesPerScreen();
    public static boolean isWorkspaceScrollable(Launcher launcher) {
        return launcher.getWorkspace().getPageCount() > launcher.getWorkspace().getPanelCount();
    }

    private int getCurrentWorkspacePage(Launcher launcher) {
@@ -192,7 +188,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
        executeOnLauncher(
                launcher -> assertEquals(
                        "Ensuring workspace scrollable didn't switch to next screen",
                        pagesPerScreen(), getCurrentWorkspacePage(launcher)));
                        workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
        executeOnLauncher(
                launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
                        isWorkspaceScrollable(launcher)));
@@ -209,7 +205,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
        workspace.flingForward();
        executeOnLauncher(
                launcher -> assertEquals("Flinging forward didn't switch workspace to next screen",
                        pagesPerScreen(), getCurrentWorkspacePage(launcher)));
                        workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
        assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));

        // Test starting a workspace app.
+285 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.ui.workspace;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.launcher3.CellLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TaplTestsLauncher3;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Tests for two panel workspace.
 *
 * Note running these tests will clear the workspace on the device.
 */
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TwoPanelWorkspaceTest extends AbstractLauncherUiTest {

    Workspace mWorkspace;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        TaplTestsLauncher3.initialize(this);
        mWorkspace = mLauncher.getWorkspace();
    }

    @Test
    public void testDragIconToRightPanel() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getHotseatAppIcon("Chrome"), 1);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Maps", "Play Store");
            assertItemsOnPage(launcher, 1, "Chrome");
        });
    }

    @Test
    public void testDragIconToPage2() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Maps"), 2);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertPageEmpty(launcher, 1);
            assertItemsOnPage(launcher, 2, "Maps");
            assertPageEmpty(launcher, 3);
        });
    }

    @Test
    public void testDragIconToPage3() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getHotseatAppIcon("Phone"), 3);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
            assertPageEmpty(launcher, 2);
            assertItemsOnPage(launcher, 3, "Phone");
        });
    }


    @Test
    public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Maps"), 3);
        mWorkspace.dragIcon(mWorkspace.getHotseatAppIcon("Chrome"), 0);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertPageEmpty(launcher, 1);
            assertItemsOnPage(launcher, 2, "Chrome");
            assertItemsOnPage(launcher, 3, "Maps");
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Maps"), -1);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertItemsOnPage(launcher, 1, "Maps");
            assertItemsOnPage(launcher, 2, "Chrome");
            assertPageEmpty(launcher, 3);
        });

        // Move Chrome to the right panel as well, to make sure pages are not deleted whichever
        // page is the empty one
        mWorkspace.flingForward();
        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Chrome"), 1);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertItemsOnPage(launcher, 1, "Maps");
            assertPageEmpty(launcher, 2);
            assertItemsOnPage(launcher, 3, "Chrome");
        });
    }


    @Test
    public void testEmptyPagesGetRemovedIfBothPagesAreEmpty() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Play Store"), 2);
        mWorkspace.dragIcon(mWorkspace.getHotseatAppIcon("Camera"), 1);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3);
            assertItemsOnPage(launcher, 0, "Maps");
            assertPageEmpty(launcher, 1);
            assertItemsOnPage(launcher, 2, "Play Store");
            assertItemsOnPage(launcher, 3, "Camera");
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Camera"), -1);
        mWorkspace.flingForward();
        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Play Store"), -2);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertItemsOnPage(launcher, 1, "Camera");
        });
    }

    @Test
    public void testMiddleEmptyPagesGetRemoved() {
        if (!mLauncher.isTwoPanels()) {
            return;
        }

        // Pre verifying the screens
        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1);
            assertItemsOnPage(launcher, 0, "Play Store", "Maps");
            assertPageEmpty(launcher, 1);
        });

        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Maps"), 2);
        mWorkspace.dragIcon(mWorkspace.getHotseatAppIcon("Messages"), 3);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertPageEmpty(launcher, 1);
            assertItemsOnPage(launcher, 2, "Maps");
            assertPageEmpty(launcher, 3);
            assertPageEmpty(launcher, 4);
            assertItemsOnPage(launcher, 5, "Messages");
        });

        mWorkspace.flingBackward();
        mWorkspace.dragIcon(mWorkspace.getWorkspaceAppIcon("Maps"), 2);

        executeOnLauncher(launcher -> {
            assertPagesExist(launcher, 0, 1, 4, 5);
            assertItemsOnPage(launcher, 0, "Play Store");
            assertPageEmpty(launcher, 1);
            assertItemsOnPage(launcher, 4, "Maps");
            assertItemsOnPage(launcher, 5, "Messages");
        });
    }

    private void assertPageEmpty(Launcher launcher, int pageId) {
        CellLayout page = launcher.getWorkspace().getScreenWithId(pageId);
        assertNotNull("Page " + pageId + " does NOT exist.", page);
        assertEquals("Page " + pageId + " is NOT empty. Number of items on the page:", 0,
                page.getShortcutsAndWidgets().getChildCount());
    }

    private void assertPagesExist(Launcher launcher, int... pageIds) {
        int pageCount = launcher.getWorkspace().getPageCount();
        assertEquals("Existing page count does NOT match.", pageIds.length, pageCount);
        for (int i = 0; i < pageCount; i++) {
            CellLayout page = (CellLayout) launcher.getWorkspace().getPageAt(i);
            int pageId = launcher.getWorkspace().getIdForScreen(page);
            assertEquals("The page's id at index " + i + " does NOT match.", pageId,
                    pageIds[i]);
        }
    }

    private void assertItemsOnPage(Launcher launcher, int pageId, String... itemTitles) {
        Set<String> itemTitleSet = Arrays.stream(itemTitles).collect(Collectors.toSet());
        CellLayout page = launcher.getWorkspace().getScreenWithId(pageId);
        int itemCount = page.getShortcutsAndWidgets().getChildCount();
        for (int i = 0; i < itemCount; i++) {
            ItemInfo itemInfo = (ItemInfo) page.getShortcutsAndWidgets().getChildAt(i).getTag();
            if (itemInfo != null) {
                assertTrue("There was an extra item on page " + pageId + ": " + itemInfo.title,
                        itemTitleSet.remove(itemInfo.title));
            }
        }
        assertTrue("Could NOT find some of the items on page " + pageId + ": "
                        + itemTitleSet.stream().collect(Collectors.joining(",")),
                itemTitleSet.isEmpty());
    }
}
+62 −13
Original line number Diff line number Diff line
@@ -145,11 +145,49 @@ public final class Workspace extends Home {
            if (!isWorkspaceScrollable(workspace)) {
                try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                        "dragging icon to a second page of workspace to make it scrollable")) {
                    dragIcon(workspace, getHotseatAppIcon("Chrome"), pagesPerScreen());
                    verifyActiveContainer();
                }
            }
            assertTrue("Home screen workspace didn't become scrollable",
                    isWorkspaceScrollable(workspace));
        }
    }

    /**
     * Returns the number of pages that are visible on the screen simultaneously.
     */
    public int pagesPerScreen() {
        return mLauncher.isTwoPanels() ? 2 : 1;
    }

    /**
     * Drags an icon to the (currentPage + pageDelta) page if the page already exists.
     * If the target page doesn't exist, the icon will be put onto an existing page that is the
     * closest to the target page.
     *
     * @param appIcon   - icon to drag.
     * @param pageDelta - how many pages should the icon be dragged from the current page.
     *                    It can be a negative value.
     */
    public void dragIcon(AppIcon appIcon, int pageDelta) {
        try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
            final UiObject2 workspace = verifyActiveContainer();
            try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                    "dragging icon to page with delta: " + pageDelta)) {
                dragIcon(workspace, appIcon, pageDelta);
                verifyActiveContainer();
            }
        }
    }

    private void dragIcon(UiObject2 workspace, AppIcon appIcon, int pageDelta) {
        int pageWidth = mLauncher.getDevice().getDisplayWidth() / pagesPerScreen();
        int targetX = (pageWidth / 2) + pageWidth * pageDelta;
        dragIconToWorkspace(
                mLauncher,
                            getHotseatAppIcon("Chrome"),
                            new Point(mLauncher.getDevice().getDisplayWidth(),
                                    mLauncher.getVisibleBounds(workspace).centerY()),
                appIcon,
                new Point(targetX, mLauncher.getVisibleBounds(workspace).centerY()),
                "popup_container",
                false,
                false,
@@ -157,11 +195,6 @@ public final class Workspace extends Home {
                        TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT));
        verifyActiveContainer();
    }
            }
            assertTrue("Home screen workspace didn't become scrollable",
                    isWorkspaceScrollable(workspace));
        }
    }

    private boolean isWorkspaceScrollable(UiObject2 workspace) {
        return workspace.getChildCount() > (mLauncher.isTwoPanels() ? 2 : 1);
@@ -258,10 +291,26 @@ public final class Workspace extends Home {
        try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
                "want to drag icon to workspace")) {
            final long downTime = SystemClock.uptimeMillis();
            final Point dragStartCenter = dragIconToSpringLoaded(launcher, downTime,
            Point dragStart = dragIconToSpringLoaded(launcher, downTime,
                    launchable.getObject(), longPressIndicator, expectLongClickEvents);
            final Point targetDest = dest.get();
            launcher.movePointer(dragStartCenter, targetDest, 10, downTime, true,
            Point targetDest = dest.get();
            int displayX = launcher.getRealDisplaySize().x;

            // Since the destination can be on another page, we need to drag to the edge first
            // until we reach the target page
            while (targetDest.x > displayX || targetDest.x < 0) {
                int edgeX = targetDest.x > 0 ? displayX : 0;
                Point screenEdge = new Point(edgeX, targetDest.y);
                launcher.movePointer(dragStart, screenEdge, 10, downTime, true,
                        LauncherInstrumentation.GestureScope.INSIDE);
                launcher.waitForIdle(); // Wait for the page change to happen
                targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
                dragStart = screenEdge;
            }

            // targetDest.x is now between 0 and displayX so we found the target page,
            // we just have to put move the icon to the destination and drop it
            launcher.movePointer(dragStart, targetDest, 10, downTime, true,
                    LauncherInstrumentation.GestureScope.INSIDE);
            dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
        }