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.
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_
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/web_contents_observer.h"
32 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
33 #include "third_party/WebKit/public/web/WebDragOperation.h"
34 #include "third_party/WebKit/public/web/WebDragStatus.h"
35 #include "third_party/WebKit/public/web/WebInputEvent.h"
36 #include "ui/base/ime/text_input_mode.h"
37 #include "ui/base/ime/text_input_type.h"
38 #include "ui/gfx/rect.h"
41 struct BrowserPluginHostMsg_AutoSize_Params
;
42 struct BrowserPluginHostMsg_Attach_Params
;
43 struct BrowserPluginHostMsg_ResizeGuest_Params
;
44 struct FrameHostMsg_CompositorFrameSwappedACK_Params
;
45 struct FrameHostMsg_ReclaimCompositorResources_Params
;
46 #if defined(OS_MACOSX)
47 struct ViewHostMsg_ShowPopup_Params
;
49 struct ViewHostMsg_TextInputState_Params
;
50 struct ViewHostMsg_UpdateRect_Params
;
62 class BrowserPluginGuestManager
;
63 class RenderViewHostImpl
;
64 class RenderWidgetHostView
;
69 // A browser plugin guest provides functionality for WebContents to operate in
70 // the guest role and implements guest-specific overrides for ViewHostMsg_*
73 // When a guest is initially created, it is in an unattached state. That is,
74 // it is not visible anywhere and has no embedder WebContents assigned.
75 // A BrowserPluginGuest is said to be "attached" if it has an embedder.
76 // A BrowserPluginGuest can also create a new unattached guest via
77 // CreateNewWindow. The newly created guest will live in the same partition,
78 // which means it can share storage and can script this guest.
79 class CONTENT_EXPORT BrowserPluginGuest
: public WebContentsObserver
{
81 virtual ~BrowserPluginGuest();
83 // The WebContents passed into the factory method here has not been
84 // initialized yet and so it does not yet hold a SiteInstance.
85 // BrowserPluginGuest must be constructed and installed into a WebContents
86 // prior to its initialization because WebContents needs to determine what
87 // type of WebContentsView to construct on initialization. The content
88 // embedder needs to be aware of |guest_site_instance| on the guest's
89 // construction and so we pass it in here.
90 static BrowserPluginGuest
* Create(
92 WebContentsImpl
* web_contents
,
93 BrowserPluginGuestDelegate
* delegate
);
95 // Returns whether the given WebContents is a BrowserPlugin guest.
96 static bool IsGuest(WebContentsImpl
* web_contents
);
98 // Returns whether the given RenderviewHost is a BrowserPlugin guest.
99 static bool IsGuest(RenderViewHostImpl
* render_view_host
);
101 // Returns a WeakPtr to this BrowserPluginGuest.
102 base::WeakPtr
<BrowserPluginGuest
> AsWeakPtr();
104 // Sets the lock state of the pointer. Returns true if |allowed| is true and
105 // the mouse has been successfully locked.
106 bool LockMouse(bool allowed
);
108 // Called when the embedder WebContents changes visibility.
109 void EmbedderVisibilityChanged(bool visible
);
111 // Destroys the guest WebContents and all its associated state, including
112 // this BrowserPluginGuest, and its new unattached windows.
115 // Creates a new guest WebContentsImpl with the provided |params| with |this|
117 WebContentsImpl
* CreateNewGuestWindow(
118 const WebContents::CreateParams
& params
);
120 // Returns the identifier that uniquely identifies a browser plugin guest
121 // within an embedder.
122 int instance_id() const { return instance_id_
; }
124 bool OnMessageReceivedFromEmbedder(const IPC::Message
& message
);
126 WebContentsImpl
* embedder_web_contents() const {
127 return embedder_web_contents_
;
130 // Returns the embedder's RenderWidgetHostView if it is available.
131 // Returns NULL otherwise.
132 RenderWidgetHostView
* GetEmbedderRenderWidgetHostView();
134 bool focused() const { return focused_
; }
135 bool visible() const { return guest_visible_
; }
136 bool is_in_destruction() { return is_in_destruction_
; }
138 void UpdateVisibility();
140 void CopyFromCompositingSurface(
141 gfx::Rect src_subrect
,
143 const base::Callback
<void(bool, const SkBitmap
&)>& callback
);
145 BrowserPluginGuestManager
* GetBrowserPluginGuestManager() const;
147 // WebContentsObserver implementation.
148 virtual void DidCommitProvisionalLoadForFrame(
149 RenderFrameHost
* render_frame_host
,
151 PageTransition transition_type
) OVERRIDE
;
153 virtual void RenderViewReady() OVERRIDE
;
154 virtual void RenderProcessGone(base::TerminationStatus status
) OVERRIDE
;
155 virtual bool OnMessageReceived(const IPC::Message
& message
) OVERRIDE
;
157 // Exposes the protected web_contents() from WebContentsObserver.
158 WebContentsImpl
* GetWebContents() const;
160 gfx::Point
GetScreenCoordinates(const gfx::Point
& relative_position
) const;
162 // Helper to send messages to embedder. This methods fills the message with
163 // the correct routing id.
164 void SendMessageToEmbedder(IPC::Message
* msg
);
166 // Returns whether the guest is attached to an embedder.
167 bool attached() const { return embedder_web_contents_
!= NULL
; }
169 // Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
170 // and initializes the guest with the provided |params|. Attaching a guest
171 // to an embedder implies that this guest's lifetime is no longer managed
172 // by its opener, and it can begin loading resources. |extra_params| are
173 // parameters passed into BrowserPlugin from JavaScript to be forwarded to
174 // the content embedder.
175 void Attach(WebContentsImpl
* embedder_web_contents
,
176 const BrowserPluginHostMsg_Attach_Params
& params
,
177 const base::DictionaryValue
& extra_params
);
179 // Returns whether BrowserPluginGuest is interested in receiving the given
181 static bool ShouldForwardToBrowserPluginGuest(const IPC::Message
& message
);
182 gfx::Rect
ToGuestRect(const gfx::Rect
& rect
);
184 void DragSourceEndedAt(int client_x
, int client_y
, int screen_x
,
185 int screen_y
, blink::WebDragOperation operation
);
187 // Called when the drag started by this guest ends at an OS-level.
188 void EndSystemDrag();
190 void RespondToPermissionRequest(int request_id
,
192 const std::string
& user_input
);
194 void PointerLockPermissionResponse(bool allow
);
197 class EmbedderWebContentsObserver
;
199 // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
200 // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
201 BrowserPluginGuest(int instance_id
,
202 bool has_render_view
,
203 WebContentsImpl
* web_contents
,
204 BrowserPluginGuestDelegate
* delegate
);
208 void Initialize(const BrowserPluginHostMsg_Attach_Params
& params
,
209 WebContentsImpl
* embedder_web_contents
,
210 const base::DictionaryValue
& extra_params
);
212 bool InAutoSizeBounds(const gfx::Size
& size
) const;
214 // Message handlers for messages from embedder.
216 void OnCompositorFrameSwappedACK(
218 const FrameHostMsg_CompositorFrameSwappedACK_Params
& params
);
219 void OnCopyFromCompositingSurfaceAck(int instance_id
,
221 const SkBitmap
& bitmap
);
222 // Handles drag events from the embedder.
223 // When dragging, the drag events go to the embedder first, and if the drag
224 // happens on the browser plugin, then the plugin sends a corresponding
225 // drag-message to the guest. This routes the drag-message to the guest
227 void OnDragStatusUpdate(int instance_id
,
228 blink::WebDragStatus drag_status
,
229 const DropData
& drop_data
,
230 blink::WebDragOperationsMask drag_mask
,
231 const gfx::Point
& location
);
232 // Instructs the guest to execute an edit command decoded in the embedder.
233 void OnExecuteEditCommand(int instance_id
,
234 const std::string
& command
);
236 // Returns compositor resources reclaimed in the embedder to the guest.
237 void OnReclaimCompositorResources(
239 const FrameHostMsg_ReclaimCompositorResources_Params
& params
);
241 void OnHandleInputEvent(int instance_id
,
242 const gfx::Rect
& guest_window_rect
,
243 const blink::WebInputEvent
* event
);
244 void OnLockMouse(bool user_gesture
,
245 bool last_unlocked_by_target
,
247 void OnLockMouseAck(int instance_id
, bool succeeded
);
248 void OnPluginDestroyed(int instance_id
);
249 // Resizes the guest's web contents.
251 int instance_id
, const BrowserPluginHostMsg_ResizeGuest_Params
& params
);
252 void OnSetFocus(int instance_id
, bool focused
);
253 // Sets the name of the guest so that other guests in the same partition can
255 void OnSetName(int instance_id
, const std::string
& name
);
256 // Updates the size state of the guest.
257 void OnSetEditCommandsForNextKeyEvent(
259 const std::vector
<EditCommand
>& edit_commands
);
260 void OnSetContentsOpaque(int instance_id
, bool opaque
);
261 // The guest WebContents is visible if both its embedder is visible and
262 // the browser plugin element is visible. If either one is not then the
263 // WebContents is marked as hidden. A hidden WebContents will consume
264 // fewer GPU and CPU resources.
266 // When every WebContents in a RenderProcessHost is hidden, it will lower
267 // the priority of the process (see RenderProcessHostImpl::WidgetHidden).
269 // It will also send a message to the guest renderer process to cleanup
270 // resources such as dropping back buffers and adjusting memory limits (if in
271 // compositing mode, see CCLayerTreeHost::setVisible).
273 // Additionally, it will slow down Javascript execution and garbage
274 // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and
275 // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible).
276 void OnSetVisibility(int instance_id
, bool visible
);
277 void OnUnlockMouse();
278 void OnUnlockMouseAck(int instance_id
);
279 void OnUpdateGeometry(int instance_id
, const gfx::Rect
& view_rect
);
281 void OnTextInputStateChanged(
282 const ViewHostMsg_TextInputState_Params
& params
);
284 void OnImeSetComposition(
286 const std::string
& text
,
287 const std::vector
<blink::WebCompositionUnderline
>& underlines
,
290 void OnImeConfirmComposition(
292 const std::string
& text
,
293 bool keep_selection
);
294 void OnExtendSelectionAndDelete(int instance_id
, int before
, int after
);
295 void OnImeCancelComposition();
296 #if defined(OS_MACOSX) || defined(USE_AURA)
297 void OnImeCompositionRangeChanged(
298 const gfx::Range
& range
,
299 const std::vector
<gfx::Rect
>& character_bounds
);
302 // Message handlers for messages from guest.
304 void OnDragStopped();
305 void OnHandleInputEventAck(
306 blink::WebInputEvent::Type event_type
,
307 InputEventAckState ack_result
);
308 void OnHasTouchEventHandlers(bool accept
);
309 void OnSetCursor(const WebCursor
& cursor
);
310 // On MacOSX popups are painted by the browser process. We handle them here
311 // so that they are positioned correctly.
312 #if defined(OS_MACOSX)
313 void OnShowPopup(const ViewHostMsg_ShowPopup_Params
& params
);
315 void OnShowWidget(int route_id
, const gfx::Rect
& initial_pos
);
316 void OnTakeFocus(bool reverse
);
317 void OnUpdateFrameName(int frame_id
,
319 const std::string
& name
);
320 void OnUpdateRect(const ViewHostMsg_UpdateRect_Params
& params
);
322 // Forwards all messages from the |pending_messages_| queue to the embedder.
323 void SendQueuedMessages();
325 scoped_ptr
<EmbedderWebContentsObserver
> embedder_web_contents_observer_
;
326 WebContentsImpl
* embedder_web_contents_
;
328 // An identifier that uniquely identifies a browser plugin guest within an
330 const int instance_id_
;
331 float guest_device_scale_factor_
;
332 gfx::Rect guest_window_rect_
;
333 gfx::Rect guest_screen_rect_
;
336 bool pending_lock_request_
;
339 bool embedder_visible_
;
341 // Each copy-request is identified by a unique number. The unique number is
342 // used to keep track of the right callback.
343 int copy_request_id_
;
344 typedef base::Callback
<void(bool, const SkBitmap
&)> CopyRequestCallback
;
345 typedef std::map
<int, const CopyRequestCallback
> CopyRequestMap
;
346 CopyRequestMap copy_request_callbacks_
;
348 // Indicates that this BrowserPluginGuest has associated renderer-side state.
349 // This is used to determine whether or not to create a new RenderView when
350 // this guest is attached. A BrowserPluginGuest would have renderer-side state
351 // prior to attachment if it is created via a call to window.open and
352 // maintains a JavaScript reference to its opener.
353 bool has_render_view_
;
355 // Last seen size of guest contents (by OnUpdateRect).
356 gfx::Size last_seen_view_size_
;
357 // Last seen size of BrowserPlugin (by OnResizeGuest).
358 gfx::Size last_seen_browser_plugin_size_
;
360 bool is_in_destruction_
;
362 // Text input type states.
363 ui::TextInputType last_text_input_type_
;
364 ui::TextInputMode last_input_mode_
;
365 bool last_can_compose_inline_
;
367 // This is a queue of messages that are destined to be sent to the embedder
368 // once the guest is attached to a particular embedder.
369 std::deque
<linked_ptr
<IPC::Message
> > pending_messages_
;
371 BrowserPluginGuestDelegate
* const delegate_
;
373 // Weak pointer used to ask GeolocationPermissionContext about geolocation
375 base::WeakPtrFactory
<BrowserPluginGuest
> weak_ptr_factory_
;
377 DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest
);
380 } // namespace content
382 #endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_