Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / browser_plugin / browser_plugin_guest.h
blob604a34bb533ead119e9cd6dca002b054359fedef
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 // A BrowserPluginGuest is the browser side of a browser <--> embedder
6 // renderer channel. A BrowserPlugin (a WebPlugin) is on the embedder
7 // renderer side of browser <--> embedder renderer communication.
8 //
9 // BrowserPluginGuest lives on the UI thread of the browser process. Any
10 // messages about the guest render process that the embedder might be interested
11 // in receiving should be listened for here.
13 // BrowserPluginGuest is a WebContentsObserver for the guest WebContents.
14 // BrowserPluginGuest operates under the assumption that the guest will be
15 // accessible through only one RenderViewHost for the lifetime of
16 // the guest WebContents. Thus, cross-process navigation is not supported.
18 #ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
19 #define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
21 #include <map>
22 #include <queue>
24 #include "base/compiler_specific.h"
25 #include "base/memory/linked_ptr.h"
26 #include "base/memory/weak_ptr.h"
27 #include "base/values.h"
28 #include "content/common/edit_command.h"
29 #include "content/common/input/input_event_ack_state.h"
30 #include "content/public/browser/browser_plugin_guest_delegate.h"
31 #include "content/public/browser/guest_host.h"
32 #include "content/public/browser/readback_types.h"
33 #include "content/public/browser/web_contents_observer.h"
34 #include "third_party/WebKit/public/platform/WebFocusType.h"
35 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
36 #include "third_party/WebKit/public/web/WebDragOperation.h"
37 #include "third_party/WebKit/public/web/WebDragStatus.h"
38 #include "third_party/WebKit/public/web/WebInputEvent.h"
39 #include "ui/base/ime/text_input_mode.h"
40 #include "ui/base/ime/text_input_type.h"
41 #include "ui/gfx/geometry/rect.h"
43 struct BrowserPluginHostMsg_Attach_Params;
44 struct FrameHostMsg_CompositorFrameSwappedACK_Params;
45 struct FrameHostMsg_ReclaimCompositorResources_Params;
46 struct FrameMsg_CompositorFrameSwapped_Params;
47 struct ViewHostMsg_TextInputState_Params;
49 #if defined(OS_MACOSX)
50 struct FrameHostMsg_ShowPopup_Params;
51 #endif
53 namespace cc {
54 class CompositorFrame;
55 struct SurfaceId;
56 struct SurfaceSequence;
57 } // namespace cc
59 namespace gfx {
60 class Range;
61 } // namespace gfx
63 namespace content {
65 class BrowserPluginGuestManager;
66 class RenderViewHostImpl;
67 class RenderWidgetHost;
68 class RenderWidgetHostView;
69 class RenderWidgetHostViewBase;
70 class SiteInstance;
71 struct DropData;
73 // A browser plugin guest provides functionality for WebContents to operate in
74 // the guest role and implements guest-specific overrides for ViewHostMsg_*
75 // messages.
77 // When a guest is initially created, it is in an unattached state. That is,
78 // it is not visible anywhere and has no embedder WebContents assigned.
79 // A BrowserPluginGuest is said to be "attached" if it has an embedder.
80 // A BrowserPluginGuest can also create a new unattached guest via
81 // CreateNewWindow. The newly created guest will live in the same partition,
82 // which means it can share storage and can script this guest.
84 // Note: in --site-per-process, all IPCs sent out from this class will be
85 // dropped on the floor since we don't have a BrowserPlugin.
86 class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
87 public WebContentsObserver {
88 public:
89 ~BrowserPluginGuest() override;
91 // The WebContents passed into the factory method here has not been
92 // initialized yet and so it does not yet hold a SiteInstance.
93 // BrowserPluginGuest must be constructed and installed into a WebContents
94 // prior to its initialization because WebContents needs to determine what
95 // type of WebContentsView to construct on initialization. The content
96 // embedder needs to be aware of |guest_site_instance| on the guest's
97 // construction and so we pass it in here.
98 static BrowserPluginGuest* Create(WebContentsImpl* web_contents,
99 BrowserPluginGuestDelegate* delegate);
101 // Returns whether the given WebContents is a BrowserPlugin guest.
102 static bool IsGuest(WebContentsImpl* web_contents);
104 // Returns whether the given RenderviewHost is a BrowserPlugin guest.
105 static bool IsGuest(RenderViewHostImpl* render_view_host);
107 // BrowserPluginGuest::Init is called after the associated guest WebContents
108 // initializes. If this guest cannot navigate without being attached to a
109 // container, then this call is a no-op. For guest types that can be
110 // navigated, this call adds the associated RenderWdigetHostViewGuest to the
111 // view hierachy and sets up the appropriate RendererPreferences so that this
112 // guest can navigate and resize offscreen.
113 void Init();
115 // Returns a WeakPtr to this BrowserPluginGuest.
116 base::WeakPtr<BrowserPluginGuest> AsWeakPtr();
118 // Sets the focus state of the current RenderWidgetHostView.
119 void SetFocus(RenderWidgetHost* rwh,
120 bool focused,
121 blink::WebFocusType focus_type);
123 // Sets the tooltip text.
124 void SetTooltipText(const base::string16& tooltip_text);
126 // Sets the lock state of the pointer. Returns true if |allowed| is true and
127 // the mouse has been successfully locked.
128 bool LockMouse(bool allowed);
130 // Return true if the mouse is locked.
131 bool mouse_locked() const { return mouse_locked_; }
133 // Called when the embedder WebContents changes visibility.
134 void EmbedderVisibilityChanged(bool visible);
136 // Creates a new guest WebContentsImpl with the provided |params| with |this|
137 // as the |opener|.
138 WebContentsImpl* CreateNewGuestWindow(
139 const WebContents::CreateParams& params);
141 // Creates, if necessary, and returns the routing ID of a proxy for the guest
142 // in the owner's renderer process.
143 int GetGuestProxyRoutingID();
145 // Returns the identifier that uniquely identifies a browser plugin guest
146 // within an embedder.
147 int browser_plugin_instance_id() const { return browser_plugin_instance_id_; }
149 bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
151 WebContentsImpl* embedder_web_contents() const {
152 return attached_ ? owner_web_contents_ : nullptr;
155 // Returns the embedder's RenderWidgetHostView if it is available.
156 // Returns nullptr otherwise.
157 RenderWidgetHostView* GetOwnerRenderWidgetHostView();
159 bool focused() const { return focused_; }
160 bool visible() const { return guest_visible_; }
161 bool is_in_destruction() { return is_in_destruction_; }
163 void UpdateVisibility();
165 BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
167 // WebContentsObserver implementation.
168 void DidCommitProvisionalLoadForFrame(
169 RenderFrameHost* render_frame_host,
170 const GURL& url,
171 ui::PageTransition transition_type) override;
173 void RenderViewReady() override;
174 void RenderProcessGone(base::TerminationStatus status) override;
175 bool OnMessageReceived(const IPC::Message& message) override;
176 bool OnMessageReceived(const IPC::Message& message,
177 RenderFrameHost* render_frame_host) override;
179 // GuestHost implementation.
180 int LoadURLWithParams(
181 const NavigationController::LoadURLParams& load_params) override;
182 void GuestResizeDueToAutoResize(const gfx::Size& new_size) override;
183 void SizeContents(const gfx::Size& new_size) override;
184 void WillDestroy() override;
186 // Exposes the protected web_contents() from WebContentsObserver.
187 WebContentsImpl* GetWebContents() const;
189 gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const;
191 // This method is called by the RenderWidgetHostViewGuest to inform the
192 // BrowserPlugin of the potential location of the context menu event (to
193 // come). The need for this (hack) is that the input events when passed on to
194 // the BrowserPlugin are modified by any CSS transforms applied on the plugin.
195 // Therefore, the coordinates of the context menu event with respect to the
196 // container window are modifed with the guest renderer process beiung unaware
197 // of the change. Then eventually, when the context menu event arrives at the
198 // browser, it contains the wrong coordinates (BUG=470087).
199 // TODO(ekaramad): Find a more fundamental solution and remove this later.
200 void SetContextMenuPosition(const gfx::Point& position);
202 // Helper to send messages to embedder. If this guest is not yet attached,
203 // then IPCs will be queued until attachment.
204 void SendMessageToEmbedder(IPC::Message* msg);
206 // Returns whether the guest is attached to an embedder.
207 bool attached() const { return attached_; }
209 // Returns true when an attachment has taken place since the last time the
210 // compositor surface was set.
211 bool has_attached_since_surface_set() const {
212 return has_attached_since_surface_set_;
215 // Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
216 // and initializes the guest with the provided |params|. Attaching a guest
217 // to an embedder implies that this guest's lifetime is no longer managed
218 // by its opener, and it can begin loading resources.
219 void Attach(int browser_plugin_instance_id,
220 WebContentsImpl* embedder_web_contents,
221 const BrowserPluginHostMsg_Attach_Params& params);
223 // Returns whether BrowserPluginGuest is interested in receiving the given
224 // |message|.
225 static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
227 void DragSourceEndedAt(int client_x, int client_y, int screen_x,
228 int screen_y, blink::WebDragOperation operation);
230 // Called when the drag started by this guest ends at an OS-level.
231 void EmbedderSystemDragEnded();
232 void EndSystemDragIfApplicable();
234 void RespondToPermissionRequest(int request_id,
235 bool should_allow,
236 const std::string& user_input);
238 void PointerLockPermissionResponse(bool allow);
240 // The next two functions are virtual for test purposes.
241 virtual void SwapCompositorFrame(uint32 output_surface_id,
242 int host_process_id,
243 int host_routing_id,
244 scoped_ptr<cc::CompositorFrame> frame);
245 virtual void SetChildFrameSurface(const cc::SurfaceId& surface_id,
246 const gfx::Size& frame_size,
247 float scale_factor,
248 const cc::SurfaceSequence& sequence);
250 void SetContentsOpaque(bool opaque);
252 // Find the given |search_text| in the page. Returns true if the find request
253 // is handled by this browser plugin guest.
254 bool Find(int request_id,
255 const base::string16& search_text,
256 const blink::WebFindOptions& options);
257 bool StopFinding(StopFindAction action);
259 protected:
261 // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
262 // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
263 // Constructor protected for testing.
264 BrowserPluginGuest(bool has_render_view,
265 WebContentsImpl* web_contents,
266 BrowserPluginGuestDelegate* delegate);
268 // Protected for testing.
269 void set_has_attached_since_surface_set_for_test(bool has_attached) {
270 has_attached_since_surface_set_ = has_attached;
273 void set_attached_for_test(bool attached) {
274 attached_ = attached;
277 private:
278 class EmbedderVisibilityObserver;
280 void InitInternal(const BrowserPluginHostMsg_Attach_Params& params,
281 WebContentsImpl* owner_web_contents);
283 void OnSatisfySequence(int instance_id, const cc::SurfaceSequence& sequence);
284 void OnRequireSequence(int instance_id,
285 const cc::SurfaceId& id,
286 const cc::SurfaceSequence& sequence);
287 // Message handlers for messages from embedder.
288 void OnCompositorFrameSwappedACK(
289 int instance_id,
290 const FrameHostMsg_CompositorFrameSwappedACK_Params& params);
291 void OnDetach(int instance_id);
292 // Handles drag events from the embedder.
293 // When dragging, the drag events go to the embedder first, and if the drag
294 // happens on the browser plugin, then the plugin sends a corresponding
295 // drag-message to the guest. This routes the drag-message to the guest
296 // renderer.
297 void OnDragStatusUpdate(int instance_id,
298 blink::WebDragStatus drag_status,
299 const DropData& drop_data,
300 blink::WebDragOperationsMask drag_mask,
301 const gfx::Point& location);
302 // Instructs the guest to execute an edit command decoded in the embedder.
303 void OnExecuteEditCommand(int instance_id,
304 const std::string& command);
306 // Returns compositor resources reclaimed in the embedder to the guest.
307 void OnReclaimCompositorResources(
308 int instance_id,
309 const FrameHostMsg_ReclaimCompositorResources_Params& params);
311 void OnLockMouse(bool user_gesture,
312 bool last_unlocked_by_target,
313 bool privileged);
314 void OnLockMouseAck(int instance_id, bool succeeded);
315 // Resizes the guest's web contents.
316 void OnSetFocus(int instance_id,
317 bool focused,
318 blink::WebFocusType focus_type);
319 // Sets the name of the guest so that other guests in the same partition can
320 // access it.
321 void OnSetName(int instance_id, const std::string& name);
322 // Updates the size state of the guest.
323 void OnSetEditCommandsForNextKeyEvent(
324 int instance_id,
325 const std::vector<EditCommand>& edit_commands);
326 // The guest WebContents is visible if both its embedder is visible and
327 // the browser plugin element is visible. If either one is not then the
328 // WebContents is marked as hidden. A hidden WebContents will consume
329 // fewer GPU and CPU resources.
331 // When every WebContents in a RenderProcessHost is hidden, it will lower
332 // the priority of the process (see RenderProcessHostImpl::WidgetHidden).
334 // It will also send a message to the guest renderer process to cleanup
335 // resources such as dropping back buffers and adjusting memory limits (if in
336 // compositing mode, see CCLayerTreeHost::setVisible).
338 // Additionally, it will slow down Javascript execution and garbage
339 // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and
340 // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible).
341 void OnSetVisibility(int instance_id, bool visible);
342 void OnUnlockMouse();
343 void OnUnlockMouseAck(int instance_id);
344 void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect);
346 void OnTextInputStateChanged(
347 const ViewHostMsg_TextInputState_Params& params);
348 void OnImeSetComposition(
349 int instance_id,
350 const std::string& text,
351 const std::vector<blink::WebCompositionUnderline>& underlines,
352 int selection_start,
353 int selection_end);
354 void OnImeConfirmComposition(
355 int instance_id,
356 const std::string& text,
357 bool keep_selection);
358 void OnExtendSelectionAndDelete(int instance_id, int before, int after);
359 void OnImeCancelComposition();
360 #if defined(OS_MACOSX) || defined(USE_AURA)
361 void OnImeCompositionRangeChanged(
362 const gfx::Range& range,
363 const std::vector<gfx::Rect>& character_bounds);
364 #endif
366 // Message handlers for messages from guest.
367 void OnHandleInputEventAck(
368 blink::WebInputEvent::Type event_type,
369 InputEventAckState ack_result);
370 void OnHasTouchEventHandlers(bool accept);
371 #if defined(OS_MACOSX)
372 // On MacOS X popups are painted by the browser process. We handle them here
373 // so that they are positioned correctly.
374 void OnShowPopup(RenderFrameHost* render_frame_host,
375 const FrameHostMsg_ShowPopup_Params& params);
376 #endif
377 void OnShowWidget(int route_id, const gfx::Rect& initial_rect);
378 void OnTakeFocus(bool reverse);
379 void OnUpdateFrameName(int frame_id,
380 bool is_top_level,
381 const std::string& name);
383 // Called when WillAttach is complete.
384 void OnWillAttachComplete(WebContentsImpl* embedder_web_contents,
385 const BrowserPluginHostMsg_Attach_Params& params);
387 // Forwards all messages from the |pending_messages_| queue to the embedder.
388 void SendQueuedMessages();
390 void SendTextInputTypeChangedToView(RenderWidgetHostViewBase* guest_rwhv);
392 // The last tooltip that was set with SetTooltipText().
393 base::string16 current_tooltip_text_;
395 scoped_ptr<EmbedderVisibilityObserver> embedder_visibility_observer_;
396 WebContentsImpl* owner_web_contents_;
398 // Indicates whether this guest has been attached to a container.
399 bool attached_;
401 // Used to signal if a browser plugin has been attached since the last time
402 // the compositing surface was set.
403 bool has_attached_since_surface_set_;
405 // An identifier that uniquely identifies a browser plugin within an embedder.
406 int browser_plugin_instance_id_;
407 gfx::Rect guest_window_rect_;
408 bool focused_;
409 bool mouse_locked_;
410 bool pending_lock_request_;
411 bool guest_visible_;
412 bool embedder_visible_;
413 // Whether the browser plugin is inside a plugin document.
414 bool is_full_page_plugin_;
416 // Indicates that this BrowserPluginGuest has associated renderer-side state.
417 // This is used to determine whether or not to create a new RenderView when
418 // this guest is attached. A BrowserPluginGuest would have renderer-side state
419 // prior to attachment if it is created via a call to window.open and
420 // maintains a JavaScript reference to its opener.
421 bool has_render_view_;
423 // Last seen size of guest contents (by SwapCompositorFrame).
424 gfx::Size last_seen_view_size_;
426 bool is_in_destruction_;
428 // BrowserPluginGuest::Init can only be called once. This flag allows it to
429 // exit early if it's already been called.
430 bool initialized_;
432 // Text input type states.
433 // Using scoped_ptr to avoid including the header file: view_messages.h.
434 scoped_ptr<const ViewHostMsg_TextInputState_Params> last_text_input_state_;
436 // The is the routing ID for a swapped out RenderView for the guest
437 // WebContents in the embedder's process.
438 int guest_proxy_routing_id_;
439 // Last seen state of drag status update.
440 blink::WebDragStatus last_drag_status_;
441 // Whether or not our embedder has seen a SystemDragEnded() call.
442 bool seen_embedder_system_drag_ended_;
443 // Whether or not our embedder has seen a DragSourceEndedAt() call.
444 bool seen_embedder_drag_source_ended_at_;
446 // Indicates the URL dragged into the guest if any.
447 GURL dragged_url_;
449 // Guests generate frames and send a CompositorFrameSwapped (CFS) message
450 // indicating the next frame is ready to be positioned and composited.
451 // Subsequent frames are not generated until the IPC is ACKed. We would like
452 // to ensure that the guest generates frames on attachment so we directly ACK
453 // an unACKed CFS. ACKs could get lost between the time a guest is detached
454 // from a container and the time it is attached elsewhere. This mitigates this
455 // race by ensuring the guest is ACKed on attachment.
456 scoped_ptr<FrameMsg_CompositorFrameSwapped_Params> last_pending_frame_;
458 // This is a queue of messages that are destined to be sent to the embedder
459 // once the guest is attached to a particular embedder.
460 std::deque<linked_ptr<IPC::Message> > pending_messages_;
462 BrowserPluginGuestDelegate* const delegate_;
464 // Weak pointer used to ask GeolocationPermissionContext about geolocation
465 // permission.
466 base::WeakPtrFactory<BrowserPluginGuest> weak_ptr_factory_;
468 DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest);
471 } // namespace content
473 #endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_