• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view;
18 
19 import android.graphics.Rect;
20 import android.test.AndroidTestCase;
21 import android.test.suitebuilder.annotation.MediumTest;
22 import android.test.suitebuilder.annotation.SmallTest;
23 
24 public class FocusFinderTest extends AndroidTestCase {
25 
26     private FocusFinderHelper mFocusFinder;
27 
28     @Override
setUp()29     protected void setUp() throws Exception {
30         super.setUp();
31 
32         mFocusFinder = new FocusFinderHelper(FocusFinder.getInstance());
33     }
34 
35     @SmallTest
testPreconditions()36     public void testPreconditions() {
37         assertNotNull("focus finder instance", mFocusFinder);
38     }
39 
40     @SmallTest
testBelowNotCandidateForDirectionUp()41     public void testBelowNotCandidateForDirectionUp() {
42         assertIsNotCandidate(View.FOCUS_UP,
43                 new Rect(0, 30, 10, 40),  // src  (left, top, right, bottom)
44                 new Rect(0, 50, 10, 60));  // dest (left, top, right, bottom)
45     }
46 
47     @SmallTest
testAboveShareEdgeEdgeOkForDirectionUp()48     public void testAboveShareEdgeEdgeOkForDirectionUp() {
49         final Rect src = new Rect(0, 30, 10, 40);
50 
51         final Rect dest = new Rect(src);
52         dest.offset(0, -src.height());
53         assertEquals(src.top, dest.bottom);
54 
55         assertDirectionIsCandidate(View.FOCUS_UP, src, dest);
56     }
57 
58     @SmallTest
testCompletelyContainedNotCandidate()59     public void testCompletelyContainedNotCandidate() {
60         assertIsNotCandidate(
61                 View.FOCUS_DOWN,
62                 //       L  T   R   B
63                 new Rect(0, 0,  50, 50),
64                 new Rect(0, 1,  50, 49));
65     }
66 
67     @SmallTest
testContinaedWithCommonBottomNotCandidate()68     public void testContinaedWithCommonBottomNotCandidate() {
69         assertIsNotCandidate(
70                 View.FOCUS_DOWN,
71                 //       L  T   R   B
72                 new Rect(0, 0,  50, 50),
73                 new Rect(0, 1,  50, 50));
74     }
75 
76     @SmallTest
testOverlappingIsCandidateWhenBothEdgesAreInDirection()77     public void testOverlappingIsCandidateWhenBothEdgesAreInDirection() {
78         assertDirectionIsCandidate(
79                 View.FOCUS_DOWN,
80                 //       L  T   R   B
81                 new Rect(0, 0,  50, 50),
82                 new Rect(0, 1,  50, 51));
83     }
84 
85     @SmallTest
testTopEdgeOfDestAtOrAboveTopOfSrcNotCandidateForDown()86     public void testTopEdgeOfDestAtOrAboveTopOfSrcNotCandidateForDown() {
87         assertIsNotCandidate(
88                 View.FOCUS_DOWN,
89                 //       L  T   R   B
90                 new Rect(0, 0,  50, 50),
91                 new Rect(0, 0,  50, 51));
92         assertIsNotCandidate(
93                 View.FOCUS_DOWN,
94                 //       L  T   R   B
95                 new Rect(0, 0,  50, 50),
96                 new Rect(0, -1, 50, 51));
97     }
98 
99     @SmallTest
testSameRectBeamsOverlap()100     public void testSameRectBeamsOverlap() {
101         final Rect rect = new Rect(0, 0, 20, 20);
102 
103         assertBeamsOverlap(View.FOCUS_LEFT, rect, rect);
104         assertBeamsOverlap(View.FOCUS_RIGHT, rect, rect);
105         assertBeamsOverlap(View.FOCUS_UP, rect, rect);
106         assertBeamsOverlap(View.FOCUS_DOWN, rect, rect);
107     }
108 
109     @SmallTest
testOverlapBeamsRightLeftUpToEdge()110     public void testOverlapBeamsRightLeftUpToEdge() {
111         final Rect rect1 = new Rect(0, 0, 20, 20);
112         final Rect rect2 = new Rect(rect1);
113 
114         // just below bottom edge
115         rect2.offset(0, rect1.height() - 1);
116         assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
117         assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
118 
119         // at edge
120         rect2.offset(0, 1);
121         assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
122         assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
123 
124         // just beyond
125         rect2.offset(0, 1);
126         assertBeamsDontOverlap(View.FOCUS_LEFT, rect1, rect2);
127         assertBeamsDontOverlap(View.FOCUS_RIGHT, rect1, rect2);
128 
129         // just below top edge
130         rect2.set(rect1);
131         rect2.offset(0, -(rect1.height() - 1));
132         assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
133         assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
134 
135         // at top edge
136         rect2.offset(0, -1);
137         assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
138         assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
139 
140         // just beyond top edge
141         rect2.offset(0, -1);
142         assertBeamsDontOverlap(View.FOCUS_LEFT, rect1, rect2);
143         assertBeamsDontOverlap(View.FOCUS_RIGHT, rect1, rect2);
144     }
145 
146     @SmallTest
testOverlapBeamsUpDownUpToEdge()147     public void testOverlapBeamsUpDownUpToEdge() {
148         final Rect rect1 = new Rect(0, 0, 20, 20);
149         final Rect rect2 = new Rect(rect1);
150 
151         // just short of right edge
152         rect2.offset(rect1.width() - 1, 0);
153         assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
154         assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
155 
156         // at edge
157         rect2.offset(1, 0);
158         assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
159         assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
160 
161         // just beyond
162         rect2.offset(1, 0);
163         assertBeamsDontOverlap(View.FOCUS_UP, rect1, rect2);
164         assertBeamsDontOverlap(View.FOCUS_DOWN, rect1, rect2);
165 
166         // just short of left edge
167         rect2.set(rect1);
168         rect2.offset(-(rect1.width() - 1), 0);
169         assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
170         assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
171 
172         // at edge
173         rect2.offset(-1, 0);
174         assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
175         assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
176 
177         // just beyond edge
178         rect2.offset(-1, 0);
179         assertBeamsDontOverlap(View.FOCUS_UP, rect1, rect2);
180         assertBeamsDontOverlap(View.FOCUS_DOWN, rect1, rect2);
181     }
182 
183     @SmallTest
testDirectlyAboveTrumpsAboveLeft()184     public void testDirectlyAboveTrumpsAboveLeft() {
185         Rect src = new Rect(0, 50, 20, 70);  // src (left, top, right, bottom)
186 
187         Rect directlyAbove = new Rect(src);
188         directlyAbove.offset(0, -(1 + src.height()));
189 
190         Rect aboveLeft = new Rect(src);
191         aboveLeft.offset(-(1 + src.width()), -(1 + src.height()));
192 
193         assertBetterCandidate(View.FOCUS_UP, src, directlyAbove, aboveLeft);
194     }
195 
196     @SmallTest
testAboveInBeamTrumpsSlightlyCloserOutOfBeam()197     public void testAboveInBeamTrumpsSlightlyCloserOutOfBeam() {
198         Rect src = new Rect(0, 50, 20, 70);  // src (left, top, right, bottom)
199 
200         Rect directlyAbove = new Rect(src);
201         directlyAbove.offset(0, -(1 + src.height()));
202 
203         Rect aboveLeft = new Rect(src);
204         aboveLeft.offset(-(1 + src.width()), -(1 + src.height()));
205 
206         // offset directly above a little further up
207         directlyAbove.offset(0, -5);
208         assertBetterCandidate(View.FOCUS_UP, src, directlyAbove, aboveLeft);
209     }
210 
211     @SmallTest
testOutOfBeamBeatsInBeamUp()212     public void testOutOfBeamBeatsInBeamUp() {
213 
214         Rect src = new Rect(0, 0, 50, 50); // (left, top, right, bottom)
215 
216         Rect aboveLeftOfBeam = new Rect(src);
217         aboveLeftOfBeam.offset(-(src.width() + 1), -src.height());
218         assertBeamsDontOverlap(View.FOCUS_UP, src, aboveLeftOfBeam);
219 
220         Rect aboveInBeam = new Rect(src);
221         aboveInBeam.offset(0, -src.height());
222         assertBeamsOverlap(View.FOCUS_UP, src, aboveInBeam);
223 
224         // in beam wins
225         assertBetterCandidate(View.FOCUS_UP, src, aboveInBeam, aboveLeftOfBeam);
226 
227         // still wins while aboveInBeam's bottom edge is < out of beams' top
228         aboveInBeam.offset(0, -(aboveLeftOfBeam.height() - 1));
229         assertTrue("aboveInBeam.bottom > aboveLeftOfBeam.top", aboveInBeam.bottom > aboveLeftOfBeam.top);
230         assertBetterCandidate(View.FOCUS_UP, src, aboveInBeam, aboveLeftOfBeam);
231 
232         // cross the threshold: the out of beam prevails
233         aboveInBeam.offset(0, -1);
234         assertEquals(aboveInBeam.bottom, aboveLeftOfBeam.top);
235         assertBetterCandidate(View.FOCUS_UP, src, aboveLeftOfBeam, aboveInBeam);
236     }
237 
238     /**
239      * A non-candidate (even a much closer one) is always a worse choice
240      * than a real candidate.
241      */
242     @MediumTest
testSomeCandidateBetterThanNonCandidate()243     public void testSomeCandidateBetterThanNonCandidate() {
244         Rect src = new Rect(0, 0, 50, 50); // (left, top, right, bottom)
245 
246         Rect nonCandidate = new Rect(src);
247         nonCandidate.offset(src.width() + 1, 0);
248 
249         assertIsNotCandidate(View.FOCUS_LEFT, src, nonCandidate);
250 
251         Rect candidate = new Rect(src);
252         candidate.offset(-(4 * src.width()), 0);
253         assertDirectionIsCandidate(View.FOCUS_LEFT, src, candidate);
254 
255         assertBetterCandidate(View.FOCUS_LEFT, src, candidate, nonCandidate);
256     }
257 
258     /**
259      * Grabbed from {@link com.android.frameworktest.focus.VerticalFocusSearchTest#testSearchFromMidLeft()}
260      */
261     @SmallTest
testVerticalFocusSearchScenario()262     public void testVerticalFocusSearchScenario() {
263         assertBetterCandidate(View.FOCUS_DOWN,
264                 //       L    T    R    B
265                 new Rect(0,   109, 153, 169),   // src
266                 new Rect(166, 169, 319, 229),  // expectedbetter
267                 new Rect(0,   229, 320, 289)); // expectedworse
268 
269         // failing test 4/10/2008, the values were tweaked somehow in functional
270         // test...
271         assertBetterCandidate(View.FOCUS_DOWN,
272                 //       L    T    R    B
273                 new Rect(0,   91, 153, 133),   // src
274                 new Rect(166, 133, 319, 175),  // expectedbetter
275                 new Rect(0,   175, 320, 217)); // expectedworse
276 
277     }
278 
279     /**
280      * Example: going down from a thin button all the way to the left of a
281      * screen where, just below, is a very wide button, and just below that,
282      * is an equally skinny button all the way to the left.  want to make
283      * sure any minor axis factor doesn't override the fact that the one below
284      * in vertical beam should be next focus
285      */
286     @SmallTest
testBeamsOverlapMajorAxisCloserMinorAxisFurther()287     public void testBeamsOverlapMajorAxisCloserMinorAxisFurther() {
288         assertBetterCandidate(View.FOCUS_DOWN,
289                 //       L   T    R    B
290                 new Rect(0,  0,   100,  100),  // src
291                 new Rect(0,  100, 480,  200),  // expectedbetter
292                 new Rect(0,  200, 100,  300)); // expectedworse
293     }
294 
295     /**
296      * Real scenario grabbed from song playback screen.
297      */
298     @SmallTest
testMusicPlaybackScenario()299     public void testMusicPlaybackScenario() {
300         assertBetterCandidate(View.FOCUS_LEFT,
301                 //       L    T    R    B
302                 new Rect(227, 185, 312, 231),   // src
303                 new Rect(195, 386, 266, 438),   // expectedbetter
304                 new Rect(124, 386, 195, 438));  // expectedworse
305     }
306 
307     /**
308      * more generalized version of {@link #testMusicPlaybackScenario()}
309      */
310     @SmallTest
testOutOfBeamOverlapBeatsOutOfBeamFurtherOnMajorAxis()311     public void testOutOfBeamOverlapBeatsOutOfBeamFurtherOnMajorAxis() {
312         assertBetterCandidate(View.FOCUS_DOWN,
313                 //       L    T    R    B
314                 new Rect(0,   0,   50,  50),   // src
315                 new Rect(60,  40,  110, 90),   // expectedbetter
316                 new Rect(60,  70,  110, 120));  // expectedworse
317     }
318 
319     /**
320      * Make sure that going down prefers views that are actually
321      * down (and not those next to but still a candidate because
322      * they are overlapping on the major axis)
323      */
324     @SmallTest
testInBeamTrumpsOutOfBeamOverlapping()325     public void testInBeamTrumpsOutOfBeamOverlapping() {
326         assertBetterCandidate(View.FOCUS_DOWN,
327                 //       L    T    R    B
328                 new Rect(0,   0,   50,  50),   // src
329                 new Rect(0,   60,  50,  110),  // expectedbetter
330                 new Rect(51,  1,   101, 51)); // expectedworse
331     }
332 
333     @SmallTest
testOverlappingBeatsNonOverlapping()334     public void testOverlappingBeatsNonOverlapping() {
335         assertBetterCandidate(View.FOCUS_DOWN,
336                 //       L    T    R    B
337                 new Rect(0,   0,   50,  50),   // src
338                 new Rect(0,   40,  50,  90),   // expectedbetter
339                 new Rect(0,   75,  50,  125)); // expectedworse
340     }
341 
342     @SmallTest
testEditContactScenarioLeftFromDiscardChangesGoesToSaveContactInLandscape()343     public void testEditContactScenarioLeftFromDiscardChangesGoesToSaveContactInLandscape() {
344         assertBetterCandidate(View.FOCUS_LEFT,
345                 //       L    T    R    B
346                 new Rect(357, 258, 478, 318),  // src
347                 new Rect(2,   258, 100, 318),  // better
348                 new Rect(106, 120, 424, 184)); // worse
349     }
350 
351     /**
352      * A dial pad with 9 squares arranged in a grid.  no padding, so
353      * the edges are equal.  see {@link com.android.frameworktest.focus.LinearLayoutGrid}
354      */
355     @SmallTest
testGridWithTouchingEdges()356     public void testGridWithTouchingEdges() {
357         assertBetterCandidate(View.FOCUS_DOWN,
358                 //       L    T    R    B
359                 new Rect(106, 49,  212, 192),  // src
360                 new Rect(106, 192, 212, 335),  // better
361                 new Rect(0,   192, 106, 335)); // worse
362 
363         assertBetterCandidate(View.FOCUS_DOWN,
364                 //       L    T    R    B
365                 new Rect(106, 49,  212, 192),  // src
366                 new Rect(106, 192, 212, 335),  // better
367                 new Rect(212, 192, 318, 335)); // worse
368     }
369 
370     @SmallTest
testSearchFromEmptyRect()371     public void testSearchFromEmptyRect() {
372         assertBetterCandidate(View.FOCUS_DOWN,
373                 //       L   T    R    B
374                 new Rect(0,  0,   0,   0),    // src
375                 new Rect(0,  0,   320, 45),   // better
376                 new Rect(0,  45,  320, 545)); // worse
377     }
378 
379     /**
380      * Reproduce bug 1124559, drilling down to actual bug
381      * (majorAxisDistance was wrong for direction left)
382      */
383     @SmallTest
testGmailReplyButtonsScenario()384     public void testGmailReplyButtonsScenario() {
385         assertBetterCandidate(View.FOCUS_LEFT,
386                 //       L    T    R    B
387                 new Rect(223, 380, 312, 417),  // src
388                 new Rect(102, 380, 210, 417),  // better
389                 new Rect(111, 443, 206, 480)); // worse
390 
391         assertBeamBeats(View.FOCUS_LEFT,
392             //       L    T    R    B
393             new Rect(223, 380, 312, 417),  // src
394             new Rect(102, 380, 210, 417),  // better
395             new Rect(111, 443, 206, 480)); // worse
396 
397         assertBeamsOverlap(View.FOCUS_LEFT,
398                 //       L    T    R    B
399                 new Rect(223, 380, 312, 417),
400                 new Rect(102, 380, 210, 417));
401 
402         assertBeamsDontOverlap(View.FOCUS_LEFT,
403                 //       L    T    R    B
404                 new Rect(223, 380, 312, 417),
405                 new Rect(111, 443, 206, 480));
406 
407         assertTrue(
408                 "major axis distance less than major axis distance to "
409                         + "far edge",
410                 FocusFinderHelper.majorAxisDistance(View.FOCUS_LEFT,
411                         //       L    T    R    B
412                         new Rect(223, 380, 312, 417),
413                         new Rect(102, 380, 210, 417)) <
414                 FocusFinderHelper.majorAxisDistanceToFarEdge(View.FOCUS_LEFT,
415                         //       L    T    R    B
416                         new Rect(223, 380, 312, 417),
417                         new Rect(111, 443, 206, 480)));
418     }
419 
420     @SmallTest
testGmailScenarioBug1203288()421     public void testGmailScenarioBug1203288() {
422         assertBetterCandidate(View.FOCUS_DOWN,
423                 //       L    T    R    B
424                 new Rect(0,   2,   480, 82),   // src
425                 new Rect(344, 87,  475, 124),  // better
426                 new Rect(0,   130, 480, 203)); // worse
427     }
428 
429     @SmallTest
testHomeShortcutScenarioBug1295354()430     public void testHomeShortcutScenarioBug1295354() {
431         assertBetterCandidate(View.FOCUS_RIGHT,
432                 //       L    T    R    B
433                 new Rect(3, 338, 77, 413),   // src
434                 new Rect(163, 338, 237, 413),  // better
435                 new Rect(83, 38, 157, 113)); // worse
436     }
437 
438     @SmallTest
testBeamAlwaysBeatsHoriz()439     public void testBeamAlwaysBeatsHoriz() {
440         assertBetterCandidate(View.FOCUS_RIGHT,
441                 //       L    T    R    B
442                 new Rect(0,   0,   50,  50),   // src
443                 new Rect(150, 0,   200, 50),   // better, (way further, but in beam)
444                 new Rect(60,  51,  110, 101)); // worse, even though it is closer
445 
446         assertBetterCandidate(View.FOCUS_LEFT,
447                 //       L    T    R    B
448                 new Rect(150, 0,   200,  50),   // src
449                 new Rect(0,   50,  50,   50),   // better, (way further, but in beam)
450                 new Rect(49,  99,  149,  101)); // worse, even though it is closer
451     }
452 
453     @SmallTest
testIsCandidateOverlappingEdgeFromEmptyRect()454     public void testIsCandidateOverlappingEdgeFromEmptyRect() {
455         assertDirectionIsCandidate(View.FOCUS_DOWN,
456                 //       L   T    R    B
457                 new Rect(0,  0,   0,   0),   // src
458                 new Rect(0,  0,   20,  1));  // candidate
459 
460         assertDirectionIsCandidate(View.FOCUS_UP,
461                 //       L   T    R    B
462                 new Rect(0,  0,   0,   0),   // src
463                 new Rect(0,  -1,  20,  0));  // candidate
464 
465         assertDirectionIsCandidate(View.FOCUS_LEFT,
466                 //       L   T    R    B
467                 new Rect(0,  0,   0,   0),    // src
468                 new Rect(-1,  0,  0,   20));  // candidate
469 
470         assertDirectionIsCandidate(View.FOCUS_RIGHT,
471                 //       L   T    R    B
472                 new Rect(0,  0,   0,   0),    // src
473                 new Rect(0,  0,   1,   20));  // candidate
474     }
475 
assertBeamsOverlap(int direction, Rect rect1, Rect rect2)476     private void assertBeamsOverlap(int direction, Rect rect1, Rect rect2) {
477         String directionStr = validateAndGetStringFor(direction);
478         String assertMsg = String.format("Expected beams to overlap in direction %s "
479                 + "for rectangles %s and %s", directionStr, rect1, rect2);
480         assertTrue(assertMsg, mFocusFinder.beamsOverlap(direction, rect1, rect2));
481     }
482 
assertBeamsDontOverlap(int direction, Rect rect1, Rect rect2)483     private void assertBeamsDontOverlap(int direction, Rect rect1, Rect rect2) {
484         String directionStr = validateAndGetStringFor(direction);
485         String assertMsg = String.format("Expected beams not to overlap in direction %s "
486                 + "for rectangles %s and %s", directionStr, rect1, rect2);
487         assertFalse(assertMsg, mFocusFinder.beamsOverlap(direction, rect1, rect2));
488     }
489 
490     /**
491      * Assert that particular rect is a better focus search candidate from a
492      * source rect than another.
493      * @param direction The direction of focus search.
494      * @param srcRect The src rectangle.
495      * @param expectedBetter The candidate that should be better.
496      * @param expectedWorse The candidate that should be worse.
497      */
assertBetterCandidate(int direction, Rect srcRect, Rect expectedBetter, Rect expectedWorse)498     private void assertBetterCandidate(int direction, Rect srcRect,
499             Rect expectedBetter, Rect expectedWorse) {
500 
501         String directionStr = validateAndGetStringFor(direction);
502         String assertMsg = String.format(
503                 "expected %s to be a better focus search candidate than "
504                         + "%s when searching "
505                         + "from %s in direction %s",
506                 expectedBetter, expectedWorse, srcRect, directionStr);
507 
508         assertTrue(assertMsg,
509                 mFocusFinder.isBetterCandidate(direction, srcRect,
510                         expectedBetter, expectedWorse));
511 
512         assertMsg = String.format(
513                 "expected %s to not be a better focus search candidate than "
514                         + "%s when searching "
515                         + "from %s in direction %s",
516                 expectedWorse, expectedBetter, srcRect, directionStr);
517 
518         assertFalse(assertMsg,
519                 mFocusFinder.isBetterCandidate(direction, srcRect,
520                         expectedWorse, expectedBetter));
521     }
522 
assertIsNotCandidate(int direction, Rect src, Rect dest)523     private void assertIsNotCandidate(int direction, Rect src, Rect dest) {
524         String directionStr = validateAndGetStringFor(direction);
525 
526         final String assertMsg = String.format(
527                 "expected going from %s to %s in direction %s to be an invalid "
528                         + "focus search candidate",
529                 src, dest, directionStr);
530         assertFalse(assertMsg, mFocusFinder.isCandidate(src, dest, direction));
531     }
532 
assertBeamBeats(int direction, Rect srcRect, Rect rect1, Rect rect2)533     private void assertBeamBeats(int direction, Rect srcRect,
534             Rect rect1, Rect rect2) {
535 
536         String directionStr = validateAndGetStringFor(direction);
537         String assertMsg = String.format(
538                 "expecting %s to beam beat %s w.r.t %s in direction %s",
539                 rect1, rect2, srcRect, directionStr);
540         assertTrue(assertMsg, mFocusFinder.beamBeats(direction, srcRect, rect1, rect2));
541     }
542 
543 
assertDirectionIsCandidate(int direction, Rect src, Rect dest)544     private void assertDirectionIsCandidate(int direction, Rect src, Rect dest) {
545         String directionStr = validateAndGetStringFor(direction);
546 
547         final String assertMsg = String.format(
548                 "expected going from %s to %s in direction %s to be a valid "
549                         + "focus search candidate",
550                 src, dest, directionStr);
551         assertTrue(assertMsg, mFocusFinder.isCandidate(src, dest, direction));
552     }
553 
validateAndGetStringFor(int direction)554     private String validateAndGetStringFor(int direction) {
555         String directionStr = "??";
556         switch(direction) {
557             case View.FOCUS_UP:
558                 directionStr = "FOCUS_UP";
559                 break;
560             case View.FOCUS_DOWN:
561                 directionStr = "FOCUS_DOWN";
562                 break;
563             case View.FOCUS_LEFT:
564                 directionStr = "FOCUS_LEFT";
565                 break;
566             case View.FOCUS_RIGHT:
567                 directionStr = "FOCUS_RIGHT";
568                 break;
569             default:
570                 fail("passed in unknown direction, ya blewit!");
571         }
572         return directionStr;
573     }
574 
575 
576 }
577