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 "third_party/skia/include/core/SkBitmap.h" 16 #include "ui/gfx/size.h" 17 #include "ui/surface/transport_dib.h" 18 19 #if defined(OS_MACOSX) 20 #include "skia/ext/platform_device.h" 21 #endif 22 23 class SkBitmap; 24 25 namespace gfx { 26 class Rect; 27 } 28 29 namespace blink { 30 class WebMouseEvent; 31 struct WebScreenInfo; 32 } 33 34 namespace content { 35 36 class RenderProcessHost; 37 class RenderWidgetHostImpl; 38 class RenderWidgetHostIterator; 39 class 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. 107 class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender { 108 public: 109 // Returns the RenderWidgetHost given its ID and the ID of its render process. 110 // Returns NULL if the IDs do not correspond to a live RenderWidgetHost. 111 static RenderWidgetHost* FromID(int32 process_id, int32 routing_id); 112 113 // Returns an iterator to iterate over the global list of active render widget 114 // hosts. 115 static scoped_ptr<RenderWidgetHostIterator> GetRenderWidgetHosts(); 116 ~RenderWidgetHost()117 virtual ~RenderWidgetHost() {} 118 119 // Update the text direction of the focused input element and notify it to a 120 // renderer process. 121 // These functions have two usage scenarios: changing the text direction 122 // from a menu (as Safari does), and; changing the text direction when a user 123 // presses a set of keys (as IE and Firefox do). 124 // 1. Change the text direction from a menu. 125 // In this scenario, we receive a menu event only once and we should update 126 // the text direction immediately when a user chooses a menu item. So, we 127 // should call both functions at once as listed in the following snippet. 128 // void RenderViewHost::SetTextDirection(WebTextDirection direction) { 129 // UpdateTextDirection(direction); 130 // NotifyTextDirection(); 131 // } 132 // 2. Change the text direction when pressing a set of keys. 133 // Because of auto-repeat, we may receive the same key-press event many 134 // times while we presses the keys and it is nonsense to send the same IPC 135 // message every time when we receive a key-press event. 136 // To suppress the number of IPC messages, we just update the text direction 137 // when receiving a key-press event and send an IPC message when we release 138 // the keys as listed in the following snippet. 139 // if (key_event.type == WebKeyboardEvent::KEY_DOWN) { 140 // if (key_event.windows_key_code == 'A' && 141 // key_event.modifiers == WebKeyboardEvent::CTRL_KEY) { 142 // UpdateTextDirection(dir); 143 // } else { 144 // CancelUpdateTextDirection(); 145 // } 146 // } else if (key_event.type == WebKeyboardEvent::KEY_UP) { 147 // NotifyTextDirection(); 148 // } 149 // Once we cancel updating the text direction, we have to ignore all 150 // succeeding UpdateTextDirection() requests until calling 151 // NotifyTextDirection(). (We may receive keydown events even after we 152 // canceled updating the text direction because of auto-repeat.) 153 // Note: we cannot undo this change for compatibility with Firefox and IE. 154 virtual void UpdateTextDirection(blink::WebTextDirection direction) = 0; 155 virtual void NotifyTextDirection() = 0; 156 157 virtual void Focus() = 0; 158 virtual void Blur() = 0; 159 160 // Sets whether the renderer should show controls in an active state. On all 161 // platforms except mac, that's the same as focused. On mac, the frontmost 162 // window will show active controls even if the focus is not in the web 163 // contents, but e.g. in the omnibox. 164 virtual void SetActive(bool active) = 0; 165 166 // Copies the given subset of the backing store, and passes the result as a 167 // bitmap to a callback. 168 // 169 // If |src_rect| is empty, the whole contents is copied. If non empty 170 // |accelerated_dst_size| is given and accelerated compositing is active, the 171 // content is shrunk so that it fits in |accelerated_dst_size|. If 172 // |accelerated_dst_size| is larger than the content size, the content is not 173 // resized. If |accelerated_dst_size| is empty, the size copied from the 174 // source contents is used. |callback| is invoked with true on success, false 175 // otherwise, along with a SkBitmap containing the copied pixel data. 176 // 177 // NOTE: |callback| is called synchronously if the backing store is available. 178 // When accelerated compositing is active, |callback| may be called 179 // asynchronously. 180 virtual void CopyFromBackingStore( 181 const gfx::Rect& src_rect, 182 const gfx::Size& accelerated_dst_size, 183 const base::Callback<void(bool, const SkBitmap&)>& callback, 184 const SkColorType color_type) = 0; 185 // Ensures that the view does not drop the backing store even when hidden. 186 virtual bool CanCopyFromBackingStore() = 0; 187 #if defined(OS_ANDROID) 188 virtual void LockBackingStore() = 0; 189 virtual void UnlockBackingStore() = 0; 190 #endif 191 192 // Forwards the given message to the renderer. These are called by 193 // the view when it has received a message. 194 virtual void ForwardMouseEvent( 195 const blink::WebMouseEvent& mouse_event) = 0; 196 virtual void ForwardWheelEvent( 197 const blink::WebMouseWheelEvent& wheel_event) = 0; 198 virtual void ForwardKeyboardEvent( 199 const NativeWebKeyboardEvent& key_event) = 0; 200 201 virtual RenderProcessHost* GetProcess() const = 0; 202 203 virtual int GetRoutingID() const = 0; 204 205 // Gets the View of this RenderWidgetHost. Can be NULL, e.g. if the 206 // RenderWidget is being destroyed or the render process crashed. You should 207 // never cache this pointer since it can become NULL if the renderer crashes, 208 // instead you should always ask for it using the accessor. 209 virtual RenderWidgetHostView* GetView() const = 0; 210 211 // Returns true if the renderer is loading, false if not. 212 virtual bool IsLoading() const = 0; 213 214 // Returns true if this is a RenderViewHost, false if not. 215 virtual bool IsRenderView() const = 0; 216 217 // Called to notify the RenderWidget that the resize rect has changed without 218 // the size of the RenderWidget itself changing. 219 virtual void ResizeRectChanged(const gfx::Rect& new_rect) = 0; 220 221 // Restart the active hang monitor timeout. Clears all existing timeouts and 222 // starts with a new one. This can be because the renderer has become 223 // active, the tab is being hidden, or the user has chosen to wait some more 224 // to give the tab a chance to become active and we don't want to display a 225 // warning too soon. 226 virtual void RestartHangMonitorTimeout() = 0; 227 228 virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0; 229 230 // Called to notify the RenderWidget that it has been resized. 231 virtual void WasResized() = 0; 232 233 // Access to the implementation's IPC::Listener::OnMessageReceived. Intended 234 // only for test code. 235 236 // Add/remove a callback that can handle key presses without requiring focus. 237 typedef base::Callback<bool(const NativeWebKeyboardEvent&)> 238 KeyPressEventCallback; 239 virtual void AddKeyPressEventCallback( 240 const KeyPressEventCallback& callback) = 0; 241 virtual void RemoveKeyPressEventCallback( 242 const KeyPressEventCallback& callback) = 0; 243 244 // Add/remove a callback that can handle all kinds of mouse events. 245 typedef base::Callback<bool(const blink::WebMouseEvent&)> MouseEventCallback; 246 virtual void AddMouseEventCallback(const MouseEventCallback& callback) = 0; 247 virtual void RemoveMouseEventCallback(const MouseEventCallback& callback) = 0; 248 249 // Get the screen info corresponding to this render widget. 250 virtual void GetWebScreenInfo(blink::WebScreenInfo* result) = 0; 251 252 virtual SkColorType PreferredReadbackFormat() = 0; 253 254 protected: 255 friend class RenderWidgetHostImpl; 256 257 // Retrieves the implementation class. Intended only for code 258 // within content/. This method is necessary because 259 // RenderWidgetHost is the root of a diamond inheritance pattern, so 260 // subclasses inherit it virtually, which removes our ability to 261 // static_cast to the subclass. 262 virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() = 0; 263 }; 264 265 } // namespace content 266 267 #endif // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_ 268