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 
17 package com.android.launcher3.util;
18 
19 import android.test.AndroidTestCase;
20 import android.test.suitebuilder.annotation.SmallTest;
21 import android.view.KeyEvent;
22 import android.view.View;
23 
24 import com.android.launcher3.util.FocusLogic;
25 
26 /**
27  * Tests the {@link FocusLogic} class that handles key event based focus handling.
28  */
29 @SmallTest
30 public final class FocusLogicTest extends AndroidTestCase {
31 
32     @Override
setUp()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
tearDown()39     protected void tearDown() throws Exception {
40         // Nothing to tear down as this class only tests static methods.
41     }
42 
testShouldConsume()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 
testCreateSparseMatrix()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 
testMoveFromBottomRightToBottomLeft()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 
testMoveFromBottomRightToTopLeft()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 
testMoveIntoHotseatWithEqualHotseatAndWorkspaceColumns()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 
testMoveIntoHotseatWithExtraColumnForAllApps()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 
testCrossingAllAppsColumn()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. */
transpose(int[][] m)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