• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
30 struct NPObject;
31 struct PluginHostMsg_URLRequest_Params;
32 class SkBitmap;
33 
34 namespace base {
35 class WaitableEvent;
36 }
37 
38 namespace content {
39 class NPObjectStub;
40 class PluginChannelHost;
41 class RenderFrameImpl;
42 class RenderViewImpl;
43 class WebPluginImpl;
44 
45 // An implementation of WebPluginDelegate that proxies all calls to
46 // the plugin process.
47 class 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 
front_buffer_index()213   int front_buffer_index() const {
214     return front_buffer_index_;
215   }
216 
back_buffer_index()217   int back_buffer_index() const {
218     return 1 - front_buffer_index_;
219   }
220 
front_buffer_canvas()221   SkCanvas* front_buffer_canvas() const {
222     return transport_stores_[front_buffer_index()].canvas.get();
223   }
224 
back_buffer_canvas()225   SkCanvas* back_buffer_canvas() const {
226     return transport_stores_[back_buffer_index()].canvas.get();
227   }
228 
front_buffer_dib()229   TransportDIB* front_buffer_dib() const {
230     return transport_stores_[front_buffer_index()].dib.get();
231   }
232 
back_buffer_dib()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