Home | History | Annotate | Download | only in browser
      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 
     25 class SkBitmap;
     26 
     27 namespace gfx {
     28 class Rect;
     29 }
     30 
     31 namespace WebKit {
     32 struct WebScreenInfo;
     33 }
     34 
     35 namespace content {
     36 
     37 class RenderProcessHost;
     38 class RenderWidgetHostImpl;
     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   // 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 
    126   // Returns the global list of active render widget hosts.
    127   static RenderWidgetHost::List GetRenderWidgetHosts();
    128 
    129   virtual ~RenderWidgetHost() {}
    130 
    131   // Edit operations.
    132   virtual void Undo() = 0;
    133   virtual void Redo() = 0;
    134   virtual void Cut() = 0;
    135   virtual void Copy() = 0;
    136   virtual void CopyToFindPboard() = 0;
    137   virtual void Paste() = 0;
    138   virtual void PasteAndMatchStyle() = 0;
    139   virtual void Delete() = 0;
    140   virtual void SelectAll() = 0;
    141   virtual void Unselect() = 0;
    142 
    143   // Update the text direction of the focused input element and notify it to a
    144   // renderer process.
    145   // These functions have two usage scenarios: changing the text direction
    146   // from a menu (as Safari does), and; changing the text direction when a user
    147   // presses a set of keys (as IE and Firefox do).
    148   // 1. Change the text direction from a menu.
    149   // In this scenario, we receive a menu event only once and we should update
    150   // the text direction immediately when a user chooses a menu item. So, we
    151   // should call both functions at once as listed in the following snippet.
    152   //   void RenderViewHost::SetTextDirection(WebTextDirection direction) {
    153   //     UpdateTextDirection(direction);
    154   //     NotifyTextDirection();
    155   //   }
    156   // 2. Change the text direction when pressing a set of keys.
    157   // Because of auto-repeat, we may receive the same key-press event many
    158   // times while we presses the keys and it is nonsense to send the same IPC
    159   // message every time when we receive a key-press event.
    160   // To suppress the number of IPC messages, we just update the text direction
    161   // when receiving a key-press event and send an IPC message when we release
    162   // the keys as listed in the following snippet.
    163   //   if (key_event.type == WebKeyboardEvent::KEY_DOWN) {
    164   //     if (key_event.windows_key_code == 'A' &&
    165   //         key_event.modifiers == WebKeyboardEvent::CTRL_KEY) {
    166   //       UpdateTextDirection(dir);
    167   //     } else {
    168   //       CancelUpdateTextDirection();
    169   //     }
    170   //   } else if (key_event.type == WebKeyboardEvent::KEY_UP) {
    171   //     NotifyTextDirection();
    172   //   }
    173   // Once we cancel updating the text direction, we have to ignore all
    174   // succeeding UpdateTextDirection() requests until calling
    175   // NotifyTextDirection(). (We may receive keydown events even after we
    176   // canceled updating the text direction because of auto-repeat.)
    177   // Note: we cannot undo this change for compatibility with Firefox and IE.
    178   virtual void UpdateTextDirection(WebKit::WebTextDirection direction) = 0;
    179   virtual void NotifyTextDirection() = 0;
    180 
    181   virtual void Focus() = 0;
    182   virtual void Blur() = 0;
    183 
    184   // Sets whether the renderer should show controls in an active state.  On all
    185   // platforms except mac, that's the same as focused. On mac, the frontmost
    186   // window will show active controls even if the focus is not in the web
    187   // contents, but e.g. in the omnibox.
    188   virtual void SetActive(bool active) = 0;
    189 
    190   // Copies the given subset of the backing store, and passes the result as a
    191   // bitmap to a callback.
    192   //
    193   // If |src_rect| is empty, the whole contents is copied. If non empty
    194   // |accelerated_dst_size| is given and accelerated compositing is active, the
    195   // content is shrunk so that it fits in |accelerated_dst_size|. If
    196   // |accelerated_dst_size| is larger than the content size, the content is not
    197   // resized. If |accelerated_dst_size| is empty, the size copied from the
    198   // source contents is used. |callback| is invoked with true on success, false
    199   // otherwise, along with a SkBitmap containing the copied pixel data.
    200   //
    201   // NOTE: |callback| is called synchronously if the backing store is available.
    202   // When accelerated compositing is active, |callback| may be called
    203   // asynchronously.
    204   virtual void CopyFromBackingStore(
    205       const gfx::Rect& src_rect,
    206       const gfx::Size& accelerated_dst_size,
    207       const base::Callback<void(bool, const SkBitmap&)>& callback) = 0;
    208 #if defined(TOOLKIT_GTK)
    209   // Paint the backing store into the target's |dest_rect|.
    210   virtual bool CopyFromBackingStoreToGtkWindow(const gfx::Rect& dest_rect,
    211                                                GdkWindow* target) = 0;
    212 #elif defined(OS_MACOSX)
    213   virtual gfx::Size GetBackingStoreSize() = 0;
    214   virtual bool CopyFromBackingStoreToCGContext(const CGRect& dest_rect,
    215                                                CGContextRef target) = 0;
    216 #endif
    217 
    218   // Send a command to the renderer to turn on full accessibility.
    219   virtual void EnableFullAccessibilityMode() = 0;
    220 
    221   // Forwards the given message to the renderer. These are called by
    222   // the view when it has received a message.
    223   virtual void ForwardMouseEvent(
    224       const WebKit::WebMouseEvent& mouse_event) = 0;
    225   virtual void ForwardWheelEvent(
    226       const WebKit::WebMouseWheelEvent& wheel_event) = 0;
    227   virtual void ForwardKeyboardEvent(
    228       const NativeWebKeyboardEvent& key_event) = 0;
    229 
    230   virtual const gfx::Vector2d& GetLastScrollOffset() const = 0;
    231 
    232   virtual RenderProcessHost* GetProcess() const = 0;
    233 
    234   virtual int GetRoutingID() const = 0;
    235 
    236   // Gets the View of this RenderWidgetHost. Can be NULL, e.g. if the
    237   // RenderWidget is being destroyed or the render process crashed. You should
    238   // never cache this pointer since it can become NULL if the renderer crashes,
    239   // instead you should always ask for it using the accessor.
    240   virtual RenderWidgetHostView* GetView() const = 0;
    241 
    242   // Returns true if the renderer is loading, false if not.
    243   virtual bool IsLoading() const = 0;
    244 
    245   // Returns true if this is a RenderViewHost, false if not.
    246   virtual bool IsRenderView() const = 0;
    247 
    248   // This tells the renderer to paint into a bitmap and return it,
    249   // regardless of whether the tab is hidden or not.  It resizes the
    250   // web widget to match the |page_size| and then returns the bitmap
    251   // scaled so it matches the |desired_size|, so that the scaling
    252   // happens on the rendering thread.  When the bitmap is ready, the
    253   // renderer sends a PaintAtSizeACK to this host, and a
    254   // RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK notification is issued.
    255   // Note that this bypasses most of the update logic that is normally invoked,
    256   // and doesn't put the results into the backing store.
    257   virtual void PaintAtSize(TransportDIB::Handle dib_handle,
    258                            int tag,
    259                            const gfx::Size& page_size,
    260                            const gfx::Size& desired_size) = 0;
    261 
    262   // Makes an IPC call to tell webkit to replace the currently selected word
    263   // or a word around the cursor.
    264   virtual void Replace(const string16& word) = 0;
    265 
    266   // Makes an IPC call to tell webkit to replace the misspelling in the current
    267   // selection.
    268   virtual void ReplaceMisspelling(const string16& word) = 0;
    269 
    270   // Called to notify the RenderWidget that the resize rect has changed without
    271   // the size of the RenderWidget itself changing.
    272   virtual void ResizeRectChanged(const gfx::Rect& new_rect) = 0;
    273 
    274   // Restart the active hang monitor timeout. Clears all existing timeouts and
    275   // starts with a new one.  This can be because the renderer has become
    276   // active, the tab is being hidden, or the user has chosen to wait some more
    277   // to give the tab a chance to become active and we don't want to display a
    278   // warning too soon.
    279   virtual void RestartHangMonitorTimeout() = 0;
    280 
    281   virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0;
    282 
    283   // Stops loading the page.
    284   virtual void Stop() = 0;
    285 
    286   // Called to notify the RenderWidget that it has been resized.
    287   virtual void WasResized() = 0;
    288 
    289   // Access to the implementation's IPC::Listener::OnMessageReceived. Intended
    290   // only for test code.
    291 
    292   // Add a keyboard listener that can handle key presses without requiring
    293   // focus.
    294   virtual void AddKeyboardListener(KeyboardListener* listener) = 0;
    295 
    296   // Remove a keyboard listener.
    297   virtual void RemoveKeyboardListener(KeyboardListener* listener) = 0;
    298 
    299   // Get the screen info corresponding to this render widget.
    300   virtual void GetWebScreenInfo(WebKit::WebScreenInfo* result) = 0;
    301 
    302   // Grabs snapshot from renderer side and returns the bitmap to a callback.
    303   // If |src_rect| is empty, the whole contents is copied. This is an expensive
    304   // operation due to the IPC, but it can be used as a fallback method when
    305   // CopyFromBackingStore fails due to the backing store not being available or,
    306   // in composited mode, when the accelerated surface is not available to the
    307   // browser side.
    308   virtual void GetSnapshotFromRenderer(
    309       const gfx::Rect& src_subrect,
    310       const base::Callback<void(bool, const SkBitmap&)>& callback) = 0;
    311 
    312  protected:
    313   friend class RenderWidgetHostImpl;
    314 
    315   // Retrieves the implementation class.  Intended only for code
    316   // within content/.  This method is necessary because
    317   // RenderWidgetHost is the root of a diamond inheritance pattern, so
    318   // subclasses inherit it virtually, which removes our ability to
    319   // static_cast to the subclass.
    320   virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() = 0;
    321 };
    322 
    323 }  // namespace content
    324 
    325 #endif  // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
    326