blob: f17818a42b2de726811c7d132cad8994884b51ed [file] [log] [blame]
Sunny Goyal83a8f042015-05-19 12:52:12 -07001package com.android.launcher3.accessibility;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08002
Sunny Goyal9ca9c132015-04-29 14:57:22 -07003import android.app.AlertDialog;
4import android.appwidget.AppWidgetProviderInfo;
5import android.content.DialogInterface;
Adam Cohenc9735cf2015-01-23 16:11:55 -08006import android.graphics.Rect;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08007import android.os.Bundle;
Sunny Goyal9ae77772015-04-29 16:30:23 -07008import android.os.Handler;
Sunny Goyal1a70cef2015-04-22 11:29:51 -07009import android.text.TextUtils;
Sunny Goyala9116722015-04-29 13:55:58 -070010import android.util.Log;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080011import android.util.SparseArray;
12import android.view.View;
13import android.view.View.AccessibilityDelegate;
14import android.view.accessibility.AccessibilityNodeInfo;
15import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
16
Sunny Goyal83a8f042015-05-19 12:52:12 -070017import com.android.launcher3.AppInfo;
18import com.android.launcher3.AppWidgetResizeFrame;
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070019import com.android.launcher3.BubbleTextView;
Sunny Goyal0236d0b2017-10-24 14:54:30 -070020import com.android.launcher3.ButtonDropTarget;
Sunny Goyal83a8f042015-05-19 12:52:12 -070021import com.android.launcher3.CellLayout;
22import com.android.launcher3.DeleteDropTarget;
Sunny Goyal94b510c2016-08-16 15:36:48 -070023import com.android.launcher3.DropTarget.DragObject;
Sunny Goyal83a8f042015-05-19 12:52:12 -070024import com.android.launcher3.FolderInfo;
25import com.android.launcher3.InfoDropTarget;
26import com.android.launcher3.ItemInfo;
27import com.android.launcher3.Launcher;
28import com.android.launcher3.LauncherAppWidgetHostView;
29import com.android.launcher3.LauncherAppWidgetInfo;
Sunny Goyal83a8f042015-05-19 12:52:12 -070030import com.android.launcher3.LauncherSettings;
31import com.android.launcher3.PendingAddItemInfo;
32import com.android.launcher3.R;
33import com.android.launcher3.ShortcutInfo;
34import com.android.launcher3.UninstallDropTarget;
35import com.android.launcher3.Workspace;
Vadim Tryshevfedca432015-08-19 17:55:02 -070036import com.android.launcher3.dragndrop.DragController.DragListener;
Sunny Goyala52ecb02016-12-16 15:04:51 -080037import com.android.launcher3.dragndrop.DragOptions;
38import com.android.launcher3.folder.Folder;
Mario Bertschlerc06af332017-03-28 12:23:22 -070039import com.android.launcher3.popup.PopupContainerWithArrow;
Tony18c4aa42017-05-10 21:23:57 -050040import com.android.launcher3.shortcuts.DeepShortcutManager;
Adam Cohen091440a2015-03-18 14:16:05 -070041import com.android.launcher3.util.Thunk;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080042
43import java.util.ArrayList;
44
Sunny Goyal45478022015-06-08 16:52:41 -070045public class LauncherAccessibilityDelegate extends AccessibilityDelegate implements DragListener {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080046
Sunny Goyala9116722015-04-29 13:55:58 -070047 private static final String TAG = "LauncherAccessibilityDelegate";
48
Sunny Goyal0236d0b2017-10-24 14:54:30 -070049 public static final int REMOVE = R.id.action_remove;
50 public static final int INFO = R.id.action_info;
51 public static final int UNINSTALL = R.id.action_uninstall;
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070052 protected static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
53 protected static final int MOVE = R.id.action_move;
54 protected static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
55 protected static final int RESIZE = R.id.action_resize;
Sunny Goyal66b24572016-09-21 15:57:55 -070056 public static final int DEEP_SHORTCUTS = R.id.action_deep_shortcuts;
Adam Cohenc9735cf2015-01-23 16:11:55 -080057
Sunny Goyale9b651e2015-04-24 11:44:51 -070058 public enum DragType {
Adam Cohenc9735cf2015-01-23 16:11:55 -080059 ICON,
60 FOLDER,
61 WIDGET
62 }
63
64 public static class DragInfo {
Sunny Goyale9b651e2015-04-24 11:44:51 -070065 public DragType dragType;
66 public ItemInfo info;
67 public View item;
Adam Cohenc9735cf2015-01-23 16:11:55 -080068 }
69
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070070 protected final SparseArray<AccessibilityAction> mActions = new SparseArray<>();
Adam Cohen091440a2015-03-18 14:16:05 -070071 @Thunk final Launcher mLauncher;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080072
Sunny Goyale9b651e2015-04-24 11:44:51 -070073 private DragInfo mDragInfo = null;
Sunny Goyale9b651e2015-04-24 11:44:51 -070074
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080075 public LauncherAccessibilityDelegate(Launcher launcher) {
76 mLauncher = launcher;
77
78 mActions.put(REMOVE, new AccessibilityAction(REMOVE,
Tony Wickham9aae47f2015-10-01 13:04:22 -070079 launcher.getText(R.string.remove_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080080 mActions.put(INFO, new AccessibilityAction(INFO,
Tony Wickham9aae47f2015-10-01 13:04:22 -070081 launcher.getText(R.string.app_info_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080082 mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
Tony Wickham9aae47f2015-10-01 13:04:22 -070083 launcher.getText(R.string.uninstall_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080084 mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
85 launcher.getText(R.string.action_add_to_workspace)));
Adam Cohenc9735cf2015-01-23 16:11:55 -080086 mActions.put(MOVE, new AccessibilityAction(MOVE,
87 launcher.getText(R.string.action_move)));
Sunny Goyal9ae77772015-04-29 16:30:23 -070088 mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE,
89 launcher.getText(R.string.action_move_to_workspace)));
Sunny Goyal9ca9c132015-04-29 14:57:22 -070090 mActions.put(RESIZE, new AccessibilityAction(RESIZE,
91 launcher.getText(R.string.action_resize)));
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070092 mActions.put(DEEP_SHORTCUTS, new AccessibilityAction(DEEP_SHORTCUTS,
93 launcher.getText(R.string.action_deep_shortcut)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080094 }
95
96 @Override
97 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
98 super.onInitializeAccessibilityNodeInfo(host, info);
Sunny Goyal66b24572016-09-21 15:57:55 -070099 addSupportedActions(host, info, false);
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700100 }
101
Sunny Goyal66b24572016-09-21 15:57:55 -0700102 public void addSupportedActions(View host, AccessibilityNodeInfo info, boolean fromKeyboard) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800103 if (!(host.getTag() instanceof ItemInfo)) return;
104 ItemInfo item = (ItemInfo) host.getTag();
105
Sunny Goyal66b24572016-09-21 15:57:55 -0700106 // If the request came from keyboard, do not add custom shortcuts as that is already
107 // exposed as a direct shortcut
Tony18c4aa42017-05-10 21:23:57 -0500108 if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) {
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700109 info.addAction(mActions.get(DEEP_SHORTCUTS));
110 }
111
Sunny Goyal0236d0b2017-10-24 14:54:30 -0700112 for (ButtonDropTarget target : mLauncher.getDropTargetBar().getDropTargets()) {
113 if (target.supportsAccessibilityDrop(item)) {
114 info.addAction(mActions.get(target.getAccessibilityAction()));
115 }
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700116 }
117
Sunny Goyal66b24572016-09-21 15:57:55 -0700118 // Do not add move actions for keyboard request as this uses virtual nodes.
119 if (!fromKeyboard && ((item instanceof ShortcutInfo)
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800120 || (item instanceof LauncherAppWidgetInfo)
Sunny Goyal66b24572016-09-21 15:57:55 -0700121 || (item instanceof FolderInfo))) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800122 info.addAction(mActions.get(MOVE));
Sunny Goyal9ae77772015-04-29 16:30:23 -0700123
124 if (item.container >= 0) {
125 info.addAction(mActions.get(MOVE_TO_WORKSPACE));
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700126 } else if (item instanceof LauncherAppWidgetInfo) {
127 if (!getSupportedResizeActions(host, (LauncherAppWidgetInfo) item).isEmpty()) {
128 info.addAction(mActions.get(RESIZE));
129 }
Sunny Goyal9ae77772015-04-29 16:30:23 -0700130 }
Adam Cohen6e92f052016-06-07 14:30:10 -0700131 }
132
133 if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800134 info.addAction(mActions.get(ADD_TO_WORKSPACE));
135 }
136 }
137
138 @Override
139 public boolean performAccessibilityAction(View host, int action, Bundle args) {
140 if ((host.getTag() instanceof ItemInfo)
141 && performAction(host, (ItemInfo) host.getTag(), action)) {
142 return true;
143 }
144 return super.performAccessibilityAction(host, action, args);
145 }
146
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700147 public boolean performAction(final View host, final ItemInfo item, int action) {
Sunny Goyal0236d0b2017-10-24 14:54:30 -0700148 if (action == MOVE) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800149 beginAccessibleDrag(host, item);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800150 } else if (action == ADD_TO_WORKSPACE) {
Sunny Goyala9116722015-04-29 13:55:58 -0700151 final int[] coordinates = new int[2];
152 final long screenId = findSpaceOnWorkspace(item, coordinates);
153 mLauncher.showWorkspace(true, new Runnable() {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800154
155 @Override
Sunny Goyala9116722015-04-29 13:55:58 -0700156 public void run() {
157 if (item instanceof AppInfo) {
158 ShortcutInfo info = ((AppInfo) item).makeShortcut();
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800159 mLauncher.getModelWriter().addItemToDatabase(info,
Sunny Goyala9116722015-04-29 13:55:58 -0700160 LauncherSettings.Favorites.CONTAINER_DESKTOP,
161 screenId, coordinates[0], coordinates[1]);
162
163 ArrayList<ItemInfo> itemList = new ArrayList<>();
164 itemList.add(info);
Sunny Goyalb23980c2017-08-17 07:45:25 -0700165 mLauncher.bindItems(itemList, true);
Sunny Goyala9116722015-04-29 13:55:58 -0700166 } else if (item instanceof PendingAddItemInfo) {
167 PendingAddItemInfo info = (PendingAddItemInfo) item;
168 Workspace workspace = mLauncher.getWorkspace();
169 workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
170 mLauncher.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
171 screenId, coordinates, info.spanX, info.spanY);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800172 }
Sunny Goyala9116722015-04-29 13:55:58 -0700173 announceConfirmation(R.string.item_added_to_workspace);
174 }
175 });
176 return true;
Sunny Goyal9ae77772015-04-29 16:30:23 -0700177 } else if (action == MOVE_TO_WORKSPACE) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700178 Folder folder = Folder.getOpen(mLauncher);
179 folder.close(true);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700180 ShortcutInfo info = (ShortcutInfo) item;
Sunny Goyalc52ba712016-04-05 15:59:05 -0700181 folder.getInfo().remove(info, false);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700182
183 final int[] coordinates = new int[2];
184 final long screenId = findSpaceOnWorkspace(item, coordinates);
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800185 mLauncher.getModelWriter().moveItemInDatabase(info,
Sunny Goyal9ae77772015-04-29 16:30:23 -0700186 LauncherSettings.Favorites.CONTAINER_DESKTOP,
187 screenId, coordinates[0], coordinates[1]);
188
189 // Bind the item in next frame so that if a new workspace page was created,
190 // it will get laid out.
191 new Handler().post(new Runnable() {
192
193 @Override
194 public void run() {
195 ArrayList<ItemInfo> itemList = new ArrayList<>();
196 itemList.add(item);
Sunny Goyalb23980c2017-08-17 07:45:25 -0700197 mLauncher.bindItems(itemList, true);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700198 announceConfirmation(R.string.item_moved);
199 }
200 });
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700201 } else if (action == RESIZE) {
202 final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
203 final ArrayList<Integer> actions = getSupportedResizeActions(host, info);
204 CharSequence[] labels = new CharSequence[actions.size()];
205 for (int i = 0; i < actions.size(); i++) {
206 labels[i] = mLauncher.getText(actions.get(i));
207 }
208
209 new AlertDialog.Builder(mLauncher)
210 .setTitle(R.string.action_resize)
211 .setItems(labels, new DialogInterface.OnClickListener() {
212
213 @Override
214 public void onClick(DialogInterface dialog, int which) {
215 performResizeAction(actions.get(which), host, info);
216 dialog.dismiss();
217 }
218 })
219 .show();
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700220 return true;
221 } else if (action == DEEP_SHORTCUTS) {
Tony Wickham540913e2017-01-23 11:47:51 -0800222 return PopupContainerWithArrow.showForIcon((BubbleTextView) host) != null;
Sunny Goyal0236d0b2017-10-24 14:54:30 -0700223 } else {
224 for (ButtonDropTarget dropTarget : mLauncher.getDropTargetBar().getDropTargets()) {
225 if (action == dropTarget.getAccessibilityAction()) {
226 dropTarget.onAccessibilityDrop(host, item);
227 return true;
228 }
229 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800230 }
231 return false;
232 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800233
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700234 private ArrayList<Integer> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) {
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700235 ArrayList<Integer> actions = new ArrayList<>();
236
Sunny Goyald3d8c952015-06-01 10:09:06 -0700237 AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo();
238 if (providerInfo == null) {
239 return actions;
240 }
241
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700242 CellLayout layout = (CellLayout) host.getParent().getParent();
243 if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
244 if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
245 layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
246 actions.add(R.string.action_increase_width);
247 }
248
249 if (info.spanX > info.minSpanX && info.spanX > 1) {
250 actions.add(R.string.action_decrease_width);
251 }
252 }
253
254 if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
255 if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) ||
256 layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) {
257 actions.add(R.string.action_increase_height);
258 }
259
260 if (info.spanY > info.minSpanY && info.spanY > 1) {
261 actions.add(R.string.action_decrease_height);
262 }
263 }
264 return actions;
265 }
266
Sunny Goyal316490e2015-06-02 09:38:28 -0700267 @Thunk void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700268 CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams();
269 CellLayout layout = (CellLayout) host.getParent().getParent();
270 layout.markCellsAsUnoccupiedForView(host);
271
272 if (action == R.string.action_increase_width) {
273 if (((host.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
274 && layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY))
275 || !layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY)) {
276 lp.cellX --;
277 info.cellX --;
278 }
279 lp.cellHSpan ++;
280 info.spanX ++;
281 } else if (action == R.string.action_decrease_width) {
282 lp.cellHSpan --;
283 info.spanX --;
284 } else if (action == R.string.action_increase_height) {
285 if (!layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1)) {
286 lp.cellY --;
287 info.cellY --;
288 }
289 lp.cellVSpan ++;
290 info.spanY ++;
291 } else if (action == R.string.action_decrease_height) {
292 lp.cellVSpan --;
293 info.spanY --;
294 }
295
296 layout.markCellsAsOccupiedForView(host);
297 Rect sizeRange = new Rect();
298 AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, sizeRange);
299 ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null,
300 sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom);
301 host.requestLayout();
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800302 mLauncher.getModelWriter().updateItemInDatabase(info);
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700303 announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
304 }
305
Adam Cohen091440a2015-03-18 14:16:05 -0700306 @Thunk void announceConfirmation(int resId) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800307 announceConfirmation(mLauncher.getResources().getString(resId));
308 }
309
Adam Cohen091440a2015-03-18 14:16:05 -0700310 @Thunk void announceConfirmation(String confirmation) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800311 mLauncher.getDragLayer().announceForAccessibility(confirmation);
312
313 }
314
315 public boolean isInAccessibleDrag() {
316 return mDragInfo != null;
317 }
318
319 public DragInfo getDragInfo() {
320 return mDragInfo;
321 }
322
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700323 /**
324 * @param clickedTarget the actual view that was clicked
325 * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
326 * as the actual drop location otherwise the views center is used.
327 */
328 public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
Adam Cohenc9735cf2015-01-23 16:11:55 -0800329 String confirmation) {
330 if (!isInAccessibleDrag()) return;
331
332 int[] loc = new int[2];
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700333 if (dropLocation == null) {
334 loc[0] = clickedTarget.getWidth() / 2;
335 loc[1] = clickedTarget.getHeight() / 2;
336 } else {
337 loc[0] = dropLocation.centerX();
338 loc[1] = dropLocation.centerY();
339 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800340
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700341 mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800342 mLauncher.getDragController().completeAccessibleDrag(loc);
343
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700344 if (!TextUtils.isEmpty(confirmation)) {
345 announceConfirmation(confirmation);
346 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800347 }
348
349 public void beginAccessibleDrag(View item, ItemInfo info) {
350 mDragInfo = new DragInfo();
351 mDragInfo.info = info;
352 mDragInfo.item = item;
353 mDragInfo.dragType = DragType.ICON;
354 if (info instanceof FolderInfo) {
355 mDragInfo.dragType = DragType.FOLDER;
356 } else if (info instanceof LauncherAppWidgetInfo) {
357 mDragInfo.dragType = DragType.WIDGET;
358 }
359
360 CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
361
362 Rect pos = new Rect();
363 mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800364 mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
Sunny Goyale9b651e2015-04-24 11:44:51 -0700365
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700366 Folder folder = Folder.getOpen(mLauncher);
Sunny Goyale9b651e2015-04-24 11:44:51 -0700367 if (folder != null) {
Jonathan Miranda8701cd52017-07-13 19:26:46 +0000368 if (!folder.getItemsInReadingOrder().contains(item)) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700369 folder.close(true);
Sunny Goyal94b510c2016-08-16 15:36:48 -0700370 folder = null;
Sunny Goyale9b651e2015-04-24 11:44:51 -0700371 }
372 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800373
Sunny Goyal94b510c2016-08-16 15:36:48 -0700374 mLauncher.getDragController().addDragListener(this);
375
376 DragOptions options = new DragOptions();
377 options.isAccessibleDrag = true;
378 if (folder != null) {
379 folder.startDrag(cellInfo.cell, options);
380 } else {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700381 mLauncher.getWorkspace().startDrag(cellInfo, options);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800382 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800383 }
384
Sunny Goyal45478022015-06-08 16:52:41 -0700385 @Override
Sunny Goyal94b510c2016-08-16 15:36:48 -0700386 public void onDragStart(DragObject dragObject, DragOptions options) {
Sunny Goyal45478022015-06-08 16:52:41 -0700387 // No-op
Adam Cohenc9735cf2015-01-23 16:11:55 -0800388 }
389
Sunny Goyal45478022015-06-08 16:52:41 -0700390 @Override
391 public void onDragEnd() {
392 mLauncher.getDragController().removeDragListener(this);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800393 mDragInfo = null;
Adam Cohenc9735cf2015-01-23 16:11:55 -0800394 }
Sunny Goyala9116722015-04-29 13:55:58 -0700395
396 /**
397 * Find empty space on the workspace and returns the screenId.
398 */
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700399 protected long findSpaceOnWorkspace(ItemInfo info, int[] outCoordinates) {
Sunny Goyala9116722015-04-29 13:55:58 -0700400 Workspace workspace = mLauncher.getWorkspace();
401 ArrayList<Long> workspaceScreens = workspace.getScreenOrder();
402 long screenId;
403
404 // First check if there is space on the current screen.
405 int screenIndex = workspace.getCurrentPage();
406 screenId = workspaceScreens.get(screenIndex);
407 CellLayout layout = (CellLayout) workspace.getPageAt(screenIndex);
408
409 boolean found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
Sunny Goyal7ce471b2017-08-02 03:37:39 -0700410 screenIndex = 0;
Sunny Goyala9116722015-04-29 13:55:58 -0700411 while (!found && screenIndex < workspaceScreens.size()) {
412 screenId = workspaceScreens.get(screenIndex);
413 layout = (CellLayout) workspace.getPageAt(screenIndex);
414 found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
415 screenIndex++;
416 }
417
418 if (found) {
419 return screenId;
420 }
421
422 workspace.addExtraEmptyScreen();
423 screenId = workspace.commitExtraEmptyScreen();
424 layout = workspace.getScreenWithId(screenId);
425 found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
426
427 if (!found) {
428 Log.wtf(TAG, "Not enough space on an empty screen");
429 }
430 return screenId;
431 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800432}