summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkenrb <kenrb@chromium.org>2016-01-26 07:57:52 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-26 15:59:12 +0000
commit015b5b5829406934f9863c73f931815ae5007e8f (patch)
tree873c69f58b119bdc94216f631eaf9d582b295979
parentf1edf87bbb67bc31fa9d280736753132fd81f103 (diff)
downloadchromium_src-015b5b5829406934f9863c73f931815ae5007e8f.zip
chromium_src-015b5b5829406934f9863c73f931815ae5007e8f.tar.gz
chromium_src-015b5b5829406934f9863c73f931815ae5007e8f.tar.bz2
Position autofill popup widgets correctly under --site-per-process
When a AutofillHostMsg_QueryFormFieldAutofill message is sent from an out-of-process iframe, its screen coordinates are relative to the subframe's rect and not the top-level frame's viewport. This CL exposes a facility in the content API to perform the necessary transformation, particularly: - it promotes GetView() from RenderFrameHostImpl to RenderFrameHost, so the RenderWidgetHostView becomes available to the embedder, and - it promotes TransformPointToRootCoordSpace from RenderWidgetHostViewBase to RenderWidgetHostView, so that chrome/ or components/ code that directly receives coordinates from a renderer process can ensure they properly transformed Finally, it causes the ContentAutofillDriver to use the exposed methods to transform received autofill popup coordinates in order for them to display in the correct position. BUG=554119 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation Review URL: https://codereview.chromium.org/1526263003 Cr-Commit-Position: refs/heads/master@{#371519}
-rw-r--r--components/autofill/content/browser/content_autofill_driver.cc15
-rw-r--r--components/autofill/content/browser/content_autofill_driver.h2
-rw-r--r--components/autofill/core/browser/autofill_driver.h10
-rw-r--r--components/autofill/core/browser/autofill_manager.cc4
-rw-r--r--components/autofill/core/browser/test_autofill_driver.cc6
-rw-r--r--components/autofill/core/browser/test_autofill_driver.h2
-rw-r--r--components/autofill/ios/browser/autofill_driver_ios.h2
-rw-r--r--components/autofill/ios/browser/autofill_driver_ios.mm6
-rw-r--r--content/browser/frame_host/cross_process_frame_connector.cc10
-rw-r--r--content/browser/frame_host/cross_process_frame_connector.h5
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc6
-rw-r--r--content/browser/frame_host/render_frame_host_impl.h4
-rw-r--r--content/browser/frame_host/render_widget_host_view_child_frame.cc11
-rw-r--r--content/browser/frame_host/render_widget_host_view_child_frame.h3
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc14
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h15
-rw-r--r--content/public/browser/render_frame_host.h5
-rw-r--r--content/public/browser/render_widget_host_view.h13
18 files changed, 96 insertions, 37 deletions
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
index 65ed75a..23e11eb 100644
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -20,8 +20,10 @@
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/site_instance.h"
#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/geometry/size_f.h"
namespace autofill {
@@ -147,6 +149,19 @@ void ContentAutofillDriver::PopupHidden() {
RendererShouldClearPreviewedForm();
}
+gfx::RectF ContentAutofillDriver::TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) {
+ gfx::Point orig_point(bounding_box.x(), bounding_box.y());
+ gfx::Point transformed_point;
+ transformed_point =
+ render_frame_host_->GetView()->TransformPointToRootCoordSpace(orig_point);
+
+ gfx::RectF new_box;
+ new_box.SetRect(transformed_point.x(), transformed_point.y(),
+ bounding_box.width(), bounding_box.height());
+ return new_box;
+}
+
bool ContentAutofillDriver::HandleMessage(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ContentAutofillDriver, message)
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h
index b9e9329..61bc690 100644
--- a/components/autofill/content/browser/content_autofill_driver.h
+++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -61,6 +61,8 @@ class ContentAutofillDriver : public AutofillDriver {
void RendererShouldPreviewFieldWithValue(
const base::string16& value) override;
void PopupHidden() override;
+ gfx::RectF TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) override;
// Handles a message that came from the associated render frame.
bool HandleMessage(const IPC::Message& message);
diff --git a/components/autofill/core/browser/autofill_driver.h b/components/autofill/core/browser/autofill_driver.h
index 82e0f12..cbead57 100644
--- a/components/autofill/core/browser/autofill_driver.h
+++ b/components/autofill/core/browser/autofill_driver.h
@@ -17,6 +17,10 @@ namespace net {
class URLRequestContextGetter;
}
+namespace gfx {
+class RectF;
+}
+
namespace autofill {
class FormStructure;
@@ -89,6 +93,12 @@ class AutofillDriver {
// Informs the renderer that the popup has been hidden.
virtual void PopupHidden() = 0;
+
+ // Transform bounding box coordinates to real viewport coordinates. In
+ // the case of a page spanning multiple renderer processes, subframe
+ // renderers cannot do this transformation themselves.
+ virtual gfx::RectF TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) = 0;
};
} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index fad9ab5..ff6f123 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -401,7 +401,9 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
std::vector<Suggestion> suggestions;
- external_delegate_->OnQuery(query_id, form, field, bounding_box);
+ gfx::RectF transformed_box =
+ driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
+ external_delegate_->OnQuery(query_id, form, field, transformed_box);
// Need to refresh models before using the form_event_loggers.
bool is_autofill_possible = RefreshDataModels();
diff --git a/components/autofill/core/browser/test_autofill_driver.cc b/components/autofill/core/browser/test_autofill_driver.cc
index 38a83ed..906b55e 100644
--- a/components/autofill/core/browser/test_autofill_driver.cc
+++ b/components/autofill/core/browser/test_autofill_driver.cc
@@ -6,6 +6,7 @@
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "ui/gfx/geometry/rect_f.h"
namespace autofill {
@@ -71,4 +72,9 @@ void TestAutofillDriver::RendererShouldPreviewFieldWithValue(
void TestAutofillDriver::PopupHidden() {
}
+gfx::RectF TestAutofillDriver::TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) {
+ return bounding_box;
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_driver.h b/components/autofill/core/browser/test_autofill_driver.h
index 6282fa5..132196c 100644
--- a/components/autofill/core/browser/test_autofill_driver.h
+++ b/components/autofill/core/browser/test_autofill_driver.h
@@ -44,6 +44,8 @@ class TestAutofillDriver : public AutofillDriver {
void RendererShouldPreviewFieldWithValue(
const base::string16& value) override;
void PopupHidden() override;
+ gfx::RectF TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) override;
// Methods that tests can use to specialize functionality.
diff --git a/components/autofill/ios/browser/autofill_driver_ios.h b/components/autofill/ios/browser/autofill_driver_ios.h
index 7c665f56..e89c9e6 100644
--- a/components/autofill/ios/browser/autofill_driver_ios.h
+++ b/components/autofill/ios/browser/autofill_driver_ios.h
@@ -58,6 +58,8 @@ class AutofillDriverIOS : public AutofillDriver,
void RendererShouldPreviewFieldWithValue(
const base::string16& value) override;
void PopupHidden() override;
+ gfx::RectF TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) override;
private:
AutofillDriverIOS(
diff --git a/components/autofill/ios/browser/autofill_driver_ios.mm b/components/autofill/ios/browser/autofill_driver_ios.mm
index 1f32ddd..49a24f0f 100644
--- a/components/autofill/ios/browser/autofill_driver_ios.mm
+++ b/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -8,6 +8,7 @@
#include "ios/web/public/browser_state.h"
#include "ios/web/public/web_state/web_state.h"
#include "ios/web/public/web_thread.h"
+#include "ui/gfx/geometry/rect_f.h"
DEFINE_WEB_STATE_USER_DATA_KEY(autofill::AutofillDriverIOS);
@@ -98,4 +99,9 @@ void AutofillDriverIOS::RendererShouldPreviewFieldWithValue(
void AutofillDriverIOS::PopupHidden() {
}
+gfx::RectF AutofillDriverIOS::TransformBoundingBoxToViewportCoordinates(
+ const gfx::RectF& bounding_box) {
+ return bounding_box;
+}
+
} // namespace autofill
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc
index 1d8b23c..fef7ff7 100644
--- a/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -172,15 +172,15 @@ void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) {
root_view->UpdateCursor(cursor);
}
-void CrossProcessFrameConnector::TransformPointToRootCoordSpace(
+gfx::Point CrossProcessFrameConnector::TransformPointToRootCoordSpace(
const gfx::Point& point,
- cc::SurfaceId surface_id,
- gfx::Point* transformed_point) {
+ cc::SurfaceId surface_id) {
+ gfx::Point transformed_point = point;
RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
- *transformed_point = point;
if (root_view)
root_view->TransformPointToLocalCoordSpace(point, surface_id,
- transformed_point);
+ &transformed_point);
+ return transformed_point;
}
bool CrossProcessFrameConnector::HasFocus() {
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h
index 6f31ec60..6ad56a2 100644
--- a/content/browser/frame_host/cross_process_frame_connector.h
+++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -101,9 +101,8 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
float device_scale_factor() const { return device_scale_factor_; }
void GetScreenInfo(blink::WebScreenInfo* results);
void UpdateCursor(const WebCursor& cursor);
- void TransformPointToRootCoordSpace(const gfx::Point& point,
- cc::SurfaceId surface_id,
- gfx::Point* transformed_point);
+ gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point,
+ cc::SurfaceId surface_id);
// Determines whether the root RenderWidgetHostView (and thus the current
// page) has focus.
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index b63e42f..4759476 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1327,9 +1327,9 @@ void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) {
// It is necessary to transform the coordinates to account for nested
// RenderWidgetHosts, such as with out-of-process iframes.
gfx::Point original_point(validated_params.x, validated_params.y);
- gfx::Point transformed_point = original_point;
- static_cast<RenderWidgetHostViewBase*>(GetView())
- ->TransformPointToRootCoordSpace(original_point, &transformed_point);
+ gfx::Point transformed_point =
+ static_cast<RenderWidgetHostViewBase*>(GetView())
+ ->TransformPointToRootCoordSpace(original_point);
validated_params.x = transformed_point.x();
validated_params.y = transformed_point.y();
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index abd5d53..61c61a3 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -168,6 +168,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void InsertVisualStateCallback(
const VisualStateCallback& callback) override;
bool IsRenderFrameLive() override;
+ RenderWidgetHostView* GetView() override;
#if defined(OS_ANDROID)
void ActivateNearestFindResult(int request_id, float x, float y) override;
void RequestFindMatchRects(int current_version) override;
@@ -251,9 +252,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
// pointer to the RenderViewHost (which inherits RenderWidgetHost).
RenderWidgetHostImpl* GetRenderWidgetHost();
- // This returns the RenderWidgetHostView that can be used to control
- // focus and visibility for this frame.
- RenderWidgetHostView* GetView();
// This function is called when this is a swapped out RenderFrameHost that
// lives in the same process as the parent frame. The
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
index 98119d1..10a0681 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -381,15 +381,12 @@ void RenderWidgetHostViewChildFrame::ProcessMouseWheelEvent(
host_->ForwardWheelEvent(event);
}
-void RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
- const gfx::Point& point,
- gfx::Point* transformed_point) {
- *transformed_point = point;
+gfx::Point RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
+ const gfx::Point& point) {
if (!frame_connector_ || !use_surfaces_)
- return;
+ return point;
- frame_connector_->TransformPointToRootCoordSpace(point, surface_id_,
- transformed_point);
+ return frame_connector_->TransformPointToRootCoordSpace(point, surface_id_);
}
#if defined(OS_MACOSX)
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h
index 4bacd21..c77b216 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.h
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -128,8 +128,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event) override;
void ProcessMouseEvent(const blink::WebMouseEvent& event) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
- void TransformPointToRootCoordSpace(const gfx::Point& point,
- gfx::Point* transformed_point) override;
+ gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point) override;
#if defined(OS_MACOSX)
// RenderWidgetHostView implementation.
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index a2a0884..3bd1ffc 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -14,6 +14,7 @@
#include "content/common/content_switches_internal.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "ui/gfx/display.h"
+#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/screen.h"
@@ -682,10 +683,15 @@ uint32_t RenderWidgetHostViewBase::SurfaceIdNamespaceAtPoint(
return 0;
}
-void RenderWidgetHostViewBase::TransformPointToRootCoordSpace(
- const gfx::Point& point,
- gfx::Point* transformed_point) {
- *transformed_point = point;
+gfx::Point RenderWidgetHostViewBase::TransformPointToRootCoordSpace(
+ const gfx::Point& point) {
+ return point;
+}
+
+gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) {
+ return gfx::PointF(TransformPointToRootCoordSpace(
+ gfx::ToRoundedPoint(point)));
}
void RenderWidgetHostViewBase::TransformPointToLocalCoordSpace(
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index d714137..fa223b8 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -88,6 +88,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
void EndFrameSubscription() override;
+ // This only needs to be overridden by RenderWidgetHostViewBase subclasses
+ // that handle content embedded within other RenderWidgetHostViews.
+ gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point) override;
+ gfx::PointF TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) override;
+
// IPC::Listener implementation:
bool OnMessageReceived(const IPC::Message& msg) override;
@@ -204,15 +210,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
virtual void ProcessTouchEvent(const blink::WebTouchEvent& event,
const ui::LatencyInfo& latency) {}
- // If a RenderWidgetHost is dealing with points that are transformed from the
- // root frame for a page (i.e. because its content is contained within
- // that of another RenderWidgetHost), this provides a facility to convert
- // a point from its own coordinate space to that of the root frame.
- // This only needs to be overriden by RenderWidgetHostView subclasses
- // that handle content embedded within other RenderWidgetHostViews.
- virtual void TransformPointToRootCoordSpace(const gfx::Point& point,
- gfx::Point* transformed_point);
-
// Transform a point that is in the coordinate space of a Surface that is
// embedded within the RenderWidgetHostViewBase's Surface to the
// coordinate space of the embedding Surface. Typically this means that a
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index a8f71fe..a2e497e 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -26,6 +26,7 @@ class Value;
namespace content {
class RenderProcessHost;
class RenderViewHost;
+class RenderWidgetHostView;
class ServiceRegistry;
class SiteInstance;
@@ -73,6 +74,10 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// Returns the process for this frame.
virtual RenderProcessHost* GetProcess() = 0;
+ // Returns the RenderWidgetHostView that can be used to control focus and
+ // visibility for this frame.
+ virtual RenderWidgetHostView* GetView() = 0;
+
// Returns the current RenderFrameHost of the parent frame, or nullptr if
// there is no parent. The result may be in a different process than the
// current RenderFrameHost.
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 9b48ddb..7c749a2 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -65,6 +65,19 @@ class CONTENT_EXPORT RenderWidgetHostView {
// Retrieves the last known scroll position.
virtual gfx::Vector2dF GetLastScrollOffset() const = 0;
+ // Coordinate points received from a renderer process need to be transformed
+ // to the top-level frame's coordinate space. For coordinates received from
+ // the top-level frame's renderer this is a no-op as they are already
+ // properly transformed; however, coordinates received from an out-of-process
+ // iframe renderer process require transformation.
+ virtual gfx::Point TransformPointToRootCoordSpace(
+ const gfx::Point& point) = 0;
+
+ // A floating point variant of the above. PointF values will be snapped to
+ // integral points before transformation.
+ virtual gfx::PointF TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) = 0;
+
// Retrieves the native view used to contain plugins and identify the
// renderer in IPC messages.
virtual gfx::NativeView GetNativeView() const = 0;