LauncherAccessibilityDelegate.java revision 83a8f042adda926489494dff217c15ab696139b4
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;
2383a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Folder;
2483a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.FolderInfo;
2583a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.InfoDropTarget;
2683a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.ItemInfo;
2783a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Launcher;
2883a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherAppWidgetHostView;
2983a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherAppWidgetInfo;
3083a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherModel;
3183a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.LauncherSettings;
3283a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.PendingAddItemInfo;
3383a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.R;
3483a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.ShortcutInfo;
3583a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.UninstallDropTarget;
3683a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.Workspace;
37091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
3871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
3971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport java.util.ArrayList;
4071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
4171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal@TargetApi(Build.VERSION_CODES.LOLLIPOP)
4271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalpublic class LauncherAccessibilityDelegate extends AccessibilityDelegate {
4371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
44a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final String TAG = "LauncherAccessibilityDelegate";
45a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
46a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int REMOVE = R.id.action_remove;
47a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int INFO = R.id.action_info;
48a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int UNINSTALL = R.id.action_uninstall;
49a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
50a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private static final int MOVE = R.id.action_move;
519ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal    private static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
529ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    private static final int RESIZE = R.id.action_resize;
53c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
54e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    public enum DragType {
55c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        ICON,
56c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        FOLDER,
57c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        WIDGET
58c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
59c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
60c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public static class DragInfo {
61e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public DragType dragType;
62e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public ItemInfo info;
63e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        public View item;
64c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
65c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
66a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private final SparseArray<AccessibilityAction> mActions = new SparseArray<>();
67091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk final Launcher mLauncher;
6871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
69e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    private DragInfo mDragInfo = null;
70e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    private AccessibilityDragSource mDragSource = null;
71e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
7271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public LauncherAccessibilityDelegate(Launcher launcher) {
7371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mLauncher = launcher;
7471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
7571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(REMOVE, new AccessibilityAction(REMOVE,
7671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.delete_target_label)));
7771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(INFO, new AccessibilityAction(INFO,
7871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.info_target_label)));
7971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
8071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.delete_target_uninstall_label)));
8171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
8271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                launcher.getText(R.string.action_add_to_workspace)));
83c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mActions.put(MOVE, new AccessibilityAction(MOVE,
84c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen                launcher.getText(R.string.action_move)));
859ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal        mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE,
869ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                launcher.getText(R.string.action_move_to_workspace)));
879ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        mActions.put(RESIZE, new AccessibilityAction(RESIZE,
889ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        launcher.getText(R.string.action_resize)));
8971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
9071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
9171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    @Override
9271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
9371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        super.onInitializeAccessibilityNodeInfo(host, info);
9471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if (!(host.getTag() instanceof ItemInfo)) return;
9571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        ItemInfo item = (ItemInfo) host.getTag();
9671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
971a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (DeleteDropTarget.supportsDrop(item)) {
981a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(REMOVE));
991a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1001a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (UninstallDropTarget.supportsDrop(host.getContext(), item)) {
1011a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(UNINSTALL));
1021a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1031a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (InfoDropTarget.supportsDrop(host.getContext(), item)) {
1041a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            info.addAction(mActions.get(INFO));
1051a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
1061a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal
10771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if ((item instanceof ShortcutInfo)
10871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                || (item instanceof LauncherAppWidgetInfo)
10971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                || (item instanceof FolderInfo)) {
110c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            info.addAction(mActions.get(MOVE));
1119ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1129ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            if (item.container >= 0) {
1139ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                info.addAction(mActions.get(MOVE_TO_WORKSPACE));
1149ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            } else if (item instanceof LauncherAppWidgetInfo) {
1159ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                if (!getSupportedResizeActions(host, (LauncherAppWidgetInfo) item).isEmpty()) {
1169ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    info.addAction(mActions.get(RESIZE));
1179ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                }
1189ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            }
1191a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        } if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
12071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            info.addAction(mActions.get(ADD_TO_WORKSPACE));
12171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
12271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
12371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
12471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    @Override
12571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    public boolean performAccessibilityAction(View host, int action, Bundle args) {
12671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if ((host.getTag() instanceof ItemInfo)
12771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                && performAction(host, (ItemInfo) host.getTag(), action)) {
12871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            return true;
12971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
13071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        return super.performAccessibilityAction(host, action, args);
13171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
13271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
1339ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    public boolean performAction(final View host, final ItemInfo item, int action) {
13471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        if (action == REMOVE) {
135c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) {
1361a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal                announceConfirmation(R.string.item_removed);
137c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen                return true;
138c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            }
139c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            return false;
14071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == INFO) {
14171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
14271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            return true;
14371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == UNINSTALL) {
1441a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            return UninstallDropTarget.startUninstallActivity(mLauncher, item);
145c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        } else if (action == MOVE) {
146c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            beginAccessibleDrag(host, item);
14771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        } else if (action == ADD_TO_WORKSPACE) {
148a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            final int[] coordinates = new int[2];
149a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            final long screenId = findSpaceOnWorkspace(item, coordinates);
150a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            mLauncher.showWorkspace(true, new Runnable() {
15171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
15271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                @Override
153a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                public void run() {
154a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    if (item instanceof AppInfo) {
155a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        ShortcutInfo info = ((AppInfo) item).makeShortcut();
156a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        LauncherModel.addItemToDatabase(mLauncher, info,
157a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                LauncherSettings.Favorites.CONTAINER_DESKTOP,
158a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                screenId, coordinates[0], coordinates[1]);
159a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
160a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        ArrayList<ItemInfo> itemList = new ArrayList<>();
161a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        itemList.add(info);
162a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        mLauncher.bindItems(itemList, 0, itemList.size(), true);
163a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    } else if (item instanceof PendingAddItemInfo) {
164a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        PendingAddItemInfo info = (PendingAddItemInfo) item;
165a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        Workspace workspace = mLauncher.getWorkspace();
166a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
167a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                        mLauncher.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
168a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                                screenId, coordinates, info.spanX, info.spanY);
16971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal                    }
170a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                    announceConfirmation(R.string.item_added_to_workspace);
171a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal                }
172a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            });
173a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            return true;
1749ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal        } else if (action == MOVE_TO_WORKSPACE) {
1759ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            Folder folder = mLauncher.getWorkspace().getOpenFolder();
1769ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            mLauncher.closeFolder(folder);
1779ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            ShortcutInfo info = (ShortcutInfo) item;
1789ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            folder.getInfo().remove(info);
1799ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1809ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            final int[] coordinates = new int[2];
1819ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            final long screenId = findSpaceOnWorkspace(item, coordinates);
1829ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            LauncherModel.moveItemInDatabase(mLauncher, info,
1839ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    LauncherSettings.Favorites.CONTAINER_DESKTOP,
1849ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    screenId, coordinates[0], coordinates[1]);
1859ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1869ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            // Bind the item in next frame so that if a new workspace page was created,
1879ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            // it will get laid out.
1889ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            new Handler().post(new Runnable() {
1899ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal
1909ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                @Override
1919ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                public void run() {
1929ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    ArrayList<ItemInfo> itemList = new ArrayList<>();
1939ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    itemList.add(item);
1949ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    mLauncher.bindItems(itemList, 0, itemList.size(), true);
1959ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                    announceConfirmation(R.string.item_moved);
1969ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal                }
1979ae77771d751a5a7fe87f660ab70908b5f55d9fcSunny Goyal            });
1989ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == RESIZE) {
1999ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
2009ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            final ArrayList<Integer> actions = getSupportedResizeActions(host, info);
2019ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            CharSequence[] labels = new CharSequence[actions.size()];
2029ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            for (int i = 0; i < actions.size(); i++) {
2039ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                labels[i] = mLauncher.getText(actions.get(i));
2049ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2059ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2069ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            new AlertDialog.Builder(mLauncher)
2079ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .setTitle(R.string.action_resize)
2089ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .setItems(labels, new DialogInterface.OnClickListener() {
2099ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2109ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    @Override
2119ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    public void onClick(DialogInterface dialog, int which) {
2129ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        performResizeAction(actions.get(which), host, info);
2139ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                        dialog.dismiss();
2149ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    }
2159ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                })
2169ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                .show();
21771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        }
21871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        return false;
21971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
220c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
2219ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    private ArrayList<Integer> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) {
2229ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo();
2239ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        ArrayList<Integer> actions = new ArrayList<>();
2249ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2259ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout layout = (CellLayout) host.getParent().getParent();
2269ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
2279ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
2289ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
2299ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_increase_width);
2309ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2319ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2329ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (info.spanX > info.minSpanX && info.spanX > 1) {
2339ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_decrease_width);
2349ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2359ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2369ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2379ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
2389ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) ||
2399ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) {
2409ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_increase_height);
2419ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2429ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2439ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (info.spanY > info.minSpanY && info.spanY > 1) {
2449ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                actions.add(R.string.action_decrease_height);
2459ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2469ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2479ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        return actions;
2489ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    }
2499ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2509ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    private void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
2519ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams();
2529ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        CellLayout layout = (CellLayout) host.getParent().getParent();
2539ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        layout.markCellsAsUnoccupiedForView(host);
2549ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2559ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        if (action == R.string.action_increase_width) {
2569ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (((host.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
2579ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    && layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY))
2589ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                    || !layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY)) {
2599ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                lp.cellX --;
2609ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                info.cellX --;
2619ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2629ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellHSpan ++;
2639ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanX ++;
2649ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_decrease_width) {
2659ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellHSpan --;
2669ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanX --;
2679ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_increase_height) {
2689ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            if (!layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1)) {
2699ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                lp.cellY --;
2709ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                info.cellY --;
2719ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            }
2729ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellVSpan ++;
2739ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanY ++;
2749ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        } else if (action == R.string.action_decrease_height) {
2759ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            lp.cellVSpan --;
2769ca9c1316da8382c1f663973072731033b5e533aSunny Goyal            info.spanY --;
2779ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        }
2789ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
2799ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        layout.markCellsAsOccupiedForView(host);
2809ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        Rect sizeRange = new Rect();
2819ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, sizeRange);
2829ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null,
2839ca9c1316da8382c1f663973072731033b5e533aSunny Goyal                sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom);
2849ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        host.requestLayout();
2859ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        LauncherModel.updateItemInDatabase(mLauncher, info);
2869ca9c1316da8382c1f663973072731033b5e533aSunny Goyal        announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
2879ca9c1316da8382c1f663973072731033b5e533aSunny Goyal    }
2889ca9c1316da8382c1f663973072731033b5e533aSunny Goyal
289091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk void announceConfirmation(int resId) {
290c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        announceConfirmation(mLauncher.getResources().getString(resId));
291c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
292c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
293091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk void announceConfirmation(String confirmation) {
294c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragLayer().announceForAccessibility(confirmation);
295c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
296c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
297c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
298c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public boolean isInAccessibleDrag() {
299c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        return mDragInfo != null;
300c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
301c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
302c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public DragInfo getDragInfo() {
303c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        return mDragInfo;
304c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
305c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
3061a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal    /**
3071a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * @param clickedTarget the actual view that was clicked
3081a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
3091a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     * as the actual drop location otherwise the views center is used.
3101a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal     */
3111a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal    public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
312c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            String confirmation) {
313c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        if (!isInAccessibleDrag()) return;
314c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
315c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        int[] loc = new int[2];
3161a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (dropLocation == null) {
3171a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[0] = clickedTarget.getWidth() / 2;
3181a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[1] = clickedTarget.getHeight() / 2;
3191a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        } else {
3201a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[0] = dropLocation.centerX();
3211a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            loc[1] = dropLocation.centerY();
3221a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
323c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
3241a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
325c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragController().completeAccessibleDrag(loc);
326c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
327c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        endAccessibleDrag();
3281a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        if (!TextUtils.isEmpty(confirmation)) {
3291a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal            announceConfirmation(confirmation);
3301a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal        }
331c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
332c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
333c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public void beginAccessibleDrag(View item, ItemInfo info) {
334c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo = new DragInfo();
335c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.info = info;
336c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.item = item;
337c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo.dragType = DragType.ICON;
338c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        if (info instanceof FolderInfo) {
339c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragInfo.dragType = DragType.FOLDER;
340c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        } else if (info instanceof LauncherAppWidgetInfo) {
341c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragInfo.dragType = DragType.WIDGET;
342c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
343c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
344c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
345c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
346c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        Rect pos = new Rect();
347c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
348c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
349e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
350e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        Workspace workspace = mLauncher.getWorkspace();
351e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
352e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        Folder folder = workspace.getOpenFolder();
353e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (folder != null) {
354e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            if (folder.getItemsInReadingOrder().contains(item)) {
355e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal                mDragSource = folder;
356e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            } else {
357e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal                mLauncher.closeFolder();
358e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            }
359e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
360e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (mDragSource == null) {
361e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource = workspace;
362e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
363e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        mDragSource.enableAccessibleDrag(true);
364e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        mDragSource.startDrag(cellInfo, true);
365c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
366c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
367c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public boolean onBackPressed() {
368c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        if (isInAccessibleDrag()) {
369c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            cancelAccessibleDrag();
370c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            return true;
371c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
372c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        return false;
373c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
374c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
375c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    private void cancelAccessibleDrag() {
376c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mLauncher.getDragController().cancelDrag();
377c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        endAccessibleDrag();
378c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
379c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
380c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    private void endAccessibleDrag() {
381c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragInfo = null;
382e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        if (mDragSource != null) {
383e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource.enableAccessibleDrag(false);
384e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal            mDragSource = null;
385e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        }
386e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    }
387e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
388e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal    public static interface AccessibilityDragSource {
389e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        void startDrag(CellLayout.CellInfo cellInfo, boolean accessible);
390e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal
391e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        void enableAccessibleDrag(boolean enable);
392c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
393a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
394a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    /**
395a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal     * Find empty space on the workspace and returns the screenId.
396a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal     */
397a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    private long findSpaceOnWorkspace(ItemInfo info, int[] outCoordinates) {
398a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        Workspace workspace = mLauncher.getWorkspace();
399a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        ArrayList<Long> workspaceScreens = workspace.getScreenOrder();
400a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        long screenId;
401a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
402a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        // First check if there is space on the current screen.
403a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        int screenIndex = workspace.getCurrentPage();
404a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenId = workspaceScreens.get(screenIndex);
405a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        CellLayout layout = (CellLayout) workspace.getPageAt(screenIndex);
406a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
407a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        boolean found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
408a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenIndex = workspace.hasCustomContent() ? 1 : 0;
409a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        while (!found && screenIndex < workspaceScreens.size()) {
410a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            screenId = workspaceScreens.get(screenIndex);
411a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            layout = (CellLayout) workspace.getPageAt(screenIndex);
412a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
413a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            screenIndex++;
414a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
415a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
416a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        if (found) {
417a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            return screenId;
418a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
419a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
420a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        workspace.addExtraEmptyScreen();
421a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        screenId = workspace.commitExtraEmptyScreen();
422a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        layout = workspace.getScreenWithId(screenId);
423a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
424a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal
425a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        if (!found) {
426a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal            Log.wtf(TAG, "Not enough space on an empty screen");
427a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        }
428a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal        return screenId;
429a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal    }
43071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal}
431