Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 329d8bfa authored by Tony Wickham's avatar Tony Wickham
Browse files

Cleanup keyboard code.

This should be the last keyboard CL.
- Fix bug: couldn't focus All Apps button in some cases when the All
Apps column was skipped over. Also added test case for this.
- Stop explicitly passing countX and countY to handleKeyEvent, as
these had to match the matrix dimensions anyways.
- Rename createSparseMatrix() - there were 3 methods of the same name,
but all had different purposes. This is confusing both from a
readability standpoint and also when looking at stack traces.

Change-Id: I08ba8411674fcea43a608856c114dee8dbd22398
parent 0fa5ada2
Loading
Loading
Loading
Loading
+21 −38
Original line number Diff line number Diff line
@@ -100,8 +100,6 @@ public class FocusHelper {
            // Initialize variables.
            final ShortcutAndWidgetContainer itemContainer = (ShortcutAndWidgetContainer) v.getParent();
            final CellLayout cellLayout = (CellLayout) itemContainer.getParent();
            final int countX = cellLayout.getCountX();
            final int countY = cellLayout.getCountY();

            final int iconIndex = itemContainer.indexOfChild(v);
            final FolderPagedView pagedView = (FolderPagedView) cellLayout.getParent();
@@ -112,8 +110,8 @@ public class FocusHelper {

            int[][] matrix = FocusLogic.createSparseMatrix(cellLayout);
            // Process focus.
            int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX,
                    countY, matrix, iconIndex, pageIndex, pageCount, isLayoutRtl);
            int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
                    pageCount, isLayoutRtl);
            if (newIconIndex == FocusLogic.NOOP) {
                handleNoopKey(keyCode, v);
                return consume;
@@ -130,7 +128,8 @@ public class FocusHelper {
                        pagedView.snapToPage(pageIndex - 1);
                        child = newParent.getChildAt(
                                ((newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN)
                                    ^ newParent.invertLayoutHorizontally()) ? 0 : countX - 1, row);
                                    ^ newParent.invertLayoutHorizontally()) ? 0 : matrix.length - 1,
                                row);
                    }
                    break;
                case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
@@ -144,7 +143,7 @@ public class FocusHelper {
                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1);
                    if (newParent != null) {
                        pagedView.snapToPage(pageIndex - 1);
                        child = newParent.getChildAt(countX - 1, countY - 1);
                        child = newParent.getChildAt(matrix.length - 1, matrix[0].length - 1);
                    }
                    break;
                case FocusLogic.NEXT_PAGE_FIRST_ITEM:
@@ -219,8 +218,6 @@ public class FocusHelper {
        final ItemInfo itemInfo = (ItemInfo) v.getTag();
        int pageIndex = workspace.getNextPage();
        int pageCount = workspace.getChildCount();
        int countX = -1;
        int countY = -1;
        int iconIndex = hotseatParent.indexOfChild(v);
        int iconRank = ((CellLayout.LayoutParams) hotseatLayout.getShortcutsAndWidgets()
                .getChildAt(iconIndex).getLayoutParams()).cellX;
@@ -239,19 +236,15 @@ public class FocusHelper {

        if (keyCode == KeyEvent.KEYCODE_DPAD_UP &&
                !profile.isVerticalBarLayout()) {
            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout,
            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout,
                    true /* hotseat horizontal */, profile.inv.hotseatAllAppsRank);
            iconIndex += iconParent.getChildCount();
            countX = hotseatLayout.getCountX();
            countY = iconLayout.getCountY() + hotseatLayout.getCountY();
            parent = iconParent;
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
                profile.isVerticalBarLayout()) {
            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout,
            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout,
                    false /* hotseat horizontal */, profile.inv.hotseatAllAppsRank);
            iconIndex += iconParent.getChildCount();
            countX = iconLayout.getCountX() + hotseatLayout.getCountX();
            countY = hotseatLayout.getCountY();
            parent = iconParent;
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
                profile.isVerticalBarLayout()) {
@@ -268,14 +261,12 @@ public class FocusHelper {
            // For other KEYCODE_DPAD_LEFT and KEYCODE_DPAD_RIGHT navigation, do not use the
            // matrix extended with hotseat.
            matrix = FocusLogic.createSparseMatrix(hotseatLayout);
            countX = hotseatLayout.getCountX();
            countY = hotseatLayout.getCountY();
            parent = hotseatParent;
        }

        // Process the focus.
        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX,
                countY, matrix, iconIndex, pageIndex, pageCount, Utilities.isRtl(v.getResources()));
        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
                pageCount, Utilities.isRtl(v.getResources()));

        View newIcon = null;
        switch (newIconIndex) {
@@ -369,8 +360,6 @@ public class FocusHelper {
        final int iconIndex = parent.indexOfChild(v);
        final int pageIndex = workspace.indexOfChild(iconLayout);
        final int pageCount = workspace.getChildCount();
        int countX = iconLayout.getCountX();
        int countY = iconLayout.getCountY();

        CellLayout hotseatLayout = (CellLayout) hotseat.getChildAt(0);
        ShortcutAndWidgetContainer hotseatParent = hotseatLayout.getShortcutsAndWidgets();
@@ -380,16 +369,12 @@ public class FocusHelper {
        // to take a user to the hotseat. For other dpad navigation, do not use the matrix extended
        // with the hotseat.
        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN && !profile.isVerticalBarLayout()) {
            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout, true /* horizontal */,
                    profile.inv.hotseatAllAppsRank);
            countX = hotseatLayout.getCountX();
            countY = countY + hotseatLayout.getCountY();
            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout,
                    true /* horizontal */, profile.inv.hotseatAllAppsRank);
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
                profile.isVerticalBarLayout()) {
            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout, false /* horizontal */,
                    profile.inv.hotseatAllAppsRank);
            countX = countX + hotseatLayout.getCountX();
            countY = hotseatLayout.getCountY();
            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout,
                    false /* horizontal */, profile.inv.hotseatAllAppsRank);
        } else if (isUninstallKeyChord(e)) {
            matrix = FocusLogic.createSparseMatrix(iconLayout);
            if (UninstallDropTarget.supportsDrop(launcher, itemInfo)) {
@@ -403,8 +388,8 @@ public class FocusHelper {
        }

        // Process the focus.
        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX,
                countY, matrix, iconIndex, pageIndex, pageCount, Utilities.isRtl(v.getResources()));
        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
                pageCount, Utilities.isRtl(v.getResources()));
        boolean isRtl = Utilities.isRtl(v.getResources());
        View newIcon = null;
        CellLayout workspaceLayout = (CellLayout) workspace.getChildAt(pageIndex);
@@ -424,11 +409,10 @@ public class FocusHelper {
                parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
                if (parent != null) {
                    iconLayout = (CellLayout) parent.getParent();
                    matrix = FocusLogic.createSparseMatrix(iconLayout,
                    matrix = FocusLogic.createSparseMatrixWithPivotColumn(iconLayout,
                            iconLayout.getCountX(), row);
                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX + 1, countY,
                            matrix, FocusLogic.PIVOT, newPageIndex, pageCount,
                            Utilities.isRtl(v.getResources()));
                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, FocusLogic.PIVOT,
                            newPageIndex, pageCount, Utilities.isRtl(v.getResources()));
                    if (newIconIndex == FocusLogic.NEXT_PAGE_FIRST_ITEM) {
                        newIcon = handleNextPageFirstItem(workspace, hotseatLayout, pageIndex,
                                isRtl);
@@ -465,10 +449,9 @@ public class FocusHelper {
                parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
                if (parent != null) {
                    iconLayout = (CellLayout) parent.getParent();
                    matrix = FocusLogic.createSparseMatrix(iconLayout, -1, row);
                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX + 1, countY,
                            matrix, FocusLogic.PIVOT, newPageIndex, pageCount,
                            Utilities.isRtl(v.getResources()));
                    matrix = FocusLogic.createSparseMatrixWithPivotColumn(iconLayout, -1, row);
                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, FocusLogic.PIVOT,
                            newPageIndex, pageCount, Utilities.isRtl(v.getResources()));
                    if (newIconIndex == FocusLogic.NEXT_PAGE_FIRST_ITEM) {
                        newIcon = handleNextPageFirstItem(workspace, hotseatLayout, pageIndex,
                                isRtl);
+29 −15
Original line number Diff line number Diff line
@@ -80,8 +80,11 @@ public class FocusLogic {
                keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_FORWARD_DEL);
    }

    public static int handleKeyEvent(int keyCode, int cntX, int cntY,
            int [][] map, int iconIdx, int pageIndex, int pageCount, boolean isRtl) {
    public static int handleKeyEvent(int keyCode, int [][] map, int iconIdx, int pageIndex,
            int pageCount, boolean isRtl) {

        int cntX = map == null ? -1 : map.length;
        int cntY = map == null ? -1 : map[0].length;

        if (DEBUG) {
            Log.v(TAG, String.format(
@@ -187,8 +190,8 @@ public class FocusLogic {
     * in portrait orientation. In landscape, [(icon + hotseat) column count x (icon row count)]
     */
    // TODO: get rid of the dynamic matrix creation
    public static int[][] createSparseMatrix(CellLayout iconLayout, CellLayout hotseatLayout,
            boolean isHotseatHorizontal, int allappsiconRank) {
    public static int[][] createSparseMatrixWithHotseat(CellLayout iconLayout,
            CellLayout hotseatLayout, boolean isHotseatHorizontal, int allappsiconRank) {

        ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
        ViewGroup hotseatParent = hotseatLayout.getShortcutsAndWidgets();
@@ -267,7 +270,8 @@ public class FocusLogic {
     * @param pivotY    y coordinate of the focused item in the current page
     */
    // TODO: get rid of the dynamic matrix creation
    public static int[][] createSparseMatrix(CellLayout iconLayout, int pivotX, int pivotY) {
    public static int[][] createSparseMatrixWithPivotColumn(CellLayout iconLayout,
            int pivotX, int pivotY) {

        ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();

@@ -348,23 +352,28 @@ public class FocusLogic {
        //              (x2-n, yPos + 2*increment), (x2-n, yPos - 2*increment)
        int nextYPos1;
        int nextYPos2;
        boolean haveCrossedAllAppsColumn1 = false;
        boolean haveCrossedAllAppsColumn2 = false;
        int x = -1;
        for (int coeff = 1; coeff < cntY; coeff++) {
            nextYPos1 = yPos + coeff * increment;
            nextYPos2 = yPos - coeff * increment;
            x = xPos + increment * coeff;
            if (inspectMatrix(x, nextYPos1, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
                nextYPos1 += increment;

                haveCrossedAllAppsColumn1 = true;
            }
            if (inspectMatrix(x, nextYPos2, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
                nextYPos2 -= increment;
                haveCrossedAllAppsColumn2 = true;
            }
            for (; 0 <= x && x < cntX; x += increment) {
                if ((newIconIndex = inspectMatrix(x, nextYPos1, cntX, cntY, matrix)) != NOOP) {
                int offset1 = haveCrossedAllAppsColumn1 && x < cntX - 1 ? increment : 0;
                newIconIndex = inspectMatrix(x, nextYPos1 + offset1, cntX, cntY, matrix);
                if (newIconIndex != NOOP) {
                    return newIconIndex;
                }
                if ((newIconIndex = inspectMatrix(x, nextYPos2, cntX, cntY, matrix)) != NOOP) {
                int offset2 = haveCrossedAllAppsColumn2 && x < cntX - 1 ? -increment : 0;
                newIconIndex = inspectMatrix(x, nextYPos2 + offset2, cntX, cntY, matrix);
                if (newIconIndex != NOOP) {
                    return newIconIndex;
                }
            }
@@ -427,23 +436,28 @@ public class FocusLogic {
        //              (xPos + 2*increment, y_(2-n))), (xPos - 2*increment, y_(2-n))
        int nextXPos1;
        int nextXPos2;
        boolean haveCrossedAllAppsColumn1 = false;
        boolean haveCrossedAllAppsColumn2 = false;
        int y = -1;
        for (int coeff = 1; coeff < cntX; coeff++) {
            nextXPos1 = xPos + coeff * increment;
            nextXPos2 = xPos - coeff * increment;
            y = yPos + increment * coeff;
            if (inspectMatrix(nextXPos1, y, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
                nextXPos1 += increment;

                haveCrossedAllAppsColumn1 = true;
            }
            if (inspectMatrix(nextXPos2, y, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
                nextXPos2 -= increment;
                haveCrossedAllAppsColumn2 = true;
            }
            for (; 0 <= y && y < cntY; y = y + increment) {
                if ((newIconIndex = inspectMatrix(nextXPos1, y, cntX, cntY, matrix)) != NOOP) {
                int offset1 = haveCrossedAllAppsColumn1 && y < cntY - 1 ? increment : 0;
                newIconIndex = inspectMatrix(nextXPos1 + offset1, y, cntX, cntY, matrix);
                if (newIconIndex != NOOP) {
                    return newIconIndex;
                }
                if ((newIconIndex = inspectMatrix(nextXPos2, y, cntX, cntY, matrix)) != NOOP) {
                int offset2 = haveCrossedAllAppsColumn2 && y < cntY - 1 ? -increment : 0;
                newIconIndex = inspectMatrix(nextXPos2 + offset2, y, cntX, cntY, matrix);
                if (newIconIndex != NOOP) {
                    return newIconIndex;
                }
            }
+32 −20
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1, -1, -1, -1},
                {100, 1, -1, -1, -1, -1},
        });
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 6, 5, map, 100, 1, 2, false);
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 100, 1, 2, false);
        assertEquals(1, i);
    }

@@ -79,7 +79,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1, -1, -1, -1},
                {100, -1, -1, -1, -1, -1},
        });
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 6, 5, map, 100, 1, 2, false);
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 100, 1, 2, false);
        assertEquals(FocusLogic.NEXT_PAGE_FIRST_ITEM, i);
    }

@@ -92,7 +92,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1,  0, -1, -1},
                { 2,  3,  1,  4,  5},
        });
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 5, 5, map, 0, 1, 1, true);
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test going from an icon above and to the right of the All Apps
        // button to an icon to the right of the All Apps button.
@@ -103,7 +103,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1,  0, -1},
                { 2,  3,  1,  4,  5},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 5, 5, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(4, i);
    }

@@ -118,7 +118,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1,  0,-11, -1, -1, -1},
                {-1, -1, -1,  1,  1, -1, -1},
        });
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 0, 1, 1, true);
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test going from an icon above and to the right
        // of the All Apps button to the All Apps button.
@@ -130,7 +130,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1,-11,  0, -1, -1},
                {-1, -1, -1,  1, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test going from the All Apps button to an icon
        // above and to the right of the All Apps button.
@@ -142,7 +142,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1,-11,  0, -1, -1},
                {-1, -1, -1,  1, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_UP, 7, 6, map, 1, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_UP, map, 1, 1, 1, true);
        assertEquals(0, i);
        // Test going from an icon above and to the left of the
        // All Apps button in landscape to the All Apps button.
@@ -153,7 +153,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                { -1, -1, -1, -1, -1},
                { -1, -1, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 5, 5, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test going from the All Apps button in landscape to
        // an icon above and to the left of the All Apps button.
@@ -164,7 +164,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                { -1, -1, -1, -1, -1},
                { -1, -1, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, 5, 5, map, 1, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, map, 1, 1, 1, true);
        assertEquals(0, i);
        // Test that going to the hotseat always goes to the same row as the original icon.
        map = transpose(new int[][]{
@@ -175,17 +175,17 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1, -1,-11, -1, -1, -1},
                { 7,  8,  9,  6, 10, 11, 12},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(7, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 1, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 1, 1, 1, true);
        assertEquals(8, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 2, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 2, 1, 1, true);
        assertEquals(9, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 3, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 3, 1, 1, true);
        assertEquals(10, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 4, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 4, 1, 1, true);
        assertEquals(11, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 7, 6, map, 5, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 5, 1, 1, true);
        assertEquals(12, i);
    }

@@ -198,7 +198,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1,-11, -1, -1},
                {-1, -1,  2, -1, -1},
        });
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 5, 5, map, 0, 1, 1, true);
        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test crossing from right to left in portrait.
        map = transpose(new int[][] {
@@ -208,7 +208,7 @@ public final class FocusLogicTest extends AndroidTestCase {
                {-1, -1,-11, -1, -1},
                {-1, -1,  2, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, 5, 5, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test crossing from left to right in landscape.
        map = transpose(new int[][] {
@@ -216,9 +216,9 @@ public final class FocusLogicTest extends AndroidTestCase {
                { -1, -1, -1,  0, -1},
                {-11,-11,-11,-11,  2},
                { -1,  1, -1, -1, -1},
                { -1, -1, -1, -1, -1},
                { -1, -1  -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, 5, 5, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test crossing from right to left in landscape.
        map = transpose(new int[][] {
@@ -228,8 +228,20 @@ public final class FocusLogicTest extends AndroidTestCase {
                { -1, -1,  1, -1, -1},
                { -1, -1, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 5, 5, map, 0, 1, 1, true);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 0, 1, 1, true);
        assertEquals(1, i);
        // Test NOT crossing it, if the All Apps button is the only suitable candidate.
        map = transpose(new int[][]{
                {-1, 0, -1, -1, -1},
                {-1, 1, -1, -1, -1},
                {-11, -11, -11, -11, 4},
                {-1, 2, -1, -1, -1},
                {-1, 3, -1, -1, -1},
        });
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 1, 1, 1, true);
        assertEquals(4, i);
        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 2, 1, 1, true);
        assertEquals(4, i);
    }

    /** Transposes the matrix so that we can write it in human-readable format in the tests. */