1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.android.launcher3.util;
18
19import android.test.AndroidTestCase;
20import android.test.suitebuilder.annotation.SmallTest;
21import android.view.KeyEvent;
22import android.view.View;
23
24import com.android.launcher3.util.FocusLogic;
25
26/**
27 * Tests the {@link FocusLogic} class that handles key event based focus handling.
28 */
29@SmallTest
30public final class FocusLogicTest extends AndroidTestCase {
31
32    @Override
33    protected void setUp() throws Exception {
34        super.setUp();
35        // Nothing to set up as this class only tests static methods.
36    }
37
38    @Override
39    protected void tearDown() throws Exception {
40        // Nothing to tear down as this class only tests static methods.
41    }
42
43    public void testShouldConsume() {
44         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_DPAD_LEFT));
45         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_DPAD_RIGHT));
46         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_DPAD_UP));
47         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_DPAD_DOWN));
48         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_MOVE_HOME));
49         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_MOVE_END));
50         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_PAGE_UP));
51         assertTrue(FocusLogic.shouldConsume(KeyEvent.KEYCODE_PAGE_DOWN));
52    }
53
54    public void testCreateSparseMatrix() {
55         // Either, 1) create a helper method to generate/instantiate all possible cell layout that
56         // may get created in real world to test this method. OR 2) Move all the matrix
57         // management routine to celllayout and write tests for them.
58    }
59
60    public void testMoveFromBottomRightToBottomLeft() {
61        int[][] map = transpose(new int[][] {
62                {-1, 0, -1, -1, -1, -1},
63                {-1, -1, -1, -1, -1, -1},
64                {-1, -1, -1, -1, -1, -1},
65                {-1, -1, -1, -1, -1, -1},
66                {100, 1, -1, -1, -1, -1},
67        });
68        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 100, 1, 2, false);
69        assertEquals(1, i);
70    }
71
72    public void testMoveFromBottomRightToTopLeft() {
73        int[][] map = transpose(new int[][] {
74                {-1, 0, -1, -1, -1, -1},
75                {-1, -1, -1, -1, -1, -1},
76                {-1, -1, -1, -1, -1, -1},
77                {-1, -1, -1, -1, -1, -1},
78                {100, -1, -1, -1, -1, -1},
79        });
80        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 100, 1, 2, false);
81        assertEquals(FocusLogic.NEXT_PAGE_FIRST_ITEM, i);
82    }
83
84    public void testMoveIntoHotseatWithEqualHotseatAndWorkspaceColumns() {
85        // Test going from an icon right above the All Apps button to the All Apps button.
86        int[][] map = transpose(new int[][] {
87                {-1, -1, -1, -1, -1},
88                {-1, -1, -1, -1, -1},
89                {-1, -1, -1, -1, -1},
90                {-1, -1,  0, -1, -1},
91                { 2,  3,  1,  4,  5},
92        });
93        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
94        assertEquals(1, i);
95        // Test going from an icon above and to the right of the All Apps
96        // button to an icon to the right of the All Apps button.
97        map = transpose(new int[][] {
98                {-1, -1, -1, -1, -1},
99                {-1, -1, -1, -1, -1},
100                {-1, -1, -1, -1, -1},
101                {-1, -1, -1,  0, -1},
102                { 2,  3,  1,  4,  5},
103        });
104        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
105        assertEquals(4, i);
106    }
107
108    public void testMoveIntoHotseatWithExtraColumnForAllApps() {
109        // Test going from an icon above and to the left
110        // of the All Apps button to the All Apps button.
111        int[][] map = transpose(new int[][] {
112                {-1, -1, -1,-11, -1, -1, -1},
113                {-1, -1, -1,-11, -1, -1, -1},
114                {-1, -1, -1,-11, -1, -1, -1},
115                {-1, -1, -1,-11, -1, -1, -1},
116                {-1, -1,  0,-11, -1, -1, -1},
117                {-1, -1, -1,  1,  1, -1, -1},
118        });
119        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
120        assertEquals(1, i);
121        // Test going from an icon above and to the right
122        // of the All Apps button to the All Apps button.
123        map = transpose(new int[][] {
124                {-1, -1, -1,-11, -1, -1, -1},
125                {-1, -1, -1,-11, -1, -1, -1},
126                {-1, -1, -1,-11, -1, -1, -1},
127                {-1, -1, -1,-11, -1, -1, -1},
128                {-1, -1, -1,-11,  0, -1, -1},
129                {-1, -1, -1,  1, -1, -1, -1},
130        });
131        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
132        assertEquals(1, i);
133        // Test going from the All Apps button to an icon
134        // above and to the right of the All Apps button.
135        map = transpose(new int[][] {
136                {-1, -1, -1,-11, -1, -1, -1},
137                {-1, -1, -1,-11, -1, -1, -1},
138                {-1, -1, -1,-11, -1, -1, -1},
139                {-1, -1, -1,-11, -1, -1, -1},
140                {-1, -1, -1,-11,  0, -1, -1},
141                {-1, -1, -1,  1, -1, -1, -1},
142        });
143        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_UP, map, 1, 1, 1, true);
144        assertEquals(0, i);
145        // Test going from an icon above and to the left of the
146        // All Apps button in landscape to the All Apps button.
147        map = transpose(new int[][] {
148                { -1, -1, -1, -1, -1},
149                { -1, -1, -1,  0, -1},
150                {-11,-11,-11,-11,  1},
151                { -1, -1, -1, -1, -1},
152                { -1, -1, -1, -1, -1},
153        });
154        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 0, 1, 1, true);
155        assertEquals(1, i);
156        // Test going from the All Apps button in landscape to
157        // an icon above and to the left of the All Apps button.
158        map = transpose(new int[][] {
159                { -1, -1, -1, -1, -1},
160                { -1, -1, -1,  0, -1},
161                {-11,-11,-11,-11,  1},
162                { -1, -1, -1, -1, -1},
163                { -1, -1, -1, -1, -1},
164        });
165        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, map, 1, 1, 1, true);
166        assertEquals(0, i);
167        // Test that going to the hotseat always goes to the same row as the original icon.
168        map = transpose(new int[][]{
169                { 0,  1,  2,-11,  3,  4,  5},
170                {-1, -1, -1,-11, -1, -1, -1},
171                {-1, -1, -1,-11, -1, -1, -1},
172                {-1, -1, -1,-11, -1, -1, -1},
173                {-1, -1, -1,-11, -1, -1, -1},
174                { 7,  8,  9,  6, 10, 11, 12},
175        });
176        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
177        assertEquals(7, i);
178        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 1, 1, 1, true);
179        assertEquals(8, i);
180        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 2, 1, 1, true);
181        assertEquals(9, i);
182        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 3, 1, 1, true);
183        assertEquals(10, i);
184        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 4, 1, 1, true);
185        assertEquals(11, i);
186        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 5, 1, 1, true);
187        assertEquals(12, i);
188    }
189
190    public void testCrossingAllAppsColumn() {
191        // Test crossing from left to right in portrait.
192        int[][] map = transpose(new int[][] {
193                {-1, -1,-11, -1, -1},
194                {-1,  0,-11, -1, -1},
195                {-1, -1,-11,  1, -1},
196                {-1, -1,-11, -1, -1},
197                {-1, -1,  2, -1, -1},
198        });
199        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
200        assertEquals(1, i);
201        // Test crossing from right to left in portrait.
202        map = transpose(new int[][] {
203                {-1, -1,-11, -1, -1},
204                {-1, -1,-11,  0, -1},
205                {-1,  1,-11, -1, -1},
206                {-1, -1,-11, -1, -1},
207                {-1, -1,  2, -1, -1},
208        });
209        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, map, 0, 1, 1, true);
210        assertEquals(1, i);
211        // Test crossing from left to right in landscape.
212        map = transpose(new int[][] {
213                { -1, -1, -1, -1, -1},
214                { -1, -1, -1,  0, -1},
215                {-11,-11,-11,-11,  2},
216                { -1,  1, -1, -1, -1},
217                { -1, -1, -1, -1, -1},
218        });
219        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT, map, 0, 1, 1, true);
220        assertEquals(1, i);
221        // Test crossing from right to left in landscape.
222        map = transpose(new int[][] {
223                { -1, -1, -1, -1, -1},
224                { -1,  0, -1, -1, -1},
225                {-11,-11,-11,-11,  2},
226                { -1, -1,  1, -1, -1},
227                { -1, -1, -1, -1, -1},
228        });
229        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 0, 1, 1, true);
230        assertEquals(1, i);
231        // Test NOT crossing it, if the All Apps button is the only suitable candidate.
232        map = transpose(new int[][]{
233                {-1, 0, -1, -1, -1},
234                {-1, 1, -1, -1, -1},
235                {-11, -11, -11, -11, 4},
236                {-1, 2, -1, -1, -1},
237                {-1, 3, -1, -1, -1},
238        });
239        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 1, 1, 1, true);
240        assertEquals(4, i);
241        i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, map, 2, 1, 1, true);
242        assertEquals(4, i);
243    }
244
245    /** Transposes the matrix so that we can write it in human-readable format in the tests. */
246    private int[][] transpose(int[][] m) {
247        int[][] t = new int[m[0].length][m.length];
248        for (int i = 0; i < m.length; i++) {
249            for (int j = 0; j < m[0].length; j++) {
250                t[j][i] = m[i][j];
251            }
252        }
253        return t;
254    }
255}
256