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