OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser; |
| 6 |
| 7 import android.graphics.Rect; |
| 8 import android.test.MoreAsserts; |
| 9 import android.test.suitebuilder.annotation.MediumTest; |
| 10 |
| 11 import org.chromium.base.ThreadUtils; |
| 12 import org.chromium.base.test.util.CommandLineFlags; |
| 13 import org.chromium.base.test.util.UrlUtils; |
| 14 import org.chromium.chrome.test.ChromeActivityTestCaseBase; |
| 15 import org.chromium.content.browser.ContentViewCore; |
| 16 import org.chromium.content.browser.test.util.Criteria; |
| 17 import org.chromium.content.browser.test.util.CriteriaHelper; |
| 18 import org.chromium.content.browser.test.util.DOMUtils; |
| 19 import org.chromium.content.browser.test.util.JavaScriptUtils; |
| 20 import org.chromium.content_public.browser.WebContents; |
| 21 import org.chromium.ui.UiUtils; |
| 22 |
| 23 import java.util.Locale; |
| 24 import java.util.concurrent.ExecutionException; |
| 25 import java.util.concurrent.TimeoutException; |
| 26 import java.util.concurrent.atomic.AtomicReference; |
| 27 |
| 28 |
| 29 /** |
| 30 * Integration test to ensure that OSK resizes only the visual viewport. |
| 31 */ |
| 32 |
| 33 public class OSKOverscrollTest extends ChromeActivityTestCaseBase<ChromeActivity
> { |
| 34 private static final String FIXED_FOOTER_PAGE = UrlUtils.encodeHtmlDataUri("
" |
| 35 + "<html>" |
| 36 + "<head>" |
| 37 + " <meta name=\"viewport\" " |
| 38 + " content=\"width=device-width, initial-scale=1.0, maximum-scal
e=1.0\" />" |
| 39 + " <style>" |
| 40 + " body {" |
| 41 + " height:1500px;" |
| 42 + " margin:0px;" |
| 43 + " }" |
| 44 + " #footer {" |
| 45 + " position:fixed;" |
| 46 + " left:0px;" |
| 47 + " bottom:0px;" |
| 48 + " height:50px;" |
| 49 + " width:100%;" |
| 50 + " background:#FFFF00;" |
| 51 + " }" |
| 52 + " </style>" |
| 53 + "</head>" |
| 54 + "<body>" |
| 55 + " <form method=\"POST\">" |
| 56 + " <input type=\"text\" id=\"fn\"/><br>" |
| 57 + " <div id=\"footer\"></div>" |
| 58 + " </form>" |
| 59 + "</body>" |
| 60 + "</html>"); |
| 61 |
| 62 // We convert CSS pixels into device pixels and compare the viewport size be
fore and after the |
| 63 // keyboard show. window.innerHeight returns an integer and the actual heigh
t is a floating |
| 64 // point. Need some buffer for error. |
| 65 private static final int ERROR_EPS_PIX = 1; |
| 66 |
| 67 public OSKOverscrollTest() { |
| 68 super(ChromeActivity.class); |
| 69 } |
| 70 |
| 71 @Override |
| 72 public void startMainActivity() throws InterruptedException { |
| 73 // Don't launch activity automatically. |
| 74 } |
| 75 |
| 76 private void waitForKeyboard() throws InterruptedException { |
| 77 // Wait until the keyboard is showing. |
| 78 CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard was never
shown.") { |
| 79 @Override |
| 80 public boolean isSatisfied() { |
| 81 return UiUtils.isKeyboardShowing( |
| 82 getActivity(), |
| 83 getActivity().getCurrentContentViewCore().getContainerVi
ew()); |
| 84 } |
| 85 }); |
| 86 } |
| 87 |
| 88 private int getViewportHeight(WebContents webContents) { |
| 89 try { |
| 90 String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( |
| 91 webContents, "window.innerHeight"); |
| 92 MoreAsserts.assertNotEqual(jsonText.trim().toLowerCase(Locale.US), "
null"); |
| 93 return Integer.parseInt(jsonText); |
| 94 } catch (Exception ex) { |
| 95 fail(ex.toString()); |
| 96 } |
| 97 return -1; |
| 98 } |
| 99 |
| 100 private boolean almostEqual(int a, int b) { |
| 101 return Math.abs(a - b) <= ERROR_EPS_PIX; |
| 102 } |
| 103 |
| 104 /** |
| 105 * Verify that OSK show only resizes the visual viewport when the ENABLE_OSK
_OVERSCROLL flag is |
| 106 * set. |
| 107 * @throws InterruptedException |
| 108 * @throws TimeoutException |
| 109 * @throws ExecutionException |
| 110 */ |
| 111 @MediumTest |
| 112 @CommandLineFlags.Add({ChromeSwitches.ENABLE_OSK_OVERSCROLL}) |
| 113 public void testOnlyVisualViewportResizes() |
| 114 throws InterruptedException, TimeoutException, ExecutionException { |
| 115 startMainActivityWithURL(FIXED_FOOTER_PAGE); |
| 116 |
| 117 final AtomicReference<ContentViewCore> viewCoreRef = new AtomicReference
<ContentViewCore>(); |
| 118 final AtomicReference<WebContents> webContentsRef = new AtomicReference<
WebContents>(); |
| 119 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 120 @Override |
| 121 public void run() { |
| 122 viewCoreRef.set(getActivity().getCurrentContentViewCore()); |
| 123 webContentsRef.set(viewCoreRef.get().getWebContents()); |
| 124 } |
| 125 }); |
| 126 |
| 127 DOMUtils.waitForNonZeroNodeBounds(webContentsRef.get(), "fn"); |
| 128 |
| 129 // Get the position of the footer and the viewport height before bringin
g up the OSK. |
| 130 Rect footerPositionBefore = DOMUtils.getNodeBounds(webContentsRef.get(),
"footer"); |
| 131 int viewportHeightBeforeCss = getViewportHeight(webContentsRef.get()); |
| 132 float cssToDevicePixFactor = viewCoreRef.get().getPageScaleFactor() |
| 133 * viewCoreRef.get().getDeviceScaleFactor(); |
| 134 |
| 135 // Click on the unfocused input element for the first time to focus on i
t. This brings up |
| 136 // the OSK. |
| 137 DOMUtils.clickNode(this, viewCoreRef.get(), "fn"); |
| 138 |
| 139 waitForKeyboard(); |
| 140 |
| 141 // Get the position of the footer after bringing up the OSK. This should
be the same as the |
| 142 // position before because only the visual viewport should have resized. |
| 143 Rect footerPositionAfter = DOMUtils.getNodeBounds(webContentsRef.get(),
"footer"); |
| 144 assertEquals(footerPositionBefore, footerPositionAfter); |
| 145 |
| 146 // Verify that the size of the viewport before the OSK show is equal to
the size of the |
| 147 // viewport after the OSK show plus the size of the keyboard. |
| 148 int viewportHeightAfterCss = getViewportHeight(webContentsRef.get()); |
| 149 int keyboardHeight = viewCoreRef.get().getContentViewClient().getSystemW
indowInsetBottom(); |
| 150 assertTrue(almostEqual( |
| 151 (int) (viewportHeightBeforeCss * cssToDevicePixFactor), |
| 152 (int) (viewportHeightAfterCss * cssToDevicePixFactor) + keyboard
Height)); |
| 153 } |
| 154 } |
OLD | NEW |