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