1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.tapl;
17 
18 import static com.android.launcher3.testing.shared.TestProtocol.TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE;
19 
20 import android.graphics.Point;
21 import android.util.Log;
22 
23 import java.util.function.Supplier;
24 
25 /** {@link Launchable} that can serve as a source for dragging and dropping to the workspace. */
26 interface WorkspaceDragSource {
27 
28     /**
29      * Drags an object to the center of homescreen.
30      *
31      * @param startsActivity   whether it's expected to start an activity.
32      * @param isWidgetShortcut whether we drag a widget shortcut
33      */
dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut)34     default void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
35         Launchable launchable = getLaunchable();
36         LauncherInstrumentation launcher = launchable.mLauncher;
37         try (LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
38             internalDragToWorkspace(startsActivity, isWidgetShortcut);
39         }
40     }
41 
42     /**
43      * TODO(Redesign WorkspaceDragSource to have actual private methods)
44      * Temporary private method
45      *
46      * @param startsActivity   whether it's expected to start an activity.
47      * @param isWidgetShortcut whether we drag a widget shortcut
48      */
internalDragToWorkspace(boolean startsActivity, boolean isWidgetShortcut)49     default void internalDragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
50         Launchable launchable = getLaunchable();
51         LauncherInstrumentation launcher = launchable.mLauncher;
52         final Point launchableCenter = launchable.getObject().getVisibleCenter();
53         final Point displaySize = launcher.getRealDisplaySize();
54         final int width = displaySize.x / 2;
55         Workspace.dragIconToWorkspace(
56                 launcher,
57                 launchable,
58                 () -> new Point(
59                         launchableCenter.x >= width
60                                 ? launchableCenter.x - width / 2
61                                 : launchableCenter.x + width / 2,
62                         displaySize.y / 2),
63                 startsActivity,
64                 isWidgetShortcut,
65                 launchable::addExpectedEventsForLongClick);
66     }
67 
68     /**
69      * Drag an object to the given cell in workspace. The target cell must be empty.
70      *
71      * @param cellX zero based column number, starting from the left of the screen.
72      * @param cellY zero based row number, starting from the top of the screen.     *
73      */
dragToWorkspace(int cellX, int cellY)74     default HomeAppIcon dragToWorkspace(int cellX, int cellY) {
75         Launchable launchable = getLaunchable();
76         final String iconName = launchable.getObject().getText();
77         LauncherInstrumentation launcher = launchable.mLauncher;
78         try (LauncherInstrumentation.Closable e = launcher.eventsCheck();
79              LauncherInstrumentation.Closable c = launcher.addContextLayer(
80                      String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))) {
81             final Supplier<Point> dest = () -> Workspace.getCellCenter(launcher, cellX, cellY);
82             Log.d(TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE,
83                     "WorkspaceDragSource.dragToWorkspace: dragging icon to workspace | dest: "
84                             + dest.get());
85             Workspace.dragIconToWorkspace(
86                     launcher,
87                     launchable,
88                     dest,
89                     launchable::addExpectedEventsForLongClick,
90                     /*expectDropEvents= */ null,
91                     /* startsActivity = */ false);
92 
93             try (LauncherInstrumentation.Closable ignore = launcher.addContextLayer("dragged")) {
94                 WorkspaceAppIcon appIcon =
95                         (WorkspaceAppIcon) launcher.getWorkspace().getWorkspaceAppIcon(iconName);
96                 launcher.assertTrue(
97                         String.format(
98                                 "The %s icon should be in the cell (%d, %d).", iconName, cellX,
99                                 cellY),
100                         appIcon.isInCell(cellX, cellY));
101                 return appIcon;
102             }
103         }
104     }
105 
106     /** This method requires public access, however should not be called in tests. */
getLaunchable()107     Launchable getLaunchable();
108 }
109