• 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 #ifndef CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
6 #define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
7 
8 #include "base/callback.h"
9 #include "content/common/content_export.h"
10 #include "content/public/browser/native_web_keyboard_event.h"
11 #include "ipc/ipc_channel.h"
12 #include "ipc/ipc_sender.h"
13 #include "third_party/WebKit/public/web/WebInputEvent.h"
14 #include "third_party/WebKit/public/web/WebTextDirection.h"
15 #include "ui/gfx/size.h"
16 #include "ui/surface/transport_dib.h"
17 
18 #if defined(TOOLKIT_GTK)
19 #include "ui/base/x/x11_util.h"
20 #elif defined(OS_MACOSX)
21 #include "skia/ext/platform_device.h"
22 #endif
23 
24 class SkBitmap;
25 
26 namespace gfx {
27 class Rect;
28 }
29 
30 namespace blink {
31 class WebMouseEvent;
32 struct WebScreenInfo;
33 }
34 
35 namespace content {
36 
37 class RenderProcessHost;
38 class RenderWidgetHostImpl;
39 class RenderWidgetHostIterator;
40 class RenderWidgetHostView;
41 
42 // A RenderWidgetHost manages the browser side of a browser<->renderer
43 // HWND connection.  The HWND lives in the browser process, and
44 // windows events are sent over IPC to the corresponding object in the
45 // renderer.  The renderer paints into shared memory, which we
46 // transfer to a backing store and blit to the screen when Windows
47 // sends us a WM_PAINT message.
48 //
49 // How Shutdown Works
50 //
51 // There are two situations in which this object, a RenderWidgetHost, can be
52 // instantiated:
53 //
54 // 1. By a WebContents as the communication conduit for a rendered web page.
55 //    The WebContents instantiates a derived class: RenderViewHost.
56 // 2. By a WebContents as the communication conduit for a select widget. The
57 //    WebContents instantiates the RenderWidgetHost directly.
58 //
59 // For every WebContents there are several objects in play that need to be
60 // properly destroyed or cleaned up when certain events occur.
61 //
62 // - WebContents - the WebContents itself, and its associated HWND.
63 // - RenderViewHost - representing the communication conduit with the child
64 //   process.
65 // - RenderWidgetHostView - the view of the web page content, message handler,
66 //   and plugin root.
67 //
68 // Normally, the WebContents contains a child RenderWidgetHostView that renders
69 // the contents of the loaded page. It has a WS_CLIPCHILDREN style so that it
70 // does no painting of its own.
71 //
72 // The lifetime of the RenderWidgetHostView is tied to the render process. If
73 // the render process dies, the RenderWidgetHostView goes away and all
74 // references to it must become NULL.
75 //
76 // RenderViewHost (a RenderWidgetHost subclass) is the conduit used to
77 // communicate with the RenderView and is owned by the WebContents. If the
78 // render process crashes, the RenderViewHost remains and restarts the render
79 // process if needed to continue navigation.
80 //
81 // Some examples of how shutdown works:
82 //
83 // For a WebContents, its Destroy method tells the RenderViewHost to
84 // shut down the render process and die.
85 //
86 // When the render process is destroyed it destroys the View: the
87 // RenderWidgetHostView, which destroys its HWND and deletes that object.
88 //
89 // For select popups, the situation is a little different. The RenderWidgetHost
90 // associated with the select popup owns the view and itself (is responsible
91 // for destroying itself when the view is closed). The WebContents's only
92 // responsibility is to select popups is to create them when it is told to. When
93 // the View is destroyed via an IPC message (for when WebCore destroys the
94 // popup, e.g. if the user selects one of the options), or because
95 // WM_CANCELMODE is received by the view, the View schedules the destruction of
96 // the render process. However in this case since there's no WebContents
97 // container, when the render process is destroyed, the RenderWidgetHost just
98 // deletes itself, which is safe because no one else should have any references
99 // to it (the WebContents does not).
100 //
101 // It should be noted that the RenderViewHost, not the RenderWidgetHost,
102 // handles IPC messages relating to the render process going away, since the
103 // way a RenderViewHost (WebContents) handles the process dying is different to
104 // the way a select popup does. As such the RenderWidgetHostView handles these
105 // messages for select popups. This placement is more out of convenience than
106 // anything else. When the view is live, these messages are forwarded to it by
107 // the RenderWidgetHost's IPC message map.
108 class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
109  public:
110   // Free all backing stores used for rendering to drop memory usage.
111   static void RemoveAllBackingStores();
112 
113   // Returns the size of all the backing stores used for rendering
114   static size_t BackingStoreMemorySize();
115 
116   // Returns the RenderWidgetHost given its ID and the ID of its render process.
117   // Returns NULL if the IDs do not correspond to a live RenderWidgetHost.
118   static RenderWidgetHost* FromID(int32 process_id, int32 routing_id);
119 
120   // Returns an iterator to iterate over the global list of active render widget
121   // hosts.
122   static scoped_ptr<RenderWidgetHostIterator> GetRenderWidgetHosts();
123 
~RenderWidgetHost()124   virtual ~RenderWidgetHost() {}
125 
126   // Edit operations.
127   virtual void Undo() = 0;
128   virtual void Redo() = 0;
129   virtual void Cut() = 0;
130   virtual void Copy() = 0;
131   virtual void CopyToFindPboard() = 0;
132   virtual void Paste() = 0;
133   virtual void PasteAndMatchStyle() = 0;
134   virtual void Delete() = 0;
135   virtual void SelectAll() = 0;
136   virtual void Unselect() = 0;
137 
138   // Update the text direction of the focused input element and notify it to a
139   // renderer process.
140   // These functions have two usage scenarios: changing the text direction
141   // from a menu (as Safari does), and; changing the text direction when a user
142   // presses a set of keys (as IE and Firefox do).
143   // 1. Change the text direction from a menu.
144   // In this scenario, we receive a menu event only once and we should update
145   // the text direction immediately when a user chooses a menu item. So, we
146   // should call both functions at once as listed in the following snippet.
147   //   void RenderViewHost::SetTextDirection(WebTextDirection direction) {
148   //     UpdateTextDirection(direction);
149   //     NotifyTextDirection();
150   //   }
151   // 2. Change the text direction when pressing a set of keys.
152   // Because of auto-repeat, we may receive the same key-press event many
153   // times while we presses the keys and it is nonsense to send the same IPC
154   // message every time when we receive a key-press event.
155   // To suppress the number of IPC messages, we just update the text direction
156   // when receiving a key-press event and send an IPC message when we release
157   // the keys as listed in the following snippet.
158   //   if (key_event.type == WebKeyboardEvent::KEY_DOWN) {
159   //     if (key_event.windows_key_code == 'A' &&
160   //         key_event.modifiers == WebKeyboardEvent::CTRL_KEY) {
161   //       UpdateTextDirection(dir);
162   //     } else {
163   //       CancelUpdateTextDirection();
164   //     }
165   //   } else if (key_event.type == WebKeyboardEvent::KEY_UP) {
166   //     NotifyTextDirection();
167   //   }
168   // Once we cancel updating the text direction, we have to ignore all
169   // succeeding UpdateTextDirection() requests until calling
170   // NotifyTextDirection(). (We may receive keydown events even after we
171   // canceled updating the text direction because of auto-repeat.)
172   // Note: we cannot undo this change for compatibility with Firefox and IE.
173   virtual void UpdateTextDirection(blink::WebTextDirection direction) = 0;
174   virtual void NotifyTextDirection() = 0;
175 
176   virtual void Focus() = 0;
177   virtual void Blur() = 0;
178 
179   // Sets whether the renderer should show controls in an active state.  On all
180   // platforms except mac, that's the same as focused. On mac, the frontmost
181   // window will show active controls even if the focus is not in the web
182   // contents, but e.g. in the omnibox.
183   virtual void SetActive(bool active) = 0;
184 
185   // Copies the given subset of the backing store, and passes the result as a
186   // bitmap to a callback.
187   //
188   // If |src_rect| is empty, the whole contents is copied. If non empty
189   // |accelerated_dst_size| is given and accelerated compositing is active, the
190   // content is shrunk so that it fits in |accelerated_dst_size|. If
191   // |accelerated_dst_size| is larger than the content size, the content is not
192   // resized. If |accelerated_dst_size| is empty, the size copied from the
193   // source contents is used. |callback| is invoked with true on success, false
194   // otherwise, along with a SkBitmap containing the copied pixel data.
195   //
196   // NOTE: |callback| is called synchronously if the backing store is available.
197   // When accelerated compositing is active, |callback| may be called
198   // asynchronously.
199   virtual void CopyFromBackingStore(
200       const gfx::Rect& src_rect,
201       const gfx::Size& accelerated_dst_size,
202       const base::Callback<void(bool, const SkBitmap&)>& callback) = 0;
203 #if defined(TOOLKIT_GTK)
204   // Paint the backing store into the target's |dest_rect|.
205   virtual bool CopyFromBackingStoreToGtkWindow(const gfx::Rect& dest_rect,
206                                                GdkWindow* target) = 0;
207 #elif defined(OS_MACOSX)
208   virtual gfx::Size GetBackingStoreSize() = 0;
209   virtual bool CopyFromBackingStoreToCGContext(const CGRect& dest_rect,
210                                                CGContextRef target) = 0;
211 #endif
212 
213   // Send a command to the renderer to turn on full accessibility.
214   virtual void EnableFullAccessibilityMode() = 0;
215 
216   // Forwards the given message to the renderer. These are called by
217   // the view when it has received a message.
218   virtual void ForwardMouseEvent(
219       const blink::WebMouseEvent& mouse_event) = 0;
220   virtual void ForwardWheelEvent(
221       const blink::WebMouseWheelEvent& wheel_event) = 0;
222   virtual void ForwardKeyboardEvent(
223       const NativeWebKeyboardEvent& key_event) = 0;
224 
225   virtual const gfx::Vector2d& GetLastScrollOffset() const = 0;
226 
227   virtual RenderProcessHost* GetProcess() const = 0;
228 
229   virtual int GetRoutingID() const = 0;
230 
231   // Gets the View of this RenderWidgetHost. Can be NULL, e.g. if the
232   // RenderWidget is being destroyed or the render process crashed. You should
233   // never cache this pointer since it can become NULL if the renderer crashes,
234   // instead you should always ask for it using the accessor.
235   virtual RenderWidgetHostView* GetView() const = 0;
236 
237   // Returns true if the renderer is loading, false if not.
238   virtual bool IsLoading() const = 0;
239 
240   // Returns true if this is a RenderViewHost, false if not.
241   virtual bool IsRenderView() const = 0;
242 
243   // This tells the renderer to paint into a bitmap and return it,
244   // regardless of whether the tab is hidden or not.  It resizes the
245   // web widget to match the |page_size| and then returns the bitmap
246   // scaled so it matches the |desired_size|, so that the scaling
247   // happens on the rendering thread.  When the bitmap is ready, the
248   // renderer sends a PaintAtSizeACK to this host, and a
249   // RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK notification is issued.
250   // Note that this bypasses most of the update logic that is normally invoked,
251   // and doesn't put the results into the backing store.
252   virtual void PaintAtSize(TransportDIB::Handle dib_handle,
253                            int tag,
254                            const gfx::Size& page_size,
255                            const gfx::Size& desired_size) = 0;
256 
257   // Makes an IPC call to tell webkit to replace the currently selected word
258   // or a word around the cursor.
259   virtual void Replace(const base::string16& word) = 0;
260 
261   // Makes an IPC call to tell webkit to replace the misspelling in the current
262   // selection.
263   virtual void ReplaceMisspelling(const base::string16& word) = 0;
264 
265   // Called to notify the RenderWidget that the resize rect has changed without
266   // the size of the RenderWidget itself changing.
267   virtual void ResizeRectChanged(const gfx::Rect& new_rect) = 0;
268 
269   // Restart the active hang monitor timeout. Clears all existing timeouts and
270   // starts with a new one.  This can be because the renderer has become
271   // active, the tab is being hidden, or the user has chosen to wait some more
272   // to give the tab a chance to become active and we don't want to display a
273   // warning too soon.
274   virtual void RestartHangMonitorTimeout() = 0;
275 
276   virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0;
277 
278   // Stops loading the page.
279   virtual void Stop() = 0;
280 
281   // Called to notify the RenderWidget that it has been resized.
282   virtual void WasResized() = 0;
283 
284   // Access to the implementation's IPC::Listener::OnMessageReceived. Intended
285   // only for test code.
286 
287   // Add/remove a callback that can handle key presses without requiring focus.
288   typedef base::Callback<bool(const NativeWebKeyboardEvent&)>
289       KeyPressEventCallback;
290   virtual void AddKeyPressEventCallback(
291       const KeyPressEventCallback& callback) = 0;
292   virtual void RemoveKeyPressEventCallback(
293       const KeyPressEventCallback& callback) = 0;
294 
295   // Add/remove a callback that can handle all kinds of mouse events.
296   typedef base::Callback<bool(const blink::WebMouseEvent&)> MouseEventCallback;
297   virtual void AddMouseEventCallback(const MouseEventCallback& callback) = 0;
298   virtual void RemoveMouseEventCallback(const MouseEventCallback& callback) = 0;
299 
300   // Get the screen info corresponding to this render widget.
301   virtual void GetWebScreenInfo(blink::WebScreenInfo* result) = 0;
302 
303   // Grabs snapshot from renderer side and returns the bitmap to a callback.
304   // If |src_rect| is empty, the whole contents is copied. This is an expensive
305   // operation due to the IPC, but it can be used as a fallback method when
306   // CopyFromBackingStore fails due to the backing store not being available or,
307   // in composited mode, when the accelerated surface is not available to the
308   // browser side.
309   virtual void GetSnapshotFromRenderer(
310       const gfx::Rect& src_subrect,
311       const base::Callback<void(bool, const SkBitmap&)>& callback) = 0;
312 
313  protected:
314   friend class RenderWidgetHostImpl;
315 
316   // Retrieves the implementation class.  Intended only for code
317   // within content/.  This method is necessary because
318   // RenderWidgetHost is the root of a diamond inheritance pattern, so
319   // subclasses inherit it virtually, which removes our ability to
320   // static_cast to the subclass.
321   virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() = 0;
322 };
323 
324 }  // namespace content
325 
326 #endif  // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
327