LauncherAccessibilityDelegate.java revision fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834
183a8f042adda926489494dff217c15ab696139b4Sunny Goyalpackage com.android.launcher3.accessibility;
271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.annotation.TargetApi;
49ca9c1316da8382c1f663973072731033b5e533aSunny Goyalimport android.app.AlertDialog;
59ca9c1316da8382c1f663973072731033b5e533aSunny Goyalimport android.appwidget.AppWidgetProviderInfo;
69ca9c1316da8382c1f663973072731033b5e533aSunny Goyalimport android.content.DialogInterface;
7c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohenimport android.graphics.Rect;
871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.os.Build;
971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.os.Bundle;
109ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyalimport android.os.Handler;
111a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyalimport android.text.TextUtils;
12a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyalimport android.util.Log;
1371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.util.SparseArray;
1471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.view.View;
1571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.view.View.AccessibilityDelegate;
1671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.view.accessibility.AccessibilityNodeInfo;
1771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
1871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
1983a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.AppInfo;
2083a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.AppWidgetResizeFrame;
2183a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.CellLayout;
2283a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.DeleteDropTarget;
2345478022977de9025dfc887cc1507d90d15febf8Sunny Goyalimport com.android.launcher3.DragSource;
2483a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Folder;
2583a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.FolderInfo;
2683a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.InfoDropTarget;
2783a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.ItemInfo;
2883a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Launcher;
2983a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherAppWidgetHostView;
3083a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherAppWidgetInfo;
3183a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherModel;
3283a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherSettings;
3383a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.PendingAddItemInfo;
3483a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.R;
3583a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.ShortcutInfo;
3683a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.UninstallDropTarget;
3783a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Workspace;
38fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.dragndrop.DragController.DragListener;
39091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
4071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
4171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport java.util.ArrayList;
4271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
4371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal@TargetApi(Build.VERSION_CODES.LOLLIPOP)
4445478022977de9025dfc887cc1507d90d15febf8Sunny Goyalpublic class LauncherAccessibilityDelegate extends AccessibilityDelegate implements DragListener {
4571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
46a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final String TAG = "LauncherAccessibilityDelegate";
47a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
48a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int REMOVE = R.id.action_remove;
49a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int INFO = R.id.action_info;
50a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int UNINSTALL = R.id.action_uninstall;
51a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
52a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int MOVE = R.id.action_move;
539ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal    private static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
549ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    private static final int RESIZE = R.id.action_resize;
55c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
56e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    public enum DragType {
57c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        ICON,
58c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        FOLDER,
59c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        WIDGET
60c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
61c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
62c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public static class DragInfo {
63e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public DragType dragType;
64e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public ItemInfo info;
65e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public View item;
66c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
67c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
68a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private final SparseArray<AccessibilityAction> mActions = new SparseArray<>();
69091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk final Launcher mLauncher;
7071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
71e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    private DragInfo mDragInfo = null;
72e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    private AccessibilityDragSource mDragSource = null;
73e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
7471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public LauncherAccessibilityDelegate(Launcher launcher) {
7571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mLauncher = launcher;
7671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
7771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(REMOVE, new AccessibilityAction(REMOVE,
7871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.delete_target_label)));
7971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(INFO, new AccessibilityAction(INFO,
8071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.info_target_label)));
8171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
8271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.delete_target_uninstall_label)));
8371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
8471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.action_add_to_workspace)));
85c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mActions.put(MOVE, new AccessibilityAction(MOVE,
86c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen                launcher.getText(R.string.action_move)));
879ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal        mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE,
889ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                launcher.getText(R.string.action_move_to_workspace)));
899ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        mActions.put(RESIZE, new AccessibilityAction(RESIZE,
909ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        launcher.getText(R.string.action_resize)));
9171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
9271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
9371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    @Override
9471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
9571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        super.onInitializeAccessibilityNodeInfo(host, info);
9671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if (!(host.getTag() instanceof ItemInfo)) return;
9771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        ItemInfo item = (ItemInfo) host.getTag();
9871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
991a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (DeleteDropTarget.supportsDrop(item)) {
1001a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(REMOVE));
1011a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1021a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (UninstallDropTarget.supportsDrop(host.getContext(), item)) {
1031a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(UNINSTALL));
1041a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1051a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (InfoDropTarget.supportsDrop(host.getContext(), item)) {
1061a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(INFO));
1071a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1081a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal
10971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if ((item instanceof ShortcutInfo)
11071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                || (item instanceof LauncherAppWidgetInfo)
11171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                || (item instanceof FolderInfo)) {
112c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            info.addAction(mActions.get(MOVE));
1139ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1149ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            if (item.container >= 0) {
1159ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                info.addAction(mActions.get(MOVE_TO_WORKSPACE));
1169ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            } else if (item instanceof LauncherAppWidgetInfo) {
1179ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                if (!getSupportedResizeActions(host, (LauncherAppWidgetInfo) item).isEmpty()) {
1189ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    info.addAction(mActions.get(RESIZE));
1199ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                }
1209ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            }
1211a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        } if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
12271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            info.addAction(mActions.get(ADD_TO_WORKSPACE));
12371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
12471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
12571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
12671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    @Override
12771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public boolean performAccessibilityAction(View host, int action, Bundle args) {
12871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if ((host.getTag() instanceof ItemInfo)
12971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                && performAction(host, (ItemInfo) host.getTag(), action)) {
13071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            return true;
13171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
13271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        return super.performAccessibilityAction(host, action, args);
13371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
13471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
1359ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    public boolean performAction(final View host, final ItemInfo item, int action) {
13671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if (action == REMOVE) {
137c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) {
1381a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal                announceConfirmation(R.string.item_removed);
139c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen                return true;
140c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            }
141c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            return false;
14271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == INFO) {
14371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
14471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            return true;
14571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == UNINSTALL) {
1461a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            return UninstallDropTarget.startUninstallActivity(mLauncher, item);
147c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        } else if (action == MOVE) {
148c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            beginAccessibleDrag(host, item);
14971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == ADD_TO_WORKSPACE) {
150a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            final int[] coordinates = new int[2];
151a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            final long screenId = findSpaceOnWorkspace(item, coordinates);
152a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            mLauncher.showWorkspace(true, new Runnable() {
15371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
15471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                @Override
155a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                public void run() {
156a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    if (item instanceof AppInfo) {
157a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        ShortcutInfo info = ((AppInfo) item).makeShortcut();
158a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        LauncherModel.addItemToDatabase(mLauncher, info,
159a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                LauncherSettings.Favorites.CONTAINER_DESKTOP,
160a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                screenId, coordinates[0], coordinates[1]);
161a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
162a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        ArrayList<ItemInfo> itemList = new ArrayList<>();
163a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        itemList.add(info);
164a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        mLauncher.bindItems(itemList, 0, itemList.size(), true);
165a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    } else if (item instanceof PendingAddItemInfo) {
166a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        PendingAddItemInfo info = (PendingAddItemInfo) item;
167a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        Workspace workspace = mLauncher.getWorkspace();
168a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
169a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        mLauncher.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
170a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                screenId, coordinates, info.spanX, info.spanY);
17171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                    }
172a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    announceConfirmation(R.string.item_added_to_workspace);
173a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                }
174a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            });
175a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            return true;
1769ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal        } else if (action == MOVE_TO_WORKSPACE) {
1779ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            Folder folder = mLauncher.getWorkspace().getOpenFolder();
1789ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            mLauncher.closeFolder(folder);
1799ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            ShortcutInfo info = (ShortcutInfo) item;
1809ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            folder.getInfo().remove(info);
1819ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1829ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            final int[] coordinates = new int[2];
1839ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            final long screenId = findSpaceOnWorkspace(item, coordinates);
1849ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            LauncherModel.moveItemInDatabase(mLauncher, info,
1859ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    LauncherSettings.Favorites.CONTAINER_DESKTOP,
1869ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    screenId, coordinates[0], coordinates[1]);
1879ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1889ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            // Bind the item in next frame so that if a new workspace page was created,
1899ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            // it will get laid out.
1909ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            new Handler().post(new Runnable() {
1919ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1929ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                @Override
1939ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                public void run() {
1949ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    ArrayList<ItemInfo> itemList = new ArrayList<>();
1959ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    itemList.add(item);
1969ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    mLauncher.bindItems(itemList, 0, itemList.size(), true);
1979ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    announceConfirmation(R.string.item_moved);
1989ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                }
1999ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            });
2009ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == RESIZE) {
2019ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
2029ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            final ArrayList<Integer> actions = getSupportedResizeActions(host, info);
2039ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            CharSequence[] labels = new CharSequence[actions.size()];
2049ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            for (int i = 0; i < actions.size(); i++) {
2059ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                labels[i] = mLauncher.getText(actions.get(i));
2069ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2079ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2089ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            new AlertDialog.Builder(mLauncher)
2099ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .setTitle(R.string.action_resize)
2109ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .setItems(labels, new DialogInterface.OnClickListener() {
2119ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2129ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    @Override
2139ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    public void onClick(DialogInterface dialog, int which) {
2149ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        performResizeAction(actions.get(which), host, info);
2159ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        dialog.dismiss();
2169ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    }
2179ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                })
2189ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .show();
21971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
22071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        return false;
22171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
222c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
2239ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    private ArrayList<Integer> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) {
2249ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        ArrayList<Integer> actions = new ArrayList<>();
2259ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
226d3d8c958a28aee7815fa2bc81b5c0b79903d51adSunny Goyal        AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo();
227d3d8c958a28aee7815fa2bc81b5c0b79903d51adSunny Goyal        if (providerInfo == null) {
228d3d8c958a28aee7815fa2bc81b5c0b79903d51adSunny Goyal            return actions;
229d3d8c958a28aee7815fa2bc81b5c0b79903d51adSunny Goyal        }
230d3d8c958a28aee7815fa2bc81b5c0b79903d51adSunny Goyal
2319ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout layout = (CellLayout) host.getParent().getParent();
2329ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
2339ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
2349ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
2359ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_increase_width);
2369ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2379ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2389ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (info.spanX > info.minSpanX && info.spanX > 1) {
2399ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_decrease_width);
2409ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2419ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2429ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2439ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
2449ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) ||
2459ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) {
2469ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_increase_height);
2479ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2489ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2499ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (info.spanY > info.minSpanY && info.spanY > 1) {
2509ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_decrease_height);
2519ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2529ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2539ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        return actions;
2549ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    }
2559ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
256316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal    @Thunk void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
2579ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams();
2589ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout layout = (CellLayout) host.getParent().getParent();
2599ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        layout.markCellsAsUnoccupiedForView(host);
2609ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2619ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if (action == R.string.action_increase_width) {
2629ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (((host.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
2639ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    && layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY))
2649ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    || !layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY)) {
2659ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                lp.cellX --;
2669ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                info.cellX --;
2679ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2689ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellHSpan ++;
2699ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanX ++;
2709ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_decrease_width) {
2719ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellHSpan --;
2729ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanX --;
2739ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_increase_height) {
2749ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (!layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1)) {
2759ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                lp.cellY --;
2769ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                info.cellY --;
2779ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2789ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellVSpan ++;
2799ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanY ++;
2809ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_decrease_height) {
2819ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellVSpan --;
2829ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanY --;
2839ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2849ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2859ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        layout.markCellsAsOccupiedForView(host);
2869ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        Rect sizeRange = new Rect();
2879ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, sizeRange);
2889ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null,
2899ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom);
2909ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        host.requestLayout();
2919ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        LauncherModel.updateItemInDatabase(mLauncher, info);
2929ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
2939ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    }
2949ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
295091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk void announceConfirmation(int resId) {
296c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        announceConfirmation(mLauncher.getResources().getString(resId));
297c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
298c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
299091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk void announceConfirmation(String confirmation) {
300c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragLayer().announceForAccessibility(confirmation);
301c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
302c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
303c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
304c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public boolean isInAccessibleDrag() {
305c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        return mDragInfo != null;
306c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
307c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
308c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public DragInfo getDragInfo() {
309c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        return mDragInfo;
310c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
311c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
3121a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal    /**
3131a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * @param clickedTarget the actual view that was clicked
3141a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
3151a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * as the actual drop location otherwise the views center is used.
3161a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     */
3171a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal    public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
318c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            String confirmation) {
319c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        if (!isInAccessibleDrag()) return;
320c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
321c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        int[] loc = new int[2];
3221a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (dropLocation == null) {
3231a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[0] = clickedTarget.getWidth() / 2;
3241a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[1] = clickedTarget.getHeight() / 2;
3251a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        } else {
3261a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[0] = dropLocation.centerX();
3271a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[1] = dropLocation.centerY();
3281a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
329c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
3301a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
331c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragController().completeAccessibleDrag(loc);
332c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
3331a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (!TextUtils.isEmpty(confirmation)) {
3341a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            announceConfirmation(confirmation);
3351a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
336c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
337c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
338c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public void beginAccessibleDrag(View item, ItemInfo info) {
339c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo = new DragInfo();
340c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.info = info;
341c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.item = item;
342c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.dragType = DragType.ICON;
343c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        if (info instanceof FolderInfo) {
344c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragInfo.dragType = DragType.FOLDER;
345c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        } else if (info instanceof LauncherAppWidgetInfo) {
346c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragInfo.dragType = DragType.WIDGET;
347c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
348c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
349c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
350c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
351c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        Rect pos = new Rect();
352c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
353c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
354e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
355e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        Workspace workspace = mLauncher.getWorkspace();
356e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
357e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        Folder folder = workspace.getOpenFolder();
358e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (folder != null) {
359e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            if (folder.getItemsInReadingOrder().contains(item)) {
360e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal                mDragSource = folder;
361e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            } else {
362e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal                mLauncher.closeFolder();
363e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            }
364e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
365e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (mDragSource == null) {
366e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource = workspace;
367e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
368e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        mDragSource.enableAccessibleDrag(true);
369e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        mDragSource.startDrag(cellInfo, true);
370c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
37145478022977de9025dfc887cc1507d90d15febf8Sunny Goyal        if (mLauncher.getDragController().isDragging()) {
37245478022977de9025dfc887cc1507d90d15febf8Sunny Goyal            mLauncher.getDragController().addDragListener(this);
373c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
374c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
375c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
37645478022977de9025dfc887cc1507d90d15febf8Sunny Goyal
37745478022977de9025dfc887cc1507d90d15febf8Sunny Goyal    @Override
378aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal    public void onDragStart(DragSource source, ItemInfo info, int dragAction) {
37945478022977de9025dfc887cc1507d90d15febf8Sunny Goyal        // No-op
380c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
381c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
38245478022977de9025dfc887cc1507d90d15febf8Sunny Goyal    @Override
38345478022977de9025dfc887cc1507d90d15febf8Sunny Goyal    public void onDragEnd() {
38445478022977de9025dfc887cc1507d90d15febf8Sunny Goyal        mLauncher.getDragController().removeDragListener(this);
385c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo = null;
386e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (mDragSource != null) {
387e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource.enableAccessibleDrag(false);
388e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource = null;
389e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
390e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    }
391e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
392e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    public static interface AccessibilityDragSource {
393e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        void startDrag(CellLayout.CellInfo cellInfo, boolean accessible);
394e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
395e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        void enableAccessibleDrag(boolean enable);
396c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
397a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
398a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    /**
399a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal     * Find empty space on the workspace and returns the screenId.
400a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal     */
401a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private long findSpaceOnWorkspace(ItemInfo info, int[] outCoordinates) {
402a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        Workspace workspace = mLauncher.getWorkspace();
403a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        ArrayList<Long> workspaceScreens = workspace.getScreenOrder();
404a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        long screenId;
405a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
406a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        // First check if there is space on the current screen.
407a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        int screenIndex = workspace.getCurrentPage();
408a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenId = workspaceScreens.get(screenIndex);
409a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        CellLayout layout = (CellLayout) workspace.getPageAt(screenIndex);
410a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
411a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        boolean found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
412a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenIndex = workspace.hasCustomContent() ? 1 : 0;
413a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        while (!found && screenIndex < workspaceScreens.size()) {
414a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            screenId = workspaceScreens.get(screenIndex);
415a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            layout = (CellLayout) workspace.getPageAt(screenIndex);
416a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
417a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            screenIndex++;
418a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
419a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
420a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        if (found) {
421a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            return screenId;
422a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
423a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
424a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        workspace.addExtraEmptyScreen();
425a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenId = workspace.commitExtraEmptyScreen();
426a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        layout = workspace.getScreenWithId(screenId);
427a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
428a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
429a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        if (!found) {
430a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            Log.wtf(TAG, "Not enough space on an empty screen");
431a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
432a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        return screenId;
433a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    }
43471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal}
435