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