Commit e4644b6a authored by Michael Bai's avatar Michael Bai Committed by Commit Bot

WebLayer: Fix the autofill popup position issue

AutofillProvider uses WebContents's container getLocationOnScreen()
to transform the field's bund to screen coordinates before notify
the AutofillService focus change.

WebLayer intentionally leaves the space to it's top control, but
can't set the margin to ContentView which hosts the WebContents.

This patch adds RenderCoordinates.getContentOffsetYPixInt() API
for AutofillProvider to get the top margin.

Test: the autofill pop is in correct location, and I didn't see
side effect.

Bug: 1085294, 1135076
Change-Id: I163f67375e0177a5f75717a3069124ec2ff53894
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523525
Commit-Queue: Michael Bai <michaelbai@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826155}
parent d00e5f5f
......@@ -29,6 +29,7 @@ import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.annotations.VerifiesOnO;
import org.chromium.base.metrics.ScopedSysTraceEvent;
import org.chromium.components.version_info.VersionConstants;
import org.chromium.content_public.browser.RenderCoordinates;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsAccessibility;
import org.chromium.ui.DropdownItem;
......@@ -715,8 +716,16 @@ public class AutofillProvider {
return mDatalistPopup;
}
private Rect transformToWindowBounds(RectF rect) {
// Refer to crbug.com/1085294 for the reason of offset.
// The current version of Mockito didn't support mock static method, adding extra method so
// the transform can be tested.
return transformToWindowBoundsWithOffsetY(
rect, RenderCoordinates.fromWebContents(mWebContents).getContentOffsetYPixInt());
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public Rect transformToWindowBounds(RectF rect) {
public Rect transformToWindowBoundsWithOffsetY(RectF rect, int offsetY) {
// Convert bounds to device pixel.
WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow();
DisplayAndroid displayAndroid = windowAndroid.getDisplay();
......@@ -726,6 +735,7 @@ public class AutofillProvider {
matrix.setScale(dipScale, dipScale);
int[] location = new int[2];
mContainerView.getLocationOnScreen(location);
location[1] += offsetY;
matrix.postTranslate(location[0], location[1]);
matrix.mapRect(bounds);
return new Rect(
......
......@@ -106,10 +106,11 @@ public class AutofillProviderTest {
@Test
public void testTransformToWindowBounds() {
RectF source = new RectF(10, 20, 300, 400);
Rect result = mAutofillProvider.transformToWindowBounds(source);
final int offsetY = 10;
Rect result = mAutofillProvider.transformToWindowBoundsWithOffsetY(source, offsetY);
assertEquals(10 * EXPECTED_DIP_SCALE + LOCATION_X, result.left, 0);
assertEquals(20 * EXPECTED_DIP_SCALE + LOCATION_Y, result.top, 0);
assertEquals(20 * EXPECTED_DIP_SCALE + LOCATION_Y + offsetY, result.top, 0);
assertEquals(300 * EXPECTED_DIP_SCALE + LOCATION_X, result.right, 0);
assertEquals(400 * EXPECTED_DIP_SCALE + LOCATION_Y, result.bottom, 0);
assertEquals(400 * EXPECTED_DIP_SCALE + LOCATION_Y + offsetY, result.bottom, 0);
}
}
......@@ -59,6 +59,11 @@ public class RenderCoordinatesImpl implements RenderCoordinates {
return (int) Math.floor(getScrollYPix());
}
@Override
public int getContentOffsetYPixInt() {
return (int) Math.floor(getContentOffsetYPix());
}
@Override
public int getContentWidthPixInt() {
return (int) Math.ceil(getContentWidthPix());
......
......@@ -56,4 +56,9 @@ public interface RenderCoordinates {
* @return Maximum possible horizontal scroll in physical pixels (approx, integer).
*/
int getMaxHorizontalScrollPixInt();
/**
* @return The Physical on-screen Y offset amount below the browser controls.
*/
int getContentOffsetYPixInt();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment