Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | package org.mozilla.gecko.tests; |
michael@0 | 2 | |
michael@0 | 3 | import org.mozilla.gecko.Actions; |
michael@0 | 4 | import org.mozilla.gecko.PaintedSurface; |
michael@0 | 5 | |
michael@0 | 6 | import android.net.Uri; |
michael@0 | 7 | |
michael@0 | 8 | /** |
michael@0 | 9 | * A test to ensure that when an input field is focused, it is not obscured by the VKB. |
michael@0 | 10 | * - Loads a page with an input field past the bottom of the visible area. |
michael@0 | 11 | * - scrolls down to make the input field visible at the bottom of the screen. |
michael@0 | 12 | * - taps on the input field to bring up the VKB |
michael@0 | 13 | * - verifies that the input field is still visible. |
michael@0 | 14 | */ |
michael@0 | 15 | public class testVkbOverlap extends PixelTest { |
michael@0 | 16 | private static final int CURSOR_BLINK_PERIOD = 500; |
michael@0 | 17 | private static final int LESS_THAN_CURSOR_BLINK_PERIOD = CURSOR_BLINK_PERIOD - 50; |
michael@0 | 18 | private static final int PAGE_SETTLE_TIME = 5000; |
michael@0 | 19 | |
michael@0 | 20 | public void testVkbOverlap() { |
michael@0 | 21 | blockForGeckoReady(); |
michael@0 | 22 | testSetup("initial-scale=1.0, user-scalable=no", false); |
michael@0 | 23 | testSetup("initial-scale=1.0", false); |
michael@0 | 24 | testSetup("", "phone".equals(mDevice.type)); |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | private void testSetup(String viewport, boolean shouldZoom) { |
michael@0 | 28 | loadAndPaint(getAbsoluteUrl("/robocop/test_viewport.sjs?metadata=" + Uri.encode(viewport))); |
michael@0 | 29 | |
michael@0 | 30 | // scroll to the bottom of the page and let it settle |
michael@0 | 31 | Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint(); |
michael@0 | 32 | MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop()); |
michael@0 | 33 | meh.dragSync(10, 150, 10, 50); |
michael@0 | 34 | |
michael@0 | 35 | // the input field has a green background, so let's count the number of green pixels |
michael@0 | 36 | int greenPixelCount = 0; |
michael@0 | 37 | |
michael@0 | 38 | PaintedSurface painted = waitForPaint(paintExpecter); |
michael@0 | 39 | paintExpecter.unregisterListener(); |
michael@0 | 40 | try { |
michael@0 | 41 | greenPixelCount = countGreenPixels(painted); |
michael@0 | 42 | } finally { |
michael@0 | 43 | painted.close(); |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | mAsserter.ok(greenPixelCount > 0, "testInputVisible", "Found " + greenPixelCount + " green pixels after scrolling"); |
michael@0 | 47 | |
michael@0 | 48 | paintExpecter = mActions.expectPaint(); |
michael@0 | 49 | // the input field should be in the bottom-left corner, so tap thereabouts |
michael@0 | 50 | meh.tap(5, mDriver.getGeckoHeight() - 5); |
michael@0 | 51 | |
michael@0 | 52 | // After tapping in the input field, the page needs some time to do stuff, like draw and undraw the focus highlight |
michael@0 | 53 | // on the input field, trigger the VKB, process any resulting events generated by the system, and scroll the page. So |
michael@0 | 54 | // we give it a few seconds to do all that. We are sufficiently generous with our definition of "few seconds" to |
michael@0 | 55 | // prevent intermittent test failures. |
michael@0 | 56 | try { |
michael@0 | 57 | Thread.sleep(PAGE_SETTLE_TIME); |
michael@0 | 58 | } catch (InterruptedException ie) { |
michael@0 | 59 | ie.printStackTrace(); |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | // now that the focus is in the text field we will repaint every 500ms as the cursor blinks, so we need to use a smaller |
michael@0 | 63 | // "no paints" threshold to consider the page painted |
michael@0 | 64 | paintExpecter.blockUntilClear(LESS_THAN_CURSOR_BLINK_PERIOD); |
michael@0 | 65 | paintExpecter.unregisterListener(); |
michael@0 | 66 | painted = mDriver.getPaintedSurface(); |
michael@0 | 67 | try { |
michael@0 | 68 | // if the vkb scrolled into view as expected, then the number of green pixels now visible should be about the |
michael@0 | 69 | // same as it was before, since the green pixels indicate the text input is in view. use a fudge factor of 0.9 to |
michael@0 | 70 | // account for borders and such of the text input which might still be out of view. |
michael@0 | 71 | int newCount = countGreenPixels(painted); |
michael@0 | 72 | |
michael@0 | 73 | // if zooming is allowed, the number of green pixels visible should have increased substatially |
michael@0 | 74 | if (shouldZoom) { |
michael@0 | 75 | mAsserter.ok(newCount > greenPixelCount * 1.5, "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount); |
michael@0 | 76 | } else { |
michael@0 | 77 | mAsserter.ok((Math.abs(greenPixelCount - newCount) / greenPixelCount < 0.1), "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount); |
michael@0 | 78 | } |
michael@0 | 79 | } finally { |
michael@0 | 80 | painted.close(); |
michael@0 | 81 | } |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | private int countGreenPixels(PaintedSurface painted) { |
michael@0 | 85 | int count = 0; |
michael@0 | 86 | for (int y = painted.getHeight() - 1; y >= 0; y--) { |
michael@0 | 87 | for (int x = painted.getWidth() - 1; x >= 0; x--) { |
michael@0 | 88 | int pixel = painted.getPixelAt(x, y); |
michael@0 | 89 | int r = (pixel >> 16) & 0xFF; |
michael@0 | 90 | int g = (pixel >> 8) & 0xFF; |
michael@0 | 91 | int b = (pixel & 0xFF); |
michael@0 | 92 | if (g > (r + 0x30) && g > (b + 0x30)) { |
michael@0 | 93 | // there's more green in this pixel than red or blue, so count it. |
michael@0 | 94 | // the reason this is so hacky-looking is because even though green is supposed to |
michael@0 | 95 | // be (r,g,b) = (0x00, 0x80, 0x00), the GL readback ends up coming back quite |
michael@0 | 96 | // different. |
michael@0 | 97 | count++; |
michael@0 | 98 | } |
michael@0 | 99 | // uncomment for debugging: |
michael@0 | 100 | // if (pixel != -1) mAsserter.dumpLog("Pixel at " + x + ", " + y + ": " + Integer.toString(pixel, 16)); |
michael@0 | 101 | } |
michael@0 | 102 | } |
michael@0 | 103 | return count; |
michael@0 | 104 | } |
michael@0 | 105 | } |