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 WebContentsDelegate and WebContentsObserver for the
14 // guest WebContents. BrowserPluginGuest operates under the assumption that the
15 // guest will be 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/weak_ptr.h"
26 #include "base/values.h"
27 #include "content/common/edit_command.h"
28 #include "content/common/input/input_event_ack_state.h"
29 #include "content/public/browser/browser_plugin_guest_delegate.h"
30 #include "content/public/browser/web_contents_delegate.h"
31 #include "content/public/browser/web_contents_observer.h"
32 #include "content/public/common/browser_plugin_permission_type.h"
33 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
34 #include "third_party/WebKit/public/web/WebDragOperation.h"
35 #include "third_party/WebKit/public/web/WebDragStatus.h"
36 #include "third_party/WebKit/public/web/WebInputEvent.h"
37 #include "ui/base/ime/text_input_mode.h"
38 #include "ui/base/ime/text_input_type.h"
39 #include "ui/gfx/rect.h"
40 #include "ui/surface/transport_dib.h"
42 struct BrowserPluginHostMsg_AutoSize_Params;
43 struct BrowserPluginHostMsg_Attach_Params;
44 struct BrowserPluginHostMsg_ResizeGuest_Params;
45 struct FrameHostMsg_CompositorFrameSwappedACK_Params;
46 struct FrameHostMsg_ReclaimCompositorResources_Params;
47 #if defined(OS_MACOSX)
48 struct ViewHostMsg_ShowPopup_Params;
50 struct ViewHostMsg_UpdateRect_Params;
62 class BrowserPluginGuestManager;
63 class BrowserPluginHostFactory;
64 class RenderWidgetHostView;
68 struct MediaStreamRequest;
70 // A browser plugin guest provides functionality for WebContents to operate in
71 // the guest role and implements guest-specific overrides for ViewHostMsg_*
74 // When a guest is initially created, it is in an unattached state. That is,
75 // it is not visible anywhere and has no embedder WebContents assigned.
76 // A BrowserPluginGuest is said to be "attached" if it has an embedder.
77 // A BrowserPluginGuest can also create a new unattached guest via
78 // CreateNewWindow. The newly created guest will live in the same partition,
79 // which means it can share storage and can script this guest.
80 class CONTENT_EXPORT BrowserPluginGuest
81 : public WebContentsDelegate,
82 public WebContentsObserver {
84 virtual ~BrowserPluginGuest();
86 // The WebContents passed into the factory method here has not been
87 // initialized yet and so it does not yet hold a SiteInstance.
88 // BrowserPluginGuest must be constructed and installed into a WebContents
89 // prior to its initialization because WebContents needs to determine what
90 // type of WebContentsView to construct on initialization. The content
91 // embedder needs to be aware of |guest_site_instance| on the guest's
92 // construction and so we pass it in here.
93 static BrowserPluginGuest* Create(
95 SiteInstance* guest_site_instance,
96 WebContentsImpl* web_contents,
97 scoped_ptr<base::DictionaryValue> extra_params);
99 static BrowserPluginGuest* CreateWithOpener(
101 bool has_render_view,
102 WebContentsImpl* web_contents,
103 BrowserPluginGuest* opener);
105 // Returns a WeakPtr to this BrowserPluginGuest.
106 base::WeakPtr<BrowserPluginGuest> AsWeakPtr();
108 // Called when the embedder WebContents is destroyed to give the
109 // BrowserPluginGuest an opportunity to clean up after itself.
110 void EmbedderDestroyed();
112 // Called when the embedder WebContents changes visibility.
113 void EmbedderVisibilityChanged(bool visible);
115 // Destroys the guest WebContents and all its associated state, including
116 // this BrowserPluginGuest, and its new unattached windows.
119 // Returns the identifier that uniquely identifies a browser plugin guest
120 // within an embedder.
121 int instance_id() const { return instance_id_; }
123 bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
125 void Initialize(const BrowserPluginHostMsg_Attach_Params& params,
126 WebContentsImpl* embedder_web_contents);
128 WebContentsImpl* embedder_web_contents() const {
129 return embedder_web_contents_;
132 // Returns the embedder's RenderWidgetHostView if it is available.
133 // Returns NULL otherwise.
134 RenderWidgetHostView* GetEmbedderRenderWidgetHostView();
136 bool focused() const { return focused_; }
137 bool visible() const { return guest_visible_; }
138 bool is_in_destruction() { return is_in_destruction_; }
140 // Returns the BrowserPluginGuest that created this guest, if any.
141 BrowserPluginGuest* GetOpener() const;
143 // Returns whether the mouse pointer was unlocked.
144 bool UnlockMouseIfNecessary(const NativeWebKeyboardEvent& event);
146 void UpdateVisibility();
148 void CopyFromCompositingSurface(
149 gfx::Rect src_subrect,
151 const base::Callback<void(bool, const SkBitmap&)>& callback);
153 BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
155 // WebContentsObserver implementation.
156 virtual void DidCommitProvisionalLoadForFrame(
158 const base::string16& frame_unique_name,
161 PageTransition transition_type,
162 RenderViewHost* render_view_host) OVERRIDE;
163 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE;
165 virtual void RenderViewReady() OVERRIDE;
166 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
167 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
169 // WebContentsDelegate implementation.
170 virtual bool AddMessageToConsole(WebContents* source,
172 const base::string16& message,
174 const base::string16& source_id) OVERRIDE;
175 // If a new window is created with target="_blank" and rel="noreferrer", then
176 // this method is called, indicating that the new WebContents is ready to be
178 virtual void AddNewContents(WebContents* source,
179 WebContents* new_contents,
180 WindowOpenDisposition disposition,
181 const gfx::Rect& initial_pos,
183 bool* was_blocked) OVERRIDE;
184 virtual void CanDownload(RenderViewHost* render_view_host,
186 const std::string& request_method,
187 const base::Callback<void(bool)>& callback) OVERRIDE;
188 virtual void LoadProgressChanged(WebContents* source,
189 double progress) OVERRIDE;
190 virtual void CloseContents(WebContents* source) OVERRIDE;
191 virtual JavaScriptDialogManager* GetJavaScriptDialogManager() OVERRIDE;
192 virtual ColorChooser* OpenColorChooser(
193 WebContents* web_contents,
195 const std::vector<ColorSuggestion>& suggestions) OVERRIDE;
196 virtual bool HandleContextMenu(const ContextMenuParams& params) OVERRIDE;
197 virtual void HandleKeyboardEvent(
199 const NativeWebKeyboardEvent& event) OVERRIDE;
200 virtual void FindReply(WebContents* contents,
202 int number_of_matches,
203 const gfx::Rect& selection_rect,
204 int active_match_ordinal,
205 bool final_update) OVERRIDE;
206 virtual WebContents* OpenURLFromTab(WebContents* source,
207 const OpenURLParams& params) OVERRIDE;
208 virtual void WebContentsCreated(WebContents* source_contents,
209 int opener_render_frame_id,
210 const base::string16& frame_name,
211 const GURL& target_url,
212 WebContents* new_contents) OVERRIDE;
213 virtual void RendererUnresponsive(WebContents* source) OVERRIDE;
214 virtual void RendererResponsive(WebContents* source) OVERRIDE;
215 virtual void RunFileChooser(WebContents* web_contents,
216 const FileChooserParams& params) OVERRIDE;
217 virtual bool ShouldFocusPageAfterCrash() OVERRIDE;
218 virtual void RequestMediaAccessPermission(
219 WebContents* web_contents,
220 const MediaStreamRequest& request,
221 const MediaResponseCallback& callback) OVERRIDE;
222 virtual bool PreHandleGestureEvent(
223 content::WebContents* source,
224 const blink::WebGestureEvent& event) OVERRIDE;
226 // Exposes the protected web_contents() from WebContentsObserver.
227 WebContentsImpl* GetWebContents() const;
229 gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const;
231 // Helper to send messages to embedder. This methods fills the message with
232 // the correct routing id.
233 // Overridden in test implementation since we want to intercept certain
234 // messages for testing.
235 virtual void SendMessageToEmbedder(IPC::Message* msg);
237 // Returns whether the guest is attached to an embedder.
238 bool attached() const { return embedder_web_contents_ != NULL; }
240 // Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
241 // and initializes the guest with the provided |params|. Attaching a guest
242 // to an embedder implies that this guest's lifetime is no longer managed
243 // by its opener, and it can begin loading resources. |extra_params| are
244 // parameters passed into BrowserPlugin from JavaScript to be forwarded to
245 // the content embedder.
246 void Attach(WebContentsImpl* embedder_web_contents,
247 BrowserPluginHostMsg_Attach_Params params,
248 const base::DictionaryValue& extra_params);
250 // Returns whether BrowserPluginGuest is interested in receiving the given
252 static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
253 gfx::Rect ToGuestRect(const gfx::Rect& rect);
255 void DragSourceEndedAt(int client_x, int client_y, int screen_x,
256 int screen_y, blink::WebDragOperation operation);
258 // Called when the drag started by this guest ends at an OS-level.
259 void EndSystemDrag();
261 // |this| takes ownership of |delegate|.
262 void SetDelegate(BrowserPluginGuestDelegate* delegate);
264 void RespondToPermissionRequest(int request_id,
266 const std::string& user_input);
268 // Overrides factory for testing. Default (NULL) value indicates regular
269 // (non-test) environment.
270 static void set_factory_for_testing(BrowserPluginHostFactory* factory) {
271 BrowserPluginGuest::factory_ = factory;
274 void SetZoom(double zoom_factor);
276 void PointerLockPermissionResponse(bool allow);
279 class EmbedderWebContentsObserver;
280 friend class TestBrowserPluginGuest;
282 class DownloadRequest;
283 class NewWindowRequest;
284 class PermissionRequest;
286 // Tracks the name, and target URL of the new window and whether or not it has
287 // changed since the WebContents has been created and before the new window
288 // has been attached to a BrowserPlugin. Once the first navigation commits, we
289 // no longer track this information.
290 struct NewWindowInfo {
294 NewWindowInfo(const GURL& url, const std::string& name) :
300 // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
301 // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
302 BrowserPluginGuest(int instance_id,
303 bool has_render_view,
304 WebContentsImpl* web_contents);
306 // Destroy unattached new windows that have been opened by this
307 // BrowserPluginGuest.
308 void DestroyUnattachedWindows();
310 void LoadURLWithParams(const GURL& url,
311 const Referrer& referrer,
312 PageTransition transition_type,
313 WebContents* web_contents);
315 // Returns the |request_id| generated for the |request| provided.
316 void RequestPermission(
317 BrowserPluginPermissionType permission_type,
318 scoped_refptr<BrowserPluginGuest::PermissionRequest> request,
319 const base::DictionaryValue& request_info);
321 // Creates a new guest window, and BrowserPluginGuest that is owned by this
322 // BrowserPluginGuest.
323 BrowserPluginGuest* CreateNewGuestWindow(const OpenURLParams& params);
325 bool InAutoSizeBounds(const gfx::Size& size) const;
327 void RequestNewWindowPermission(WindowOpenDisposition disposition,
328 const gfx::Rect& initial_bounds,
330 WebContentsImpl* new_contents);
332 // Message handlers for messages from embedder.
334 void OnCompositorFrameSwappedACK(
336 const FrameHostMsg_CompositorFrameSwappedACK_Params& params);
337 void OnCopyFromCompositingSurfaceAck(int instance_id,
339 const SkBitmap& bitmap);
340 // Handles drag events from the embedder.
341 // When dragging, the drag events go to the embedder first, and if the drag
342 // happens on the browser plugin, then the plugin sends a corresponding
343 // drag-message to the guest. This routes the drag-message to the guest
345 void OnDragStatusUpdate(int instance_id,
346 blink::WebDragStatus drag_status,
347 const DropData& drop_data,
348 blink::WebDragOperationsMask drag_mask,
349 const gfx::Point& location);
350 // Instructs the guest to execute an edit command decoded in the embedder.
351 void OnExecuteEditCommand(int instance_id,
352 const std::string& command);
354 // Returns compositor resources reclaimed in the embedder to the guest.
355 void OnReclaimCompositorResources(
357 const FrameHostMsg_ReclaimCompositorResources_Params& params);
359 // Overridden in tests.
360 virtual void OnHandleInputEvent(int instance_id,
361 const gfx::Rect& guest_window_rect,
362 const blink::WebInputEvent* event);
363 void OnLockMouse(bool user_gesture,
364 bool last_unlocked_by_target,
366 void OnLockMouseAck(int instance_id, bool succeeded);
367 void OnNavigateGuest(int instance_id, const std::string& src);
368 void OnPluginDestroyed(int instance_id);
369 // Resizes the guest's web contents.
370 // Overridden in tests.
371 virtual void OnResizeGuest(
372 int instance_id, const BrowserPluginHostMsg_ResizeGuest_Params& params);
373 // Overridden in tests.
374 virtual void OnSetFocus(int instance_id, bool focused);
375 // Sets the name of the guest so that other guests in the same partition can
377 void OnSetName(int instance_id, const std::string& name);
378 // Updates the size state of the guest.
381 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
382 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params);
383 void OnSetEditCommandsForNextKeyEvent(
385 const std::vector<EditCommand>& edit_commands);
386 void OnSetContentsOpaque(int instance_id, bool opaque);
387 // The guest WebContents is visible if both its embedder is visible and
388 // the browser plugin element is visible. If either one is not then the
389 // WebContents is marked as hidden. A hidden WebContents will consume
390 // fewer GPU and CPU resources.
392 // When every WebContents in a RenderProcessHost is hidden, it will lower
393 // the priority of the process (see RenderProcessHostImpl::WidgetHidden).
395 // It will also send a message to the guest renderer process to cleanup
396 // resources such as dropping back buffers and adjusting memory limits (if in
397 // compositing mode, see CCLayerTreeHost::setVisible).
399 // Additionally, it will slow down Javascript execution and garbage
400 // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and
401 // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible).
402 void OnSetVisibility(int instance_id, bool visible);
403 void OnUnlockMouse();
404 void OnUnlockMouseAck(int instance_id);
405 void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect);
407 void OnTextInputTypeChanged(ui::TextInputType type,
408 ui::TextInputMode input_mode,
409 bool can_compose_inline);
410 void OnImeSetComposition(
412 const std::string& text,
413 const std::vector<blink::WebCompositionUnderline>& underlines,
416 void OnImeConfirmComposition(
418 const std::string& text,
419 bool keep_selection);
420 void OnExtendSelectionAndDelete(int instance_id, int before, int after);
421 // Overridden in tests.
422 virtual void OnImeCancelComposition();
423 #if defined(OS_MACOSX) || defined(USE_AURA)
424 void OnImeCompositionRangeChanged(
425 const gfx::Range& range,
426 const std::vector<gfx::Rect>& character_bounds);
429 // Message handlers for messages from guest.
431 void OnDragStopped();
432 void OnHandleInputEventAck(
433 blink::WebInputEvent::Type event_type,
434 InputEventAckState ack_result);
435 void OnHasTouchEventHandlers(bool accept);
436 void OnSetCursor(const WebCursor& cursor);
437 // On MacOSX popups are painted by the browser process. We handle them here
438 // so that they are positioned correctly.
439 #if defined(OS_MACOSX)
440 void OnShowPopup(const ViewHostMsg_ShowPopup_Params& params);
442 void OnShowWidget(int route_id, const gfx::Rect& initial_pos);
443 // Overridden in tests.
444 virtual void OnTakeFocus(bool reverse);
445 void OnUpdateFrameName(int frame_id,
447 const std::string& name);
448 void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
450 // Requests download permission through embedder JavaScript API after
451 // retrieving url information from IO thread.
452 void DidRetrieveDownloadURLFromRequestId(
453 const std::string& request_method,
454 const base::Callback<void(bool)>& callback,
457 // Forwards all messages from the |pending_messages_| queue to the embedder.
458 void SendQueuedMessages();
460 // Static factory instance (always NULL for non-test).
461 static BrowserPluginHostFactory* factory_;
463 scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_;
464 WebContentsImpl* embedder_web_contents_;
466 // An identifier that uniquely identifies a browser plugin guest within an
469 float guest_device_scale_factor_;
470 gfx::Rect guest_window_rect_;
471 gfx::Rect guest_screen_rect_;
472 base::TimeDelta guest_hang_timeout_;
475 bool pending_lock_request_;
478 bool embedder_visible_;
480 bool auto_size_enabled_;
481 gfx::Size max_auto_size_;
482 gfx::Size min_auto_size_;
483 gfx::Size full_size_;
485 // Each copy-request is identified by a unique number. The unique number is
486 // used to keep track of the right callback.
487 int copy_request_id_;
488 typedef base::Callback<void(bool, const SkBitmap&)> CopyRequestCallback;
489 typedef std::map<int, const CopyRequestCallback> CopyRequestMap;
490 CopyRequestMap copy_request_callbacks_;
492 typedef std::map<BrowserPluginGuest*, NewWindowInfo> PendingWindowMap;
493 PendingWindowMap pending_new_windows_;
494 // A counter to generate a unique request id for a permission request.
495 // We only need the ids to be unique for a given BrowserPluginGuest.
496 int next_permission_request_id_;
498 // A map to store relevant info for a request keyed by the request's id.
499 typedef std::map<int, scoped_refptr<PermissionRequest> > RequestMap;
500 RequestMap permission_request_map_;
502 // Indicates that this BrowserPluginGuest has associated renderer-side state.
503 // This is used to determine whether or not to create a new RenderView when
504 // this guest is attached.
505 bool has_render_view_;
507 // Last seen size of guest contents (by OnUpdateRect).
508 gfx::Size last_seen_view_size_;
509 // Last seen autosize attribute state (by OnUpdateRect).
510 bool last_seen_auto_size_enabled_;
512 bool is_in_destruction_;
514 // Text input type states.
515 ui::TextInputType last_text_input_type_;
516 ui::TextInputMode last_input_mode_;
517 bool last_can_compose_inline_;
519 // This is a queue of messages that are destined to be sent to the embedder
520 // once the guest is attached to a particular embedder.
521 std::queue<IPC::Message*> pending_messages_;
523 scoped_ptr<BrowserPluginGuestDelegate> delegate_;
525 // These are parameters passed from JavaScript on attachment to the content
527 scoped_ptr<base::DictionaryValue> extra_attach_params_;
529 // Weak pointer used to ask GeolocationPermissionContext about geolocation
531 base::WeakPtrFactory<BrowserPluginGuest> weak_ptr_factory_;
533 DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest);
536 } // namespace content
538 #endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_