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_PLUGIN_WEBPLUGIN_PROXY_H_
6#define CONTENT_PLUGIN_WEBPLUGIN_PROXY_H_
7
8#include <string>
9
10#include "base/containers/hash_tables.h"
11#include "base/memory/ref_counted.h"
12#if defined(OS_MACOSX)
13#include "base/mac/scoped_cftyperef.h"
14#endif
15#include "base/memory/scoped_handle.h"
16#include "base/memory/scoped_ptr.h"
17#include "base/memory/shared_memory.h"
18#include "base/memory/weak_ptr.h"
19#include "base/timer/timer.h"
20#include "content/child/npapi/webplugin.h"
21#include "ipc/ipc_message.h"
22#include "ipc/ipc_sender.h"
23#include "skia/ext/refptr.h"
24#include "third_party/skia/include/core/SkCanvas.h"
25#include "url/gurl.h"
26#if defined(USE_X11)
27#include "ui/base/x/x11_util.h"
28#endif
29#include "ui/gl/gpu_preference.h"
30#include "ui/surface/transport_dib.h"
31
32struct PluginMsg_FetchURL_Params;
33
34namespace content {
35class PluginChannel;
36class WebPluginDelegateImpl;
37
38#if defined(OS_MACOSX)
39class WebPluginAcceleratedSurfaceProxy;
40#endif
41
42// This is an implementation of WebPlugin that proxies all calls to the
43// renderer.
44class WebPluginProxy : public WebPlugin,
45                       public IPC::Sender {
46 public:
47  // Creates a new proxy for WebPlugin, using the given sender to send the
48  // marshalled WebPlugin calls.
49  WebPluginProxy(PluginChannel* channel,
50                 int route_id,
51                 const GURL& page_url,
52                 int host_render_view_routing_id);
53  virtual ~WebPluginProxy();
54
55  void set_delegate(WebPluginDelegateImpl* d) { delegate_ = d; }
56
57  // WebPlugin overrides
58  virtual void SetWindow(gfx::PluginWindowHandle window) OVERRIDE;
59  virtual void SetAcceptsInputEvents(bool accepts) OVERRIDE;
60  virtual void WillDestroyWindow(gfx::PluginWindowHandle window) OVERRIDE;
61  virtual void CancelResource(unsigned long id) OVERRIDE;
62  virtual void Invalidate() OVERRIDE;
63  virtual void InvalidateRect(const gfx::Rect& rect) OVERRIDE;
64  virtual NPObject* GetWindowScriptNPObject() OVERRIDE;
65  virtual NPObject* GetPluginElement() OVERRIDE;
66  virtual bool FindProxyForUrl(const GURL& url,
67                               std::string* proxy_list) OVERRIDE;
68  virtual void SetCookie(const GURL& url,
69                         const GURL& first_party_for_cookies,
70                         const std::string& cookie) OVERRIDE;
71  virtual std::string GetCookies(const GURL& url,
72                                 const GURL& first_party_for_cookies) OVERRIDE;
73  virtual void HandleURLRequest(const char* url,
74                                const char* method,
75                                const char* target,
76                                const char* buf,
77                                unsigned int len,
78                                int notify_id,
79                                bool popups_allowed,
80                                bool notify_redirects) OVERRIDE;
81  void UpdateGeometry(const gfx::Rect& window_rect,
82                      const gfx::Rect& clip_rect,
83                      const TransportDIB::Handle& windowless_buffer0,
84                      const TransportDIB::Handle& windowless_buffer1,
85                      int windowless_buffer_index);
86  virtual void CancelDocumentLoad() OVERRIDE;
87  virtual void InitiateHTTPRangeRequest(
88      const char* url, const char* range_info, int range_request_id) OVERRIDE;
89  virtual void DidStartLoading() OVERRIDE;
90  virtual void DidStopLoading() OVERRIDE;
91  virtual void SetDeferResourceLoading(unsigned long resource_id,
92                                       bool defer) OVERRIDE;
93  virtual bool IsOffTheRecord() OVERRIDE;
94  virtual void ResourceClientDeleted(
95      WebPluginResourceClient* resource_client) OVERRIDE;
96  virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE;
97  virtual bool CheckIfRunInsecureContent(const GURL& url) OVERRIDE;
98#if defined(OS_WIN)
99  void SetWindowlessData(HANDLE pump_messages_event,
100                         gfx::NativeViewId dummy_activation_window);
101#endif
102#if defined(OS_MACOSX)
103  virtual void FocusChanged(bool focused) OVERRIDE;
104  virtual void StartIme() OVERRIDE;
105  virtual WebPluginAcceleratedSurface*
106      GetAcceleratedSurface(gfx::GpuPreference gpu_preference) OVERRIDE;
107  virtual void AcceleratedPluginEnabledRendering() OVERRIDE;
108  virtual void AcceleratedPluginAllocatedIOSurface(int32 width,
109                                                   int32 height,
110                                                   uint32 surface_id) OVERRIDE;
111  virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE;
112#endif
113
114  // IPC::Sender implementation.
115  virtual bool Send(IPC::Message* msg) OVERRIDE;
116
117  // class-specific methods
118
119  // Returns a WebPluginResourceClient object given its id, or NULL if no
120  // object with that id exists.
121  WebPluginResourceClient* GetResourceClient(int id);
122
123  // Returns the id of the renderer that contains this plugin.
124  int GetRendererId();
125
126  // Returns the id of the associated render view.
127  int host_render_view_routing_id() const {
128    return host_render_view_routing_id_;
129  }
130
131  // For windowless plugins, paints the given rectangle into the local buffer.
132  void Paint(const gfx::Rect& rect);
133
134  // Callback from the renderer to let us know that a paint occurred.
135  void DidPaint();
136
137  // Notification received on a plugin issued resource request creation.
138  void OnResourceCreated(int resource_id, WebPluginResourceClient* client);
139
140#if defined(OS_WIN) && !defined(USE_AURA)
141  // Retrieves the IME status from a windowless plug-in and sends it to a
142  // renderer process. A renderer process will convert the coordinates from
143  // local to the window coordinates and send the converted coordinates to a
144  // browser process.
145  void UpdateIMEStatus();
146#endif
147
148 private:
149  class SharedTransportDIB : public base::RefCounted<SharedTransportDIB> {
150   public:
151    explicit SharedTransportDIB(TransportDIB* dib);
152    TransportDIB* dib() { return dib_.get(); }
153   private:
154    friend class base::RefCounted<SharedTransportDIB>;
155    ~SharedTransportDIB();
156
157    scoped_ptr<TransportDIB> dib_;
158  };
159
160  // Handler for sending over the paint event to the plugin.
161  void OnPaint(const gfx::Rect& damaged_rect);
162
163#if defined(OS_WIN)
164  void CreateCanvasFromHandle(const TransportDIB::Handle& dib_handle,
165                              const gfx::Rect& window_rect,
166                              skia::RefPtr<SkCanvas>* canvas);
167#elif defined(OS_MACOSX)
168  static void CreateDIBAndCGContextFromHandle(
169      const TransportDIB::Handle& dib_handle,
170      const gfx::Rect& window_rect,
171      scoped_ptr<TransportDIB>* dib_out,
172      base::ScopedCFTypeRef<CGContextRef>* cg_context_out);
173#elif defined(USE_X11)
174  static void CreateDIBAndCanvasFromHandle(
175      const TransportDIB::Handle& dib_handle,
176      const gfx::Rect& window_rect,
177      scoped_refptr<SharedTransportDIB>* dib_out,
178      skia::RefPtr<SkCanvas>* canvas);
179
180  static void CreateShmPixmapFromDIB(
181      TransportDIB* dib,
182      const gfx::Rect& window_rect,
183      XID* pixmap_out);
184#endif
185
186  // Updates the shared memory sections where windowless plugins paint.
187  void SetWindowlessBuffers(const TransportDIB::Handle& windowless_buffer0,
188                            const TransportDIB::Handle& windowless_buffer1,
189                            const gfx::Rect& window_rect);
190
191#if defined(OS_MACOSX)
192  CGContextRef windowless_context() const {
193    return windowless_contexts_[windowless_buffer_index_].get();
194  }
195#else
196  skia::RefPtr<SkCanvas> windowless_canvas() const {
197    return windowless_canvases_[windowless_buffer_index_];
198  }
199
200#if defined(USE_X11)
201  XID windowless_shm_pixmap() const {
202    return windowless_shm_pixmaps_[windowless_buffer_index_];
203  }
204#endif
205
206#endif
207
208  typedef base::hash_map<int, WebPluginResourceClient*> ResourceClientMap;
209  ResourceClientMap resource_clients_;
210
211  scoped_refptr<PluginChannel> channel_;
212  int route_id_;
213  NPObject* window_npobject_;
214  NPObject* plugin_element_;
215  WebPluginDelegateImpl* delegate_;
216  gfx::Rect damaged_rect_;
217  bool waiting_for_paint_;
218  // The url of the main frame hosting the plugin.
219  GURL page_url_;
220
221  // Variables used for desynchronized windowless plugin painting. See note in
222  // webplugin_delegate_proxy.h for how this works. The two sets of windowless_*
223  // fields are for the front-buffer and back-buffer of a buffer flipping system
224  // and windowless_buffer_index_ identifies which set we are using as the
225  // back-buffer at any given time.
226  int windowless_buffer_index_;
227#if defined(OS_MACOSX)
228  scoped_ptr<TransportDIB> windowless_dibs_[2];
229  base::ScopedCFTypeRef<CGContextRef> windowless_contexts_[2];
230  scoped_ptr<WebPluginAcceleratedSurfaceProxy> accelerated_surface_;
231#else
232  skia::RefPtr<SkCanvas> windowless_canvases_[2];
233
234#if defined(USE_X11)
235  scoped_refptr<SharedTransportDIB> windowless_dibs_[2];
236  // If we can use SHM pixmaps for windowless plugin painting or not.
237  bool use_shm_pixmap_;
238  // The SHM pixmaps for windowless plugin painting.
239  XID windowless_shm_pixmaps_[2];
240#endif
241
242#endif
243
244  // Contains the routing id of the host render view.
245  int host_render_view_routing_id_;
246
247  base::WeakPtrFactory<WebPluginProxy> weak_factory_;
248};
249
250}  // namespace content
251
252#endif  // CONTENT_PLUGIN_WEBPLUGIN_PROXY_H_
253