webplugin_delegate_proxy.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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_RENDERER_NPAPI_WEBPLUGIN_DELEGATE_PROXY_H_
6#define CONTENT_RENDERER_NPAPI_WEBPLUGIN_DELEGATE_PROXY_H_
7
8#include <string>
9#include <vector>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "base/sequenced_task_runner_helpers.h"
15#include "content/child/npapi/webplugin_delegate.h"
16#include "content/public/common/webplugininfo.h"
17#include "ipc/ipc_listener.h"
18#include "ipc/ipc_message.h"
19#include "ipc/ipc_sender.h"
20#include "ui/gfx/native_widget_types.h"
21#include "ui/gfx/rect.h"
22#include "ui/surface/transport_dib.h"
23#include "url/gurl.h"
24
25#if defined(OS_MACOSX)
26#include "base/containers/hash_tables.h"
27#include "base/memory/linked_ptr.h"
28#endif
29
30struct NPObject;
31struct PluginHostMsg_URLRequest_Params;
32class SkBitmap;
33
34namespace base {
35class WaitableEvent;
36}
37
38namespace content {
39class NPObjectStub;
40class PluginChannelHost;
41class RenderFrameImpl;
42class RenderViewImpl;
43class WebPluginImpl;
44
45// An implementation of WebPluginDelegate that proxies all calls to
46// the plugin process.
47class WebPluginDelegateProxy
48    : public WebPluginDelegate,
49      public IPC::Listener,
50      public IPC::Sender,
51      public base::SupportsWeakPtr<WebPluginDelegateProxy> {
52 public:
53  WebPluginDelegateProxy(WebPluginImpl* plugin,
54                         const std::string& mime_type,
55                         const base::WeakPtr<RenderViewImpl>& render_view,
56                         RenderFrameImpl* render_frame);
57
58  // WebPluginDelegate implementation:
59  virtual void PluginDestroyed() OVERRIDE;
60  virtual bool Initialize(const GURL& url,
61                          const std::vector<std::string>& arg_names,
62                          const std::vector<std::string>& arg_values,
63                          bool load_manually) OVERRIDE;
64  virtual void UpdateGeometry(const gfx::Rect& window_rect,
65                              const gfx::Rect& clip_rect) OVERRIDE;
66  virtual void Paint(SkCanvas* canvas, const gfx::Rect& rect) OVERRIDE;
67  virtual NPObject* GetPluginScriptableObject() OVERRIDE;
68  virtual struct _NPP* GetPluginNPP() OVERRIDE;
69  virtual bool GetFormValue(base::string16* value) OVERRIDE;
70  virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason,
71                                       int notify_id) OVERRIDE;
72  virtual void SetFocus(bool focused) OVERRIDE;
73  virtual bool HandleInputEvent(const blink::WebInputEvent& event,
74                                WebCursor::CursorInfo* cursor) OVERRIDE;
75  virtual int GetProcessId() OVERRIDE;
76
77  // Informs the plugin that its containing content view has gained or lost
78  // first responder status.
79  virtual void SetContentAreaFocus(bool has_focus);
80#if defined(OS_WIN)
81  // Informs the plugin that plugin IME has updated its status.
82  virtual void ImeCompositionUpdated(
83      const base::string16& text,
84      const std::vector<int>& clauses,
85      const std::vector<int>& target,
86      int cursor_position,
87      int plugin_id);
88  // Informs the plugin that plugin IME has completed.
89  // If |text| is empty, composition was cancelled.
90  virtual void ImeCompositionCompleted(const base::string16& text,
91                                       int plugin_id);
92#endif
93#if defined(OS_MACOSX)
94  // Informs the plugin that its enclosing window has gained or lost focus.
95  virtual void SetWindowFocus(bool window_has_focus);
96  // Informs the plugin that its container (window/tab) has changed visibility.
97  virtual void SetContainerVisibility(bool is_visible);
98  // Informs the plugin that its enclosing window's frame has changed.
99  virtual void WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
100  // Informs the plugin that plugin IME has completed.
101  // If |text| is empty, composition was cancelled.
102  virtual void ImeCompositionCompleted(const base::string16& text,
103                                       int plugin_id);
104#endif
105
106  // IPC::Listener implementation:
107  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
108  virtual void OnChannelError() OVERRIDE;
109
110  // IPC::Sender implementation:
111  virtual bool Send(IPC::Message* msg) OVERRIDE;
112
113  virtual void SendJavaScriptStream(const GURL& url,
114                                    const std::string& result,
115                                    bool success,
116                                    int notify_id) OVERRIDE;
117
118  virtual void DidReceiveManualResponse(const GURL& url,
119                                        const std::string& mime_type,
120                                        const std::string& headers,
121                                        uint32 expected_length,
122                                        uint32 last_modified) OVERRIDE;
123  virtual void DidReceiveManualData(const char* buffer, int length) OVERRIDE;
124  virtual void DidFinishManualLoading() OVERRIDE;
125  virtual void DidManualLoadFail() OVERRIDE;
126  virtual WebPluginResourceClient* CreateResourceClient(
127      unsigned long resource_id, const GURL& url, int notify_id) OVERRIDE;
128  virtual WebPluginResourceClient* CreateSeekableResourceClient(
129      unsigned long resource_id, int range_request_id) OVERRIDE;
130  virtual void FetchURL(unsigned long resource_id,
131                        int notify_id,
132                        const GURL& url,
133                        const GURL& first_party_for_cookies,
134                        const std::string& method,
135                        const char* buf,
136                        unsigned int len,
137                        const GURL& referrer,
138                        bool notify_redirects,
139                        bool is_plugin_src_load,
140                        int origin_pid,
141                        int render_frame_id,
142                        int render_view_id) OVERRIDE;
143
144  gfx::PluginWindowHandle GetPluginWindowHandle();
145
146 protected:
147  friend class base::DeleteHelper<WebPluginDelegateProxy>;
148  virtual ~WebPluginDelegateProxy();
149
150 private:
151  struct SharedBitmap {
152    SharedBitmap();
153    ~SharedBitmap();
154
155    scoped_ptr<TransportDIB> dib;
156    scoped_ptr<SkCanvas> canvas;
157  };
158
159  // Message handlers for messages that proxy WebPlugin methods, which
160  // we translate into calls to the real WebPlugin.
161  void OnSetWindow(gfx::PluginWindowHandle window);
162  void OnCompleteURL(const std::string& url_in, std::string* url_out,
163                     bool* result);
164  void OnHandleURLRequest(const PluginHostMsg_URLRequest_Params& params);
165  void OnCancelResource(int id);
166  void OnInvalidateRect(const gfx::Rect& rect);
167  void OnGetWindowScriptNPObject(int route_id, bool* success);
168  void OnResolveProxy(const GURL& url, bool* result, std::string* proxy_list);
169  void OnGetPluginElement(int route_id, bool* success);
170  void OnSetCookie(const GURL& url,
171                   const GURL& first_party_for_cookies,
172                   const std::string& cookie);
173  void OnGetCookies(const GURL& url, const GURL& first_party_for_cookies,
174                    std::string* cookies);
175  void OnCancelDocumentLoad();
176  void OnInitiateHTTPRangeRequest(const std::string& url,
177                                  const std::string& range_info,
178                                  int range_request_id);
179  void OnDidStartLoading();
180  void OnDidStopLoading();
181  void OnDeferResourceLoading(unsigned long resource_id, bool defer);
182  void OnURLRedirectResponse(bool allow, int resource_id);
183  void OnCheckIfRunInsecureContent(const GURL& url, bool* result);
184#if defined(OS_MACOSX)
185  void OnFocusChanged(bool focused);
186  void OnStartIme();
187  // Accelerated (Core Animation) plugin implementation.
188  void OnAcceleratedPluginEnabledRendering();
189  void OnAcceleratedPluginAllocatedIOSurface(int32 width,
190                                             int32 height,
191                                             uint32 surface_id);
192  void OnAcceleratedPluginSwappedIOSurface();
193#endif
194#if defined(OS_WIN)
195  void OnSetWindowlessData(HANDLE modal_loop_pump_messages_event,
196                           gfx::NativeViewId dummy_activation_window);
197  void OnNotifyIMEStatus(const int input_mode, const gfx::Rect& caret_rect);
198#endif
199  // Helper function that sends the UpdateGeometry message.
200  void SendUpdateGeometry(bool bitmaps_changed);
201
202  // Copies the given rectangle from the back-buffer transport_stores_ bitmap to
203  // the front-buffer transport_stores_ bitmap.
204  void CopyFromBackBufferToFrontBuffer(const gfx::Rect& rect);
205
206  // Updates the front-buffer with the given rectangle from the back-buffer,
207  // either by copying the rectangle or flipping the buffers.
208  void UpdateFrontBuffer(const gfx::Rect& rect, bool allow_buffer_flipping);
209
210  // Clears the shared memory section and canvases used for windowless plugins.
211  void ResetWindowlessBitmaps();
212
213  int front_buffer_index() const {
214    return front_buffer_index_;
215  }
216
217  int back_buffer_index() const {
218    return 1 - front_buffer_index_;
219  }
220
221  SkCanvas* front_buffer_canvas() const {
222    return transport_stores_[front_buffer_index()].canvas.get();
223  }
224
225  SkCanvas* back_buffer_canvas() const {
226    return transport_stores_[back_buffer_index()].canvas.get();
227  }
228
229  TransportDIB* front_buffer_dib() const {
230    return transport_stores_[front_buffer_index()].dib.get();
231  }
232
233  TransportDIB* back_buffer_dib() const {
234    return transport_stores_[back_buffer_index()].dib.get();
235  }
236
237#if !defined(OS_WIN)
238  // Creates a process-local memory section and canvas. PlatformCanvas on
239  // Windows only works with a DIB, not arbitrary memory.
240  bool CreateLocalBitmap(std::vector<uint8>* memory,
241                         scoped_ptr<SkCanvas>* canvas);
242#endif
243
244  // Creates a shared memory section and canvas.
245  bool CreateSharedBitmap(scoped_ptr<TransportDIB>* memory,
246                          scoped_ptr<SkCanvas>* canvas);
247
248  // Called for cleanup during plugin destruction. Normally right before the
249  // plugin window gets destroyed, or when the plugin has crashed (at which
250  // point the window has already been destroyed).
251  void WillDestroyWindow();
252
253#if defined(OS_WIN)
254  // Returns true if we should update the plugin geometry synchronously.
255  bool UseSynchronousGeometryUpdates();
256#endif
257
258  base::WeakPtr<RenderViewImpl> render_view_;
259  RenderFrameImpl* render_frame_;
260  WebPluginImpl* plugin_;
261  bool uses_shared_bitmaps_;
262#if defined(OS_MACOSX)
263  bool uses_compositor_;
264#elif defined(OS_WIN)
265  // Used for windowless plugins so that keyboard activation works.
266  gfx::NativeViewId dummy_activation_window_;
267#endif
268  gfx::PluginWindowHandle window_;
269  scoped_refptr<PluginChannelHost> channel_host_;
270  std::string mime_type_;
271  int instance_id_;
272  WebPluginInfo info_;
273
274  gfx::Rect plugin_rect_;
275  gfx::Rect clip_rect_;
276
277  NPObject* npobject_;
278
279  // Dummy NPP used to uniquely identify this plugin.
280  scoped_ptr<NPP_t> npp_;
281
282  // Event passed in by the plugin process and is used to decide if messages
283  // need to be pumped in the NPP_HandleEvent sync call.
284  scoped_ptr<base::WaitableEvent> modal_loop_pump_messages_event_;
285
286  // Bitmap for crashed plugin
287  SkBitmap* sad_plugin_;
288
289  // True if we got an invalidate from the plugin and are waiting for a paint.
290  bool invalidate_pending_;
291
292  // If the plugin is transparent or not.
293  bool transparent_;
294
295  // The index in the transport_stores_ array of the current front buffer
296  // (i.e., the buffer to display).
297  int front_buffer_index_;
298  SharedBitmap transport_stores_[2];
299  // This lets us know the total portion of the transport store that has been
300  // painted since the buffers were created.
301  gfx::Rect transport_store_painted_;
302  // This is a bounding box on the portion of the front-buffer that was painted
303  // on the last buffer flip and which has not yet been re-painted in the
304  // back-buffer.
305  gfx::Rect front_buffer_diff_;
306
307  // The url of the main frame hosting the plugin.
308  GURL page_url_;
309
310  DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateProxy);
311};
312
313}  // namespace content
314
315#endif  // CONTENT_RENDERER_NPAPI_WEBPLUGIN_DELEGATE_PROXY_H_
316