blob: 2b3a113f370a019163b3f619cd329e9e64bd6675 [file] [log] [blame]
Sunny Goyal83a8f042015-05-19 12:52:12 -07001package com.android.launcher3.accessibility;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08002
Sunny Goyal3e3f44c2017-10-23 17:14:52 -07003import static com.android.launcher3.LauncherState.NORMAL;
4
Sunny Goyal9ca9c132015-04-29 14:57:22 -07005import android.app.AlertDialog;
6import android.appwidget.AppWidgetProviderInfo;
7import android.content.DialogInterface;
Adam Cohenc9735cf2015-01-23 16:11:55 -08008import android.graphics.Rect;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08009import android.os.Bundle;
Sunny Goyal9ae77772015-04-29 16:30:23 -070010import android.os.Handler;
Sunny Goyal1a70cef2015-04-22 11:29:51 -070011import android.text.TextUtils;
Sunny Goyala9116722015-04-29 13:55:58 -070012import android.util.Log;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080013import android.util.SparseArray;
14import android.view.View;
15import android.view.View.AccessibilityDelegate;
16import android.view.accessibility.AccessibilityNodeInfo;
17import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
18
Sunny Goyal83a8f042015-05-19 12:52:12 -070019import com.android.launcher3.AppInfo;
20import com.android.launcher3.AppWidgetResizeFrame;
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070021import com.android.launcher3.BubbleTextView;
Sunny Goyal83a8f042015-05-19 12:52:12 -070022import com.android.launcher3.CellLayout;
23import com.android.launcher3.DeleteDropTarget;
Sunny Goyal94b510c2016-08-16 15:36:48 -070024import com.android.launcher3.DropTarget.DragObject;
Sunny Goyal83a8f042015-05-19 12:52:12 -070025import com.android.launcher3.FolderInfo;
26import com.android.launcher3.InfoDropTarget;
27import com.android.launcher3.ItemInfo;
28import com.android.launcher3.Launcher;
29import com.android.launcher3.LauncherAppWidgetHostView;
30import com.android.launcher3.LauncherAppWidgetInfo;
Sunny Goyal83a8f042015-05-19 12:52:12 -070031import com.android.launcher3.LauncherSettings;
Sunny Goyal3e3f44c2017-10-23 17:14:52 -070032import com.android.launcher3.LauncherSettings.Favorites;
Sunny Goyal83a8f042015-05-19 12:52:12 -070033import com.android.launcher3.PendingAddItemInfo;
34import com.android.launcher3.R;
35import com.android.launcher3.ShortcutInfo;
36import com.android.launcher3.UninstallDropTarget;
37import com.android.launcher3.Workspace;
Vadim Tryshevfedca432015-08-19 17:55:02 -070038import com.android.launcher3.dragndrop.DragController.DragListener;
Sunny Goyala52ecb02016-12-16 15:04:51 -080039import com.android.launcher3.dragndrop.DragOptions;
40import com.android.launcher3.folder.Folder;
Mario Bertschlerc06af332017-03-28 12:23:22 -070041import com.android.launcher3.popup.PopupContainerWithArrow;
Tony18c4aa42017-05-10 21:23:57 -050042import com.android.launcher3.shortcuts.DeepShortcutManager;
Adam Cohen091440a2015-03-18 14:16:05 -070043import com.android.launcher3.util.Thunk;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080044
45import java.util.ArrayList;
46
Sunny Goyal45478022015-06-08 16:52:41 -070047public class LauncherAccessibilityDelegate extends AccessibilityDelegate implements DragListener {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080048
Sunny Goyala9116722015-04-29 13:55:58 -070049 private static final String TAG = "LauncherAccessibilityDelegate";
50
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070051 protected static final int REMOVE = R.id.action_remove;
52 protected static final int INFO = R.id.action_info;
53 protected static final int UNINSTALL = R.id.action_uninstall;
54 protected static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
55 protected static final int MOVE = R.id.action_move;
56 protected static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
57 protected static final int RESIZE = R.id.action_resize;
Sunny Goyal66b24572016-09-21 15:57:55 -070058 public static final int DEEP_SHORTCUTS = R.id.action_deep_shortcuts;
Adam Cohenc9735cf2015-01-23 16:11:55 -080059
Sunny Goyale9b651e2015-04-24 11:44:51 -070060 public enum DragType {
Adam Cohenc9735cf2015-01-23 16:11:55 -080061 ICON,
62 FOLDER,
63 WIDGET
64 }
65
66 public static class DragInfo {
Sunny Goyale9b651e2015-04-24 11:44:51 -070067 public DragType dragType;
68 public ItemInfo info;
69 public View item;
Adam Cohenc9735cf2015-01-23 16:11:55 -080070 }
71
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070072 protected final SparseArray<AccessibilityAction> mActions = new SparseArray<>();
Adam Cohen091440a2015-03-18 14:16:05 -070073 @Thunk final Launcher mLauncher;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080074
Sunny Goyale9b651e2015-04-24 11:44:51 -070075 private DragInfo mDragInfo = null;
Sunny Goyale9b651e2015-04-24 11:44:51 -070076
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080077 public LauncherAccessibilityDelegate(Launcher launcher) {
78 mLauncher = launcher;
79
80 mActions.put(REMOVE, new AccessibilityAction(REMOVE,
Tony Wickham9aae47f2015-10-01 13:04:22 -070081 launcher.getText(R.string.remove_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080082 mActions.put(INFO, new AccessibilityAction(INFO,
Tony Wickham9aae47f2015-10-01 13:04:22 -070083 launcher.getText(R.string.app_info_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080084 mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
Tony Wickham9aae47f2015-10-01 13:04:22 -070085 launcher.getText(R.string.uninstall_drop_target_label)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080086 mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
87 launcher.getText(R.string.action_add_to_workspace)));
Adam Cohenc9735cf2015-01-23 16:11:55 -080088 mActions.put(MOVE, new AccessibilityAction(MOVE,
89 launcher.getText(R.string.action_move)));
Sunny Goyal9ae77772015-04-29 16:30:23 -070090 mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE,
91 launcher.getText(R.string.action_move_to_workspace)));
Sunny Goyal9ca9c132015-04-29 14:57:22 -070092 mActions.put(RESIZE, new AccessibilityAction(RESIZE,
93 launcher.getText(R.string.action_resize)));
Sunny Goyal3ffa64d2016-07-25 13:54:32 -070094 mActions.put(DEEP_SHORTCUTS, new AccessibilityAction(DEEP_SHORTCUTS,
95 launcher.getText(R.string.action_deep_shortcut)));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080096 }
97
98 @Override
99 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
100 super.onInitializeAccessibilityNodeInfo(host, info);
Sunny Goyal66b24572016-09-21 15:57:55 -0700101 addSupportedActions(host, info, false);
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700102 }
103
Sunny Goyal66b24572016-09-21 15:57:55 -0700104 public void addSupportedActions(View host, AccessibilityNodeInfo info, boolean fromKeyboard) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800105 if (!(host.getTag() instanceof ItemInfo)) return;
106 ItemInfo item = (ItemInfo) host.getTag();
107
Sunny Goyal66b24572016-09-21 15:57:55 -0700108 // If the request came from keyboard, do not add custom shortcuts as that is already
109 // exposed as a direct shortcut
Tony18c4aa42017-05-10 21:23:57 -0500110 if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) {
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700111 info.addAction(mActions.get(DEEP_SHORTCUTS));
112 }
113
Tony Wickham9aae47f2015-10-01 13:04:22 -0700114 if (DeleteDropTarget.supportsAccessibleDrop(item)) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700115 info.addAction(mActions.get(REMOVE));
116 }
117 if (UninstallDropTarget.supportsDrop(host.getContext(), item)) {
118 info.addAction(mActions.get(UNINSTALL));
119 }
Sunny Goyal8ad02b82016-12-29 13:31:43 -0800120 if (InfoDropTarget.supportsDrop(host.getContext(), item)) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700121 info.addAction(mActions.get(INFO));
122 }
123
Sunny Goyal66b24572016-09-21 15:57:55 -0700124 // Do not add move actions for keyboard request as this uses virtual nodes.
125 if (!fromKeyboard && ((item instanceof ShortcutInfo)
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800126 || (item instanceof LauncherAppWidgetInfo)
Sunny Goyal66b24572016-09-21 15:57:55 -0700127 || (item instanceof FolderInfo))) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800128 info.addAction(mActions.get(MOVE));
Sunny Goyal9ae77772015-04-29 16:30:23 -0700129
130 if (item.container >= 0) {
131 info.addAction(mActions.get(MOVE_TO_WORKSPACE));
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700132 } else if (item instanceof LauncherAppWidgetInfo) {
133 if (!getSupportedResizeActions(host, (LauncherAppWidgetInfo) item).isEmpty()) {
134 info.addAction(mActions.get(RESIZE));
135 }
Sunny Goyal9ae77772015-04-29 16:30:23 -0700136 }
Adam Cohen6e92f052016-06-07 14:30:10 -0700137 }
138
139 if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800140 info.addAction(mActions.get(ADD_TO_WORKSPACE));
141 }
142 }
143
144 @Override
145 public boolean performAccessibilityAction(View host, int action, Bundle args) {
146 if ((host.getTag() instanceof ItemInfo)
147 && performAction(host, (ItemInfo) host.getTag(), action)) {
148 return true;
149 }
150 return super.performAccessibilityAction(host, action, args);
151 }
152
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700153 public boolean performAction(final View host, final ItemInfo item, int action) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800154 if (action == REMOVE) {
Sunny Goyale78e3d72015-09-24 11:23:31 -0700155 DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host);
156 return true;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800157 } else if (action == INFO) {
Sunny Goyal3dce5f32017-10-05 11:40:05 -0700158 InfoDropTarget.startDetailsActivityForInfo(item, mLauncher, null, null);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800159 return true;
160 } else if (action == UNINSTALL) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700161 return UninstallDropTarget.startUninstallActivity(mLauncher, item);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800162 } else if (action == MOVE) {
163 beginAccessibleDrag(host, item);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800164 } else if (action == ADD_TO_WORKSPACE) {
Sunny Goyala9116722015-04-29 13:55:58 -0700165 final int[] coordinates = new int[2];
166 final long screenId = findSpaceOnWorkspace(item, coordinates);
Sunny Goyal3e3f44c2017-10-23 17:14:52 -0700167 mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800168
169 @Override
Sunny Goyala9116722015-04-29 13:55:58 -0700170 public void run() {
171 if (item instanceof AppInfo) {
172 ShortcutInfo info = ((AppInfo) item).makeShortcut();
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800173 mLauncher.getModelWriter().addItemToDatabase(info,
Sunny Goyal3e3f44c2017-10-23 17:14:52 -0700174 Favorites.CONTAINER_DESKTOP,
Sunny Goyala9116722015-04-29 13:55:58 -0700175 screenId, coordinates[0], coordinates[1]);
176
177 ArrayList<ItemInfo> itemList = new ArrayList<>();
178 itemList.add(info);
Sunny Goyalb23980c2017-08-17 07:45:25 -0700179 mLauncher.bindItems(itemList, true);
Sunny Goyala9116722015-04-29 13:55:58 -0700180 } else if (item instanceof PendingAddItemInfo) {
181 PendingAddItemInfo info = (PendingAddItemInfo) item;
182 Workspace workspace = mLauncher.getWorkspace();
183 workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
Sunny Goyal3e3f44c2017-10-23 17:14:52 -0700184 mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP,
Sunny Goyala9116722015-04-29 13:55:58 -0700185 screenId, coordinates, info.spanX, info.spanY);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800186 }
Sunny Goyala9116722015-04-29 13:55:58 -0700187 announceConfirmation(R.string.item_added_to_workspace);
188 }
189 });
190 return true;
Sunny Goyal9ae77772015-04-29 16:30:23 -0700191 } else if (action == MOVE_TO_WORKSPACE) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700192 Folder folder = Folder.getOpen(mLauncher);
193 folder.close(true);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700194 ShortcutInfo info = (ShortcutInfo) item;
Sunny Goyalc52ba712016-04-05 15:59:05 -0700195 folder.getInfo().remove(info, false);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700196
197 final int[] coordinates = new int[2];
198 final long screenId = findSpaceOnWorkspace(item, coordinates);
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800199 mLauncher.getModelWriter().moveItemInDatabase(info,
Sunny Goyal9ae77772015-04-29 16:30:23 -0700200 LauncherSettings.Favorites.CONTAINER_DESKTOP,
201 screenId, coordinates[0], coordinates[1]);
202
203 // Bind the item in next frame so that if a new workspace page was created,
204 // it will get laid out.
205 new Handler().post(new Runnable() {
206
207 @Override
208 public void run() {
209 ArrayList<ItemInfo> itemList = new ArrayList<>();
210 itemList.add(item);
Sunny Goyalb23980c2017-08-17 07:45:25 -0700211 mLauncher.bindItems(itemList, true);
Sunny Goyal9ae77772015-04-29 16:30:23 -0700212 announceConfirmation(R.string.item_moved);
213 }
214 });
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700215 } else if (action == RESIZE) {
216 final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
217 final ArrayList<Integer> actions = getSupportedResizeActions(host, info);
218 CharSequence[] labels = new CharSequence[actions.size()];
219 for (int i = 0; i < actions.size(); i++) {
220 labels[i] = mLauncher.getText(actions.get(i));
221 }
222
223 new AlertDialog.Builder(mLauncher)
224 .setTitle(R.string.action_resize)
225 .setItems(labels, new DialogInterface.OnClickListener() {
226
227 @Override
228 public void onClick(DialogInterface dialog, int which) {
229 performResizeAction(actions.get(which), host, info);
230 dialog.dismiss();
231 }
232 })
233 .show();
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700234 return true;
235 } else if (action == DEEP_SHORTCUTS) {
Tony Wickham540913e2017-01-23 11:47:51 -0800236 return PopupContainerWithArrow.showForIcon((BubbleTextView) host) != null;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800237 }
238 return false;
239 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800240
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700241 private ArrayList<Integer> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) {
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700242 ArrayList<Integer> actions = new ArrayList<>();
243
Sunny Goyald3d8c952015-06-01 10:09:06 -0700244 AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo();
245 if (providerInfo == null) {
246 return actions;
247 }
248
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700249 CellLayout layout = (CellLayout) host.getParent().getParent();
250 if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
251 if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
252 layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
253 actions.add(R.string.action_increase_width);
254 }
255
256 if (info.spanX > info.minSpanX && info.spanX > 1) {
257 actions.add(R.string.action_decrease_width);
258 }
259 }
260
261 if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
262 if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) ||
263 layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) {
264 actions.add(R.string.action_increase_height);
265 }
266
267 if (info.spanY > info.minSpanY && info.spanY > 1) {
268 actions.add(R.string.action_decrease_height);
269 }
270 }
271 return actions;
272 }
273
Sunny Goyal316490e2015-06-02 09:38:28 -0700274 @Thunk void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700275 CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams();
276 CellLayout layout = (CellLayout) host.getParent().getParent();
277 layout.markCellsAsUnoccupiedForView(host);
278
279 if (action == R.string.action_increase_width) {
280 if (((host.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
281 && layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY))
282 || !layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY)) {
283 lp.cellX --;
284 info.cellX --;
285 }
286 lp.cellHSpan ++;
287 info.spanX ++;
288 } else if (action == R.string.action_decrease_width) {
289 lp.cellHSpan --;
290 info.spanX --;
291 } else if (action == R.string.action_increase_height) {
292 if (!layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1)) {
293 lp.cellY --;
294 info.cellY --;
295 }
296 lp.cellVSpan ++;
297 info.spanY ++;
298 } else if (action == R.string.action_decrease_height) {
299 lp.cellVSpan --;
300 info.spanY --;
301 }
302
303 layout.markCellsAsOccupiedForView(host);
304 Rect sizeRange = new Rect();
305 AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, sizeRange);
306 ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null,
307 sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom);
308 host.requestLayout();
Sunny Goyal43bf11d2017-02-02 13:52:53 -0800309 mLauncher.getModelWriter().updateItemInDatabase(info);
Sunny Goyal9ca9c132015-04-29 14:57:22 -0700310 announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
311 }
312
Adam Cohen091440a2015-03-18 14:16:05 -0700313 @Thunk void announceConfirmation(int resId) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800314 announceConfirmation(mLauncher.getResources().getString(resId));
315 }
316
Adam Cohen091440a2015-03-18 14:16:05 -0700317 @Thunk void announceConfirmation(String confirmation) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800318 mLauncher.getDragLayer().announceForAccessibility(confirmation);
319
320 }
321
322 public boolean isInAccessibleDrag() {
323 return mDragInfo != null;
324 }
325
326 public DragInfo getDragInfo() {
327 return mDragInfo;
328 }
329
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700330 /**
331 * @param clickedTarget the actual view that was clicked
332 * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
333 * as the actual drop location otherwise the views center is used.
334 */
335 public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
Adam Cohenc9735cf2015-01-23 16:11:55 -0800336 String confirmation) {
337 if (!isInAccessibleDrag()) return;
338
339 int[] loc = new int[2];
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700340 if (dropLocation == null) {
341 loc[0] = clickedTarget.getWidth() / 2;
342 loc[1] = clickedTarget.getHeight() / 2;
343 } else {
344 loc[0] = dropLocation.centerX();
345 loc[1] = dropLocation.centerY();
346 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800347
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700348 mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800349 mLauncher.getDragController().completeAccessibleDrag(loc);
350
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700351 if (!TextUtils.isEmpty(confirmation)) {
352 announceConfirmation(confirmation);
353 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800354 }
355
356 public void beginAccessibleDrag(View item, ItemInfo info) {
357 mDragInfo = new DragInfo();
358 mDragInfo.info = info;
359 mDragInfo.item = item;
360 mDragInfo.dragType = DragType.ICON;
361 if (info instanceof FolderInfo) {
362 mDragInfo.dragType = DragType.FOLDER;
363 } else if (info instanceof LauncherAppWidgetInfo) {
364 mDragInfo.dragType = DragType.WIDGET;
365 }
366
367 CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
368
369 Rect pos = new Rect();
370 mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800371 mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
Sunny Goyale9b651e2015-04-24 11:44:51 -0700372
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700373 Folder folder = Folder.getOpen(mLauncher);
Sunny Goyale9b651e2015-04-24 11:44:51 -0700374 if (folder != null) {
Jonathan Miranda8701cd52017-07-13 19:26:46 +0000375 if (!folder.getItemsInReadingOrder().contains(item)) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700376 folder.close(true);
Sunny Goyal94b510c2016-08-16 15:36:48 -0700377 folder = null;
Sunny Goyale9b651e2015-04-24 11:44:51 -0700378 }
379 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800380
Sunny Goyal94b510c2016-08-16 15:36:48 -0700381 mLauncher.getDragController().addDragListener(this);
382
383 DragOptions options = new DragOptions();
384 options.isAccessibleDrag = true;
385 if (folder != null) {
386 folder.startDrag(cellInfo.cell, options);
387 } else {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700388 mLauncher.getWorkspace().startDrag(cellInfo, options);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800389 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800390 }
391
Sunny Goyal45478022015-06-08 16:52:41 -0700392 @Override
Sunny Goyal94b510c2016-08-16 15:36:48 -0700393 public void onDragStart(DragObject dragObject, DragOptions options) {
Sunny Goyal45478022015-06-08 16:52:41 -0700394 // No-op
Adam Cohenc9735cf2015-01-23 16:11:55 -0800395 }
396
Sunny Goyal45478022015-06-08 16:52:41 -0700397 @Override
398 public void onDragEnd() {
399 mLauncher.getDragController().removeDragListener(this);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800400 mDragInfo = null;
Adam Cohenc9735cf2015-01-23 16:11:55 -0800401 }
Sunny Goyala9116722015-04-29 13:55:58 -0700402
403 /**
404 * Find empty space on the workspace and returns the screenId.
405 */
Sunny Goyal3ffa64d2016-07-25 13:54:32 -0700406 protected long findSpaceOnWorkspace(ItemInfo info, int[] outCoordinates) {
Sunny Goyala9116722015-04-29 13:55:58 -0700407 Workspace workspace = mLauncher.getWorkspace();
408 ArrayList<Long> workspaceScreens = workspace.getScreenOrder();
409 long screenId;
410
411 // First check if there is space on the current screen.
412 int screenIndex = workspace.getCurrentPage();
413 screenId = workspaceScreens.get(screenIndex);
414 CellLayout layout = (CellLayout) workspace.getPageAt(screenIndex);
415
416 boolean found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
Sunny Goyal7ce471b2017-08-02 03:37:39 -0700417 screenIndex = 0;
Sunny Goyala9116722015-04-29 13:55:58 -0700418 while (!found && screenIndex < workspaceScreens.size()) {
419 screenId = workspaceScreens.get(screenIndex);
420 layout = (CellLayout) workspace.getPageAt(screenIndex);
421 found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
422 screenIndex++;
423 }
424
425 if (found) {
426 return screenId;
427 }
428
429 workspace.addExtraEmptyScreen();
430 screenId = workspace.commitExtraEmptyScreen();
431 layout = workspace.getScreenWithId(screenId);
432 found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
433
434 if (!found) {
435 Log.wtf(TAG, "Not enough space on an empty screen");
436 }
437 return screenId;
438 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800439}