• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
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.
12 //
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.
17 
18 #ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
19 #define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
20 
21 #include <map>
22 #include <queue>
23 
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"
39 
40 class SkBitmap;
41 struct BrowserPluginHostMsg_Attach_Params;
42 struct BrowserPluginHostMsg_ResizeGuest_Params;
43 struct FrameHostMsg_CompositorFrameSwappedACK_Params;
44 struct FrameHostMsg_ReclaimCompositorResources_Params;
45 #if defined(OS_MACOSX)
46 struct FrameHostMsg_ShowPopup_Params;
47 #endif
48 
49 namespace blink {
50 class WebInputEvent;
51 }  // namespace blink
52 
53 namespace cc {
54 class CompositorFrame;
55 }  // namespace cc
56 
57 namespace gfx {
58 class Range;
59 }  // namespace gfx
60 
61 namespace content {
62 
63 class BrowserPluginGuestManager;
64 class RenderViewHostImpl;
65 class RenderWidgetHost;
66 class RenderWidgetHostView;
67 class SiteInstance;
68 struct DropData;
69 
70 // A browser plugin guest provides functionality for WebContents to operate in
71 // the guest role and implements guest-specific overrides for ViewHostMsg_*
72 // messages.
73 //
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 : public WebContentsObserver {
81  public:
82   virtual ~BrowserPluginGuest();
83 
84   // The WebContents passed into the factory method here has not been
85   // initialized yet and so it does not yet hold a SiteInstance.
86   // BrowserPluginGuest must be constructed and installed into a WebContents
87   // prior to its initialization because WebContents needs to determine what
88   // type of WebContentsView to construct on initialization. The content
89   // embedder needs to be aware of |guest_site_instance| on the guest's
90   // construction and so we pass it in here.
91   static BrowserPluginGuest* Create(WebContentsImpl* web_contents,
92                                     BrowserPluginGuestDelegate* delegate);
93 
94   // Returns whether the given WebContents is a BrowserPlugin guest.
95   static bool IsGuest(WebContentsImpl* web_contents);
96 
97   // Returns whether the given RenderviewHost is a BrowserPlugin guest.
98   static bool IsGuest(RenderViewHostImpl* render_view_host);
99 
100   // Returns a WeakPtr to this BrowserPluginGuest.
101   base::WeakPtr<BrowserPluginGuest> AsWeakPtr();
102 
103   // Sets the focus state of the current RenderWidgetHostView.
104   void SetFocus(RenderWidgetHost* rwh, bool focused);
105 
106   // Sets the lock state of the pointer. Returns true if |allowed| is true and
107   // the mouse has been successfully locked.
108   bool LockMouse(bool allowed);
109 
110   // Return true if the mouse is locked.
mouse_locked()111   bool mouse_locked() const { return mouse_locked_; }
112 
113   // Called when the embedder WebContents changes visibility.
114   void EmbedderVisibilityChanged(bool visible);
115 
116   // Destroys the guest WebContents and all its associated state, including
117   // this BrowserPluginGuest, and its new unattached windows.
118   void Destroy();
119 
120   // Creates a new guest WebContentsImpl with the provided |params| with |this|
121   // as the |opener|.
122   WebContentsImpl* CreateNewGuestWindow(
123       const WebContents::CreateParams& params);
124 
125   // Returns the identifier that uniquely identifies a browser plugin guest
126   // within an embedder.
browser_plugin_instance_id()127   int browser_plugin_instance_id() const { return browser_plugin_instance_id_; }
128 
129   bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
130 
embedder_web_contents()131   WebContentsImpl* embedder_web_contents() const {
132     return embedder_web_contents_;
133   }
134 
135   // Returns the embedder's RenderWidgetHostView if it is available.
136   // Returns NULL otherwise.
137   RenderWidgetHostView* GetEmbedderRenderWidgetHostView();
138 
focused()139   bool focused() const { return focused_; }
visible()140   bool visible() const { return guest_visible_; }
is_in_destruction()141   bool is_in_destruction() { return is_in_destruction_; }
142 
143   void UpdateVisibility();
144 
145   void CopyFromCompositingSurface(
146       gfx::Rect src_subrect,
147       gfx::Size dst_size,
148       const base::Callback<void(bool, const SkBitmap&)>& callback);
149 
150   BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
151 
152   // WebContentsObserver implementation.
153   virtual void DidCommitProvisionalLoadForFrame(
154       RenderFrameHost* render_frame_host,
155       const GURL& url,
156       ui::PageTransition transition_type) OVERRIDE;
157 
158   virtual void RenderViewReady() OVERRIDE;
159   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
160   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
161   virtual bool OnMessageReceived(const IPC::Message& message,
162                                  RenderFrameHost* render_frame_host) OVERRIDE;
163 
164   // Exposes the protected web_contents() from WebContentsObserver.
165   WebContentsImpl* GetWebContents() const;
166 
167   gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const;
168 
169   // Helper to send messages to embedder. This methods fills the message with
170   // the correct routing id.
171   void SendMessageToEmbedder(IPC::Message* msg);
172 
173   // Returns whether the guest is attached to an embedder.
attached()174   bool attached() const { return embedder_web_contents_ != NULL; }
175 
176   // Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
177   // and initializes the guest with the provided |params|. Attaching a guest
178   // to an embedder implies that this guest's lifetime is no longer managed
179   // by its opener, and it can begin loading resources.
180   void Attach(int browser_plugin_instance_id,
181               WebContentsImpl* embedder_web_contents,
182               const BrowserPluginHostMsg_Attach_Params& params);
183 
184   // Returns whether BrowserPluginGuest is interested in receiving the given
185   // |message|.
186   static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
187 
188   void DragSourceEndedAt(int client_x, int client_y, int screen_x,
189       int screen_y, blink::WebDragOperation operation);
190 
191   // Called when the drag started by this guest ends at an OS-level.
192   void EndSystemDrag();
193 
194   void RespondToPermissionRequest(int request_id,
195                                   bool should_allow,
196                                   const std::string& user_input);
197 
198   void PointerLockPermissionResponse(bool allow);
199 
200   void SwapCompositorFrame(uint32 output_surface_id,
201                            int host_process_id,
202                            int host_routing_id,
203                            scoped_ptr<cc::CompositorFrame> frame);
204 
205   void SetContentsOpaque(bool opaque);
206 
207  private:
208   class EmbedderWebContentsObserver;
209 
210   // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
211   // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
212   BrowserPluginGuest(bool has_render_view,
213                      WebContentsImpl* web_contents,
214                      BrowserPluginGuestDelegate* delegate);
215 
216   void WillDestroy();
217 
218   void Initialize(int browser_plugin_instance_id,
219                   const BrowserPluginHostMsg_Attach_Params& params,
220                   WebContentsImpl* embedder_web_contents);
221 
222   bool InAutoSizeBounds(const gfx::Size& size) const;
223 
224   // Message handlers for messages from embedder.
225 
226   void OnCompositorFrameSwappedACK(
227       int instance_id,
228       const FrameHostMsg_CompositorFrameSwappedACK_Params& params);
229   void OnCopyFromCompositingSurfaceAck(int instance_id,
230                                        int request_id,
231                                        const SkBitmap& bitmap);
232   // Handles drag events from the embedder.
233   // When dragging, the drag events go to the embedder first, and if the drag
234   // happens on the browser plugin, then the plugin sends a corresponding
235   // drag-message to the guest. This routes the drag-message to the guest
236   // renderer.
237   void OnDragStatusUpdate(int instance_id,
238                           blink::WebDragStatus drag_status,
239                           const DropData& drop_data,
240                           blink::WebDragOperationsMask drag_mask,
241                           const gfx::Point& location);
242   // Instructs the guest to execute an edit command decoded in the embedder.
243   void OnExecuteEditCommand(int instance_id,
244                             const std::string& command);
245 
246   // Returns compositor resources reclaimed in the embedder to the guest.
247   void OnReclaimCompositorResources(
248       int instance_id,
249       const FrameHostMsg_ReclaimCompositorResources_Params& params);
250 
251   void OnLockMouse(bool user_gesture,
252                    bool last_unlocked_by_target,
253                    bool privileged);
254   void OnLockMouseAck(int instance_id, bool succeeded);
255   void OnPluginDestroyed(int instance_id);
256   // Resizes the guest's web contents.
257   void OnResizeGuest(
258       int instance_id, const BrowserPluginHostMsg_ResizeGuest_Params& params);
259   void OnSetFocus(int instance_id, bool focused);
260   // Sets the name of the guest so that other guests in the same partition can
261   // access it.
262   void OnSetName(int instance_id, const std::string& name);
263   // Updates the size state of the guest.
264   void OnSetEditCommandsForNextKeyEvent(
265       int instance_id,
266       const std::vector<EditCommand>& edit_commands);
267   // The guest WebContents is visible if both its embedder is visible and
268   // the browser plugin element is visible. If either one is not then the
269   // WebContents is marked as hidden. A hidden WebContents will consume
270   // fewer GPU and CPU resources.
271   //
272   // When every WebContents in a RenderProcessHost is hidden, it will lower
273   // the priority of the process (see RenderProcessHostImpl::WidgetHidden).
274   //
275   // It will also send a message to the guest renderer process to cleanup
276   // resources such as dropping back buffers and adjusting memory limits (if in
277   // compositing mode, see CCLayerTreeHost::setVisible).
278   //
279   // Additionally, it will slow down Javascript execution and garbage
280   // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and
281   // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible).
282   void OnSetVisibility(int instance_id, bool visible);
283   void OnUnlockMouse();
284   void OnUnlockMouseAck(int instance_id);
285   void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect);
286 
287   void OnTextInputTypeChanged(ui::TextInputType type,
288                               ui::TextInputMode input_mode,
289                               bool can_compose_inline);
290   void OnImeSetComposition(
291       int instance_id,
292       const std::string& text,
293       const std::vector<blink::WebCompositionUnderline>& underlines,
294       int selection_start,
295       int selection_end);
296   void OnImeConfirmComposition(
297       int instance_id,
298       const std::string& text,
299       bool keep_selection);
300   void OnExtendSelectionAndDelete(int instance_id, int before, int after);
301   void OnImeCancelComposition();
302 #if defined(OS_MACOSX) || defined(USE_AURA)
303   void OnImeCompositionRangeChanged(
304       const gfx::Range& range,
305       const std::vector<gfx::Rect>& character_bounds);
306 #endif
307 
308   // Message handlers for messages from guest.
309   void OnHandleInputEventAck(
310       blink::WebInputEvent::Type event_type,
311       InputEventAckState ack_result);
312   void OnHasTouchEventHandlers(bool accept);
313 #if defined(OS_MACOSX)
314   // On MacOS X popups are painted by the browser process. We handle them here
315   // so that they are positioned correctly.
316   void OnShowPopup(RenderFrameHost* render_frame_host,
317                    const FrameHostMsg_ShowPopup_Params& params);
318 #endif
319   void OnShowWidget(int route_id, const gfx::Rect& initial_pos);
320   void OnTakeFocus(bool reverse);
321   void OnUpdateFrameName(int frame_id,
322                          bool is_top_level,
323                          const std::string& name);
324 
325   // Forwards all messages from the |pending_messages_| queue to the embedder.
326   void SendQueuedMessages();
327 
328   scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_;
329   WebContentsImpl* embedder_web_contents_;
330 
331   // An identifier that uniquely identifies a browser plugin within an embedder.
332   int browser_plugin_instance_id_;
333   float guest_device_scale_factor_;
334   gfx::Rect guest_window_rect_;
335   bool focused_;
336   bool mouse_locked_;
337   bool pending_lock_request_;
338   bool guest_visible_;
339   bool embedder_visible_;
340 
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_;
347 
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_;
354 
355   // Last seen size of guest contents (by SwapCompositorFrame).
356   gfx::Size last_seen_view_size_;
357   // Last seen size of BrowserPlugin (by OnResizeGuest).
358   gfx::Size last_seen_browser_plugin_size_;
359 
360   bool is_in_destruction_;
361 
362   // Text input type states.
363   ui::TextInputType last_text_input_type_;
364   ui::TextInputMode last_input_mode_;
365   bool last_can_compose_inline_;
366 
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_;
370 
371   BrowserPluginGuestDelegate* const delegate_;
372 
373   // Weak pointer used to ask GeolocationPermissionContext about geolocation
374   // permission.
375   base::WeakPtrFactory<BrowserPluginGuest> weak_ptr_factory_;
376 
377   DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest);
378 };
379 
380 }  // namespace content
381 
382 #endif  // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
383