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. It has a
10 // helper, BrowserPluginGuestHelper, which is a RenderViewHostObserver. The
11 // helper object intercepts messages (ViewHostMsg_*) directed at the browser
12 // process and redirects them to this class. Any messages about the guest render
13 // process that the embedder might be interested in receiving should be listened
16 // BrowserPluginGuest is a WebContentsDelegate and WebContentsObserver for the
17 // guest WebContents. BrowserPluginGuest operates under the assumption that the
18 // guest will be accessible through only one RenderViewHost for the lifetime of
19 // the guest WebContents. Thus, cross-process navigation is not supported.
21 #ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
22 #define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
26 #include "base/compiler_specific.h"
27 #include "base/id_map.h"
28 #include "base/memory/weak_ptr.h"
29 #include "base/shared_memory.h"
30 #include "base/time.h"
31 #include "content/common/browser_plugin/browser_plugin_message_enums.h"
32 #include "content/port/common/input_event_ack_state.h"
33 #include "content/public/browser/notification_observer.h"
34 #include "content/public/browser/notification_registrar.h"
35 #include "content/public/browser/web_contents_delegate.h"
36 #include "content/public/browser/web_contents_observer.h"
37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragStatus.h"
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
40 #include "ui/gfx/rect.h"
41 #include "ui/surface/transport_dib.h"
43 struct BrowserPluginHostMsg_AutoSize_Params
;
44 struct BrowserPluginHostMsg_CreateGuest_Params
;
45 struct BrowserPluginHostMsg_ResizeGuest_Params
;
46 struct ViewHostMsg_CreateWindow_Params
;
47 #if defined(OS_MACOSX)
48 struct ViewHostMsg_ShowPopup_Params
;
50 struct ViewHostMsg_UpdateRect_Params
;
60 class BrowserPluginHostFactory
;
61 class BrowserPluginEmbedder
;
62 class BrowserPluginGuestManager
;
63 class RenderProcessHost
;
64 class RenderWidgetHostView
;
65 struct MediaStreamRequest
;
67 // A browser plugin guest provides functionality for WebContents to operate in
68 // the guest role and implements guest specific overrides for ViewHostMsg_*
71 // BrowserPluginEmbedder is responsible for creating and destroying a guest.
72 class CONTENT_EXPORT BrowserPluginGuest
: public NotificationObserver
,
73 public WebContentsDelegate
,
74 public WebContentsObserver
{
76 typedef base::Callback
<void(bool)> GeolocationCallback
;
77 virtual ~BrowserPluginGuest();
79 static BrowserPluginGuest
* Create(
81 WebContentsImpl
* web_contents
,
82 const BrowserPluginHostMsg_CreateGuest_Params
& params
);
84 // Overrides factory for testing. Default (NULL) value indicates regular
85 // (non-test) environment.
86 static void set_factory_for_testing(BrowserPluginHostFactory
* factory
) {
87 content::BrowserPluginGuest::factory_
= factory
;
90 bool OnMessageReceivedFromEmbedder(const IPC::Message
& message
);
92 void Initialize(WebContentsImpl
* embedder_web_contents
,
93 const BrowserPluginHostMsg_CreateGuest_Params
& params
);
95 void set_guest_hang_timeout_for_testing(const base::TimeDelta
& timeout
) {
96 guest_hang_timeout_
= timeout
;
99 WebContentsImpl
* embedder_web_contents() const {
100 return embedder_web_contents_
;
103 RenderWidgetHostView
* GetEmbedderRenderWidgetHostView();
105 bool focused() const { return focused_
; }
106 bool visible() const { return guest_visible_
; }
107 void clear_damage_buffer() { damage_buffer_
.reset(); }
109 void UpdateVisibility();
111 // NotificationObserver implementation.
112 virtual void Observe(int type
,
113 const NotificationSource
& source
,
114 const NotificationDetails
& details
) OVERRIDE
;
116 // WebContentsObserver implementation.
117 virtual void DidStartProvisionalLoadForFrame(
119 int64 parent_frame_id
,
121 const GURL
& validated_url
,
123 bool is_iframe_srcdoc
,
124 RenderViewHost
* render_view_host
) OVERRIDE
;
125 virtual void DidFailProvisionalLoad(
128 const GURL
& validated_url
,
130 const string16
& error_description
,
131 RenderViewHost
* render_view_host
) OVERRIDE
;
132 virtual void DidCommitProvisionalLoadForFrame(
136 PageTransition transition_type
,
137 RenderViewHost
* render_view_host
) OVERRIDE
;
138 virtual void DidStopLoading(RenderViewHost
* render_view_host
) OVERRIDE
;
140 virtual void RenderViewReady() OVERRIDE
;
141 virtual void RenderViewGone(base::TerminationStatus status
) OVERRIDE
;
142 virtual bool OnMessageReceived(const IPC::Message
& message
) OVERRIDE
;
145 // WebContentsDelegate implementation.
146 virtual bool CanDownload(RenderViewHost
* render_view_host
,
148 const std::string
& request_method
) OVERRIDE
;
149 virtual bool HandleContextMenu(const ContextMenuParams
& params
) OVERRIDE
;
150 virtual void RendererUnresponsive(WebContents
* source
) OVERRIDE
;
151 virtual void RendererResponsive(WebContents
* source
) OVERRIDE
;
152 virtual void RunFileChooser(WebContents
* web_contents
,
153 const FileChooserParams
& params
) OVERRIDE
;
154 virtual bool ShouldFocusPageAfterCrash() OVERRIDE
;
155 virtual void RequestMediaAccessPermission(
156 WebContents
* web_contents
,
157 const content::MediaStreamRequest
& request
,
158 const content::MediaResponseCallback
& callback
) OVERRIDE
;
160 // Exposes the protected web_contents() from WebContentsObserver.
161 WebContentsImpl
* GetWebContents();
163 // Kill the guest process.
166 // Overridden in tests.
167 virtual void SetDamageBuffer(
168 const BrowserPluginHostMsg_ResizeGuest_Params
& params
);
170 gfx::Point
GetScreenCoordinates(const gfx::Point
& relative_position
) const;
172 // Helper to send messages to embedder. This methods fills the message with
173 // the correct routing id.
174 // Overridden in test implementation since we want to intercept certain
175 // messages for testing.
176 virtual void SendMessageToEmbedder(IPC::Message
* msg
);
178 // Requests geolocation permission through embedder js api.
179 void AskEmbedderForGeolocationPermission(int bridge_id
,
180 const GURL
& requesting_frame
,
181 GeolocationCallback callback
);
182 // Cancels pending geolocation request.
183 void CancelGeolocationRequest(int bridge_id
);
184 // Embedder sets permission to allow or deny geolocation request.
185 void SetGeolocationPermission(int request_id
, bool allowed
);
187 // Returns the identifier that uniquely identifies a browser plugin guest
188 // within an embedder.
189 int instance_id() const { return instance_id_
; }
191 // Allow the embedder to call this for unhandled messages when
192 // BrowserPluginGuest is already destroyed.
193 static void AcknowledgeBufferPresent(int route_id
,
195 const std::string
& mailbox_name
,
198 // Returns whether BrowserPluginGuest is interested in receiving the given
200 static bool ShouldForwardToBrowserPluginGuest(const IPC::Message
& message
);
203 typedef std::pair
<content::MediaStreamRequest
, content::MediaResponseCallback
>
204 MediaStreamRequestAndCallbackPair
;
205 typedef std::map
<int, MediaStreamRequestAndCallbackPair
>
206 MediaStreamRequestsMap
;
208 friend class TestBrowserPluginGuest
;
210 BrowserPluginGuest(int instance_id
,
211 WebContentsImpl
* web_contents
,
212 const BrowserPluginHostMsg_CreateGuest_Params
& params
);
214 // Returns the embedder's routing ID.
215 int embedder_routing_id() const;
217 // Schedules this BrowserPluginGuest for deletion if it hasn't already been
221 base::SharedMemory
* damage_buffer() const { return damage_buffer_
.get(); }
222 const gfx::Size
& damage_view_size() const { return damage_view_size_
; }
223 float damage_buffer_scale_factor() const {
224 return damage_buffer_scale_factor_
;
226 // Returns the damage buffer corresponding to the handle in resize |params|.
227 base::SharedMemory
* GetDamageBufferFromEmbedder(
228 const BrowserPluginHostMsg_ResizeGuest_Params
& params
);
230 // Called when a redirect notification occurs.
231 void LoadRedirect(const GURL
& old_url
,
235 bool InAutoSizeBounds(const gfx::Size
& size
) const;
237 // Message handlers for messsages from embedder.
239 // Allows or denies a permission request access, after the embedder has had a
241 void OnRespondPermission(int instance_id
,
242 BrowserPluginPermissionType permission_type
,
245 // Handles drag events from the embedder.
246 // When dragging, the drag events go to the embedder first, and if the drag
247 // happens on the browser plugin, then the plugin sends a corresponding
248 // drag-message to the guest. This routes the drag-message to the guest
250 void OnDragStatusUpdate(int instance_id
,
251 WebKit::WebDragStatus drag_status
,
252 const WebDropData
& drop_data
,
253 WebKit::WebDragOperationsMask drag_mask
,
254 const gfx::Point
& location
);
255 // If possible, navigate the guest to |relative_index| entries away from the
256 // current navigation entry.
257 virtual void OnGo(int instance_id
, int relative_index
);
258 // Overriden in tests.
259 virtual void OnHandleInputEvent(int instance_id
,
260 const gfx::Rect
& guest_window_rect
,
261 const WebKit::WebInputEvent
* event
);
262 void OnLockMouse(bool user_gesture
,
263 bool last_unlocked_by_target
,
265 void OnLockMouseAck(int instance_id
, bool succeeded
);
266 void OnNavigateGuest(int instance_id
, const std::string
& src
);
267 void OnPluginDestroyed(int instance_id
);
268 // Reload the guest. Overriden in tests.
269 virtual void OnReload(int instance_id
);
270 // Grab the new damage buffer from the embedder, and resize the guest's
272 void OnResizeGuest(int instance_id
,
273 const BrowserPluginHostMsg_ResizeGuest_Params
& params
);
274 // Overriden in tests.
275 virtual void OnSetFocus(int instance_id
, bool focused
);
276 // Sets the name of the guest so that other guests in the same partition can
278 void OnSetName(int instance_id
, const std::string
& name
);
279 // Updates the size state of the guest.
282 const BrowserPluginHostMsg_AutoSize_Params
& auto_size_params
,
283 const BrowserPluginHostMsg_ResizeGuest_Params
& resize_guest_params
);
284 // The guest WebContents is visible if both its embedder is visible and
285 // the browser plugin element is visible. If either one is not then the
286 // WebContents is marked as hidden. A hidden WebContents will consume
287 // fewer GPU and CPU resources.
289 // When every WebContents in a RenderProcessHost is hidden, it will lower
290 // the priority of the process (see RenderProcessHostImpl::WidgetHidden).
292 // It will also send a message to the guest renderer process to cleanup
293 // resources such as dropping back buffers and adjusting memory limits (if in
294 // compositing mode, see CCLayerTreeHost::setVisible).
296 // Additionally, it will slow down Javascript execution and garbage
297 // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and
298 // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible).
299 void OnSetVisibility(int instance_id
, bool visible
);
300 // Stop loading the guest. Overriden in tests.
301 virtual void OnStop(int instance_id
);
302 // Message from embedder acknowledging last HW buffer.
303 void OnSwapBuffersACK(int instance_id
,
306 const std::string
& mailbox_name
,
309 void OnTerminateGuest(int instance_id
);
310 void OnUnlockMouse();
311 void OnUnlockMouseAck(int instance_id
);
312 void OnUpdateRectACK(
314 const BrowserPluginHostMsg_AutoSize_Params
& auto_size_params
,
315 const BrowserPluginHostMsg_ResizeGuest_Params
& resize_guest_params
);
318 // Message handlers for messages from guest.
320 void OnCreateWindow(const ViewHostMsg_CreateWindow_Params
& params
,
323 int64
* cloned_session_storage_namespace_id
);
324 void OnHandleInputEventAck(
325 WebKit::WebInputEvent::Type event_type
,
326 InputEventAckState ack_result
);
327 void OnHasTouchEventHandlers(bool accept
);
328 void OnSetCursor(const WebCursor
& cursor
);
329 // On MacOSX popups are painted by the browser process. We handle them here
330 // so that they are positioned correctly.
331 #if defined(OS_MACOSX)
332 void OnShowPopup(const ViewHostMsg_ShowPopup_Params
& params
);
334 void OnShowWidget(int route_id
, const gfx::Rect
& initial_pos
);
335 // Overriden in tests.
336 virtual void OnTakeFocus(bool reverse
);
337 void OnUpdateDragCursor(WebKit::WebDragOperation operation
);
338 void OnUpdateFrameName(int frame_id
,
340 const std::string
& name
);
341 void OnUpdateRect(const ViewHostMsg_UpdateRect_Params
& params
);
343 // Helpers for |OnRespondPermission|.
344 void OnRespondPermissionGeolocation(int request_id
, bool should_allow
);
345 void OnRespondPermissionMedia(int request_id
, bool should_allow
);
347 // Weak pointer used to ask GeolocationPermissionContext about geolocation
349 base::WeakPtrFactory
<BrowserPluginGuest
> weak_ptr_factory_
;
351 // Static factory instance (always NULL for non-test).
352 static content::BrowserPluginHostFactory
* factory_
;
354 NotificationRegistrar notification_registrar_
;
355 WebContentsImpl
* embedder_web_contents_
;
356 typedef std::map
<int, GeolocationCallback
> GeolocationRequestsMap
;
357 GeolocationRequestsMap geolocation_request_callback_map_
;
358 // An identifier that uniquely identifies a browser plugin guest within an
361 scoped_ptr
<base::SharedMemory
> damage_buffer_
;
362 // An identifier that uniquely identifies a damage buffer.
363 uint32 damage_buffer_sequence_id_
;
364 size_t damage_buffer_size_
;
365 gfx::Size damage_view_size_
;
366 float damage_buffer_scale_factor_
;
367 gfx::Rect guest_window_rect_
;
368 gfx::Rect guest_screen_rect_
;
369 base::TimeDelta guest_hang_timeout_
;
372 bool pending_lock_request_
;
374 bool embedder_visible_
;
376 bool auto_size_enabled_
;
377 gfx::Size max_auto_size_
;
378 gfx::Size min_auto_size_
;
380 // A counter to generate a unique request id for a permission request.
381 // We only need the ids to be unique for a given BrowserPluginGuest.
382 int next_permission_request_id_
;
383 // A map to store WebContents's media request object and callback.
384 // We need to store these because we need a roundtrip to the embedder to know
385 // if we allow or disallow the request. The key of the map is unique only for
386 // a given BrowserPluginGuest.
387 MediaStreamRequestsMap media_requests_map_
;
389 DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest
);
392 } // namespace content
394 #endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_