Use multiline attribute to check for IA2_STATE_MULTILINE.
[chromium-blink-merge.git] / content / browser / browser_plugin / browser_plugin_embedder.cc
blob28aa57f750411bea773b3c6385ca946841de70c2
1 // Copyright (c) 2012 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.
5 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
7 #include "content/browser/browser_plugin/browser_plugin_guest.h"
8 #include "content/browser/renderer_host/render_view_host_impl.h"
9 #include "content/browser/web_contents/web_contents_impl.h"
10 #include "content/common/browser_plugin/browser_plugin_messages.h"
11 #include "content/common/drag_messages.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/browser_plugin_guest_manager.h"
14 #include "content/public/browser/native_web_keyboard_event.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "third_party/WebKit/public/web/WebFindOptions.h"
17 #include "ui/events/keycodes/keyboard_codes.h"
19 namespace content {
21 BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents)
22 : WebContentsObserver(web_contents),
23 guest_drag_ending_(false),
24 weak_ptr_factory_(this) {
27 BrowserPluginEmbedder::~BrowserPluginEmbedder() {
30 // static
31 BrowserPluginEmbedder* BrowserPluginEmbedder::Create(
32 WebContentsImpl* web_contents) {
33 return new BrowserPluginEmbedder(web_contents);
36 bool BrowserPluginEmbedder::DragEnteredGuest(BrowserPluginGuest* guest) {
37 guest_dragging_over_ = guest->AsWeakPtr();
38 return guest_started_drag_.get() == guest;
41 void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
42 // Avoid race conditions in switching between guests being hovered over by
43 // only un-setting if the caller is marked as the guest being dragged over.
44 if (guest_dragging_over_.get() == guest) {
45 guest_dragging_over_.reset();
49 // static
50 bool BrowserPluginEmbedder::NotifyScreenInfoChanged(
51 WebContents* guest_web_contents) {
52 if (guest_web_contents->GetRenderViewHost()) {
53 auto render_widget_host =
54 RenderWidgetHostImpl::From(guest_web_contents->GetRenderViewHost());
55 render_widget_host->NotifyScreenInfoChanged();
58 // Returns false to iterate over all guests.
59 return false;
62 void BrowserPluginEmbedder::ScreenInfoChanged() {
63 GetBrowserPluginGuestManager()->ForEachGuest(web_contents(), base::Bind(
64 &BrowserPluginEmbedder::NotifyScreenInfoChanged));
67 void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
68 guest_started_drag_ = guest->AsWeakPtr();
69 guest_drag_ending_ = false;
72 BrowserPluginGuestManager*
73 BrowserPluginEmbedder::GetBrowserPluginGuestManager() const {
74 return web_contents()->GetBrowserContext()->GetGuestManager();
77 void BrowserPluginEmbedder::ClearGuestDragStateIfApplicable() {
78 // The order at which we observe SystemDragEnded() and DragSourceEndedAt() is
79 // platform dependent.
80 // In OSX, we see SystemDragEnded() first, where in aura, we see
81 // DragSourceEndedAt() first. For this reason, we check if both methods were
82 // called before resetting |guest_started_drag_|.
83 if (guest_drag_ending_) {
84 if (guest_started_drag_)
85 guest_started_drag_.reset();
86 } else {
87 guest_drag_ending_ = true;
91 // static
92 bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
93 WebContents* guest_web_contents) {
94 static_cast<RenderViewHostImpl*>(
95 guest_web_contents->GetRenderViewHost())->SendScreenRects();
96 // Not handled => Iterate over all guests.
97 return false;
100 void BrowserPluginEmbedder::DidSendScreenRects() {
101 GetBrowserPluginGuestManager()->ForEachGuest(
102 web_contents(),
103 base::Bind(&BrowserPluginEmbedder::DidSendScreenRectsCallback));
106 bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
107 return OnMessageReceived(message, nullptr);
110 bool BrowserPluginEmbedder::OnMessageReceived(
111 const IPC::Message& message,
112 RenderFrameHost* render_frame_host) {
113 bool handled = true;
114 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserPluginEmbedder, message,
115 render_frame_host)
116 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Attach, OnAttach)
117 IPC_MESSAGE_HANDLER_GENERIC(DragHostMsg_UpdateDragCursor,
118 OnUpdateDragCursor(&handled));
119 IPC_MESSAGE_UNHANDLED(handled = false)
120 IPC_END_MESSAGE_MAP()
121 return handled;
124 void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
125 int screen_x, int screen_y, blink::WebDragOperation operation) {
126 if (guest_started_drag_) {
127 gfx::Point guest_offset =
128 guest_started_drag_->GetScreenCoordinates(gfx::Point());
129 guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(),
130 client_y - guest_offset.y(), screen_x, screen_y, operation);
132 ClearGuestDragStateIfApplicable();
135 void BrowserPluginEmbedder::SystemDragEnded() {
136 // When the embedder's drag/drop operation ends, we need to pass the message
137 // to the guest that initiated the drag/drop operation. This will ensure that
138 // the guest's RVH state is reset properly.
139 if (guest_started_drag_)
140 guest_started_drag_->EmbedderSystemDragEnded();
142 guest_dragging_over_.reset();
143 ClearGuestDragStateIfApplicable();
146 void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) {
147 *handled = !!guest_dragging_over_;
150 void BrowserPluginEmbedder::OnAttach(
151 RenderFrameHost* render_frame_host,
152 int browser_plugin_instance_id,
153 const BrowserPluginHostMsg_Attach_Params& params) {
154 WebContents* guest_web_contents =
155 GetBrowserPluginGuestManager()->GetGuestByInstanceID(
156 render_frame_host->GetProcess()->GetID(),
157 browser_plugin_instance_id);
158 if (!guest_web_contents)
159 return;
160 BrowserPluginGuest* guest = static_cast<WebContentsImpl*>(guest_web_contents)
161 ->GetBrowserPluginGuest();
162 guest->Attach(browser_plugin_instance_id,
163 static_cast<WebContentsImpl*>(web_contents()),
164 params);
167 bool BrowserPluginEmbedder::HandleKeyboardEvent(
168 const NativeWebKeyboardEvent& event) {
169 if ((event.windowsKeyCode != ui::VKEY_ESCAPE) ||
170 (event.modifiers & blink::WebInputEvent::InputModifiers)) {
171 return false;
174 bool event_consumed = false;
175 GetBrowserPluginGuestManager()->ForEachGuest(
176 web_contents(),
177 base::Bind(&BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback,
178 &event_consumed));
180 return event_consumed;
183 bool BrowserPluginEmbedder::Find(int request_id,
184 const base::string16& search_text,
185 const blink::WebFindOptions& options) {
186 return GetBrowserPluginGuestManager()->ForEachGuest(
187 web_contents(),
188 base::Bind(&BrowserPluginEmbedder::FindInGuest,
189 request_id,
190 search_text,
191 options));
194 bool BrowserPluginEmbedder::StopFinding(StopFindAction action) {
195 return GetBrowserPluginGuestManager()->ForEachGuest(
196 web_contents(),
197 base::Bind(&BrowserPluginEmbedder::StopFindingInGuest, action));
200 // static
201 bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool* mouse_unlocked,
202 WebContents* guest) {
203 *mouse_unlocked |= static_cast<WebContentsImpl*>(guest)
204 ->GetBrowserPluginGuest()
205 ->mouse_locked();
206 guest->GotResponseToLockMouseRequest(false);
208 // Returns false to iterate over all guests.
209 return false;
212 // static
213 bool BrowserPluginEmbedder::FindInGuest(int request_id,
214 const base::string16& search_text,
215 const blink::WebFindOptions& options,
216 WebContents* guest) {
217 if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest()->Find(
218 request_id, search_text, options)) {
219 // There can only ever currently be one browser plugin that handles find so
220 // we can break the iteration at this point.
221 return true;
223 return false;
226 bool BrowserPluginEmbedder::StopFindingInGuest(StopFindAction action,
227 WebContents* guest) {
228 if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest()
229 ->StopFinding(action)) {
230 // There can only ever currently be one browser plugin that handles find so
231 // we can break the iteration at this point.
232 return true;
234 return false;
237 } // namespace content