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