Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: webkit/plugins/npapi/webplugin_delegate_impl.h

Issue 19761007: Move NPAPI implementation out of webkit/plugins/npapi and into content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix mac Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 WEBKIT_PLUGINS_NPAPI_WEBPLUGIN_DELEGATE_IMPL_H_
6 #define WEBKIT_PLUGINS_NPAPI_WEBPLUGIN_DELEGATE_IMPL_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 "base/timer/timer.h"
16 #include "build/build_config.h"
17 #include "third_party/npapi/bindings/npapi.h"
18 #include "ui/gfx/native_widget_types.h"
19 #include "ui/gfx/rect.h"
20 #include "webkit/common/cursors/webcursor.h"
21 #include "webkit/plugins/npapi/webplugin_delegate.h"
22 #include "webkit/plugins/webkit_plugins_export.h"
23
24 #if defined(USE_X11)
25 #include "ui/base/x/x11_util.h"
26
27 typedef struct _GdkDrawable GdkPixmap;
28 #endif
29
30 namespace base {
31 class FilePath;
32 }
33
34 #if defined(OS_MACOSX)
35 #ifdef __OBJC__
36 @class CALayer;
37 @class CARenderer;
38 #else
39 class CALayer;
40 class CARenderer;
41 #endif
42 #endif
43
44 namespace webkit {
45 namespace npapi {
46
47 class PluginInstance;
48
49 #if defined(OS_MACOSX)
50 class WebPluginAcceleratedSurface;
51 class ExternalDragTracker;
52 #endif // OS_MACOSX
53
54 #if defined(OS_WIN)
55 class WebPluginIMEWin;
56 #endif // OS_WIN
57
58 // An implementation of WebPluginDelegate that runs in the plugin process,
59 // proxied from the renderer by WebPluginDelegateProxy.
60 class WEBKIT_PLUGINS_EXPORT WebPluginDelegateImpl : public WebPluginDelegate {
61 public:
62 enum PluginQuirks {
63 PLUGIN_QUIRK_SETWINDOW_TWICE = 1, // Win32
64 PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE = 2, // Win32
65 PLUGIN_QUIRK_DONT_CALL_WND_PROC_RECURSIVELY = 4, // Win32
66 PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY = 8, // Win32
67 PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES = 16, // Win32
68 PLUGIN_QUIRK_DIE_AFTER_UNLOAD = 32, // Win32
69 PLUGIN_QUIRK_PATCH_SETCURSOR = 64, // Win32
70 PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS = 128, // Win32
71 PLUGIN_QUIRK_WINDOWLESS_OFFSET_WINDOW_TO_DRAW = 256, // Linux
72 PLUGIN_QUIRK_WINDOWLESS_INVALIDATE_AFTER_SET_WINDOW = 512, // Linux
73 PLUGIN_QUIRK_NO_WINDOWLESS = 1024, // Windows
74 PLUGIN_QUIRK_PATCH_REGENUMKEYEXW = 2048, // Windows
75 PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS = 4096, // Windows
76 PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE = 16384, // Windows
77 PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK = 32768, // Linux
78 PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL = 65536, // Windows.
79 PLUGIN_QUIRK_EMULATE_IME = 131072, // Windows.
80 };
81
82 static WebPluginDelegateImpl* Create(const base::FilePath& filename,
83 const std::string& mime_type);
84
85 #if defined(OS_WIN)
86 static bool IsPluginDelegateWindow(HWND window);
87 static bool GetPluginNameFromWindow(HWND window,
88 base::string16* plugin_name);
89 static bool GetPluginVersionFromWindow(HWND window,
90 base::string16* plugin_version);
91
92 // Returns true if the window handle passed in is that of the dummy
93 // activation window for windowless plugins.
94 static bool IsDummyActivationWindow(HWND window);
95
96 // Returns the default HWND to parent the windowed plugins and dummy windows
97 // for activation to when none isavailable.
98 static HWND GetDefaultWindowParent();
99 #endif
100
101 // WebPluginDelegate implementation
102 virtual bool Initialize(const GURL& url,
103 const std::vector<std::string>& arg_names,
104 const std::vector<std::string>& arg_values,
105 WebPlugin* plugin,
106 bool load_manually) OVERRIDE;
107 virtual void PluginDestroyed() OVERRIDE;
108 virtual void UpdateGeometry(const gfx::Rect& window_rect,
109 const gfx::Rect& clip_rect) OVERRIDE;
110 virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect) OVERRIDE;
111 virtual void SetFocus(bool focused) OVERRIDE;
112 virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
113 WebCursor::CursorInfo* cursor_info) OVERRIDE;
114 virtual NPObject* GetPluginScriptableObject() OVERRIDE;
115 virtual NPP GetPluginNPP() OVERRIDE;
116 virtual bool GetFormValue(base::string16* value) OVERRIDE;
117 virtual void DidFinishLoadWithReason(const GURL& url,
118 NPReason reason,
119 int notify_id) OVERRIDE;
120 virtual int GetProcessId() OVERRIDE;
121 virtual void SendJavaScriptStream(const GURL& url,
122 const std::string& result,
123 bool success,
124 int notify_id) OVERRIDE;
125 virtual void DidReceiveManualResponse(const GURL& url,
126 const std::string& mime_type,
127 const std::string& headers,
128 uint32 expected_length,
129 uint32 last_modified) OVERRIDE;
130 virtual void DidReceiveManualData(const char* buffer, int length) OVERRIDE;
131 virtual void DidFinishManualLoading() OVERRIDE;
132 virtual void DidManualLoadFail() OVERRIDE;
133 virtual WebPluginResourceClient* CreateResourceClient(
134 unsigned long resource_id, const GURL& url, int notify_id) OVERRIDE;
135 virtual WebPluginResourceClient* CreateSeekableResourceClient(
136 unsigned long resource_id, int range_request_id) OVERRIDE;
137 // End of WebPluginDelegate implementation.
138
139 gfx::PluginWindowHandle windowed_handle() const { return windowed_handle_; }
140 bool IsWindowless() const { return windowless_; }
141 PluginInstance* instance() { return instance_.get(); }
142 gfx::Rect GetRect() const { return window_rect_; }
143 gfx::Rect GetClipRect() const { return clip_rect_; }
144
145 // Returns the path for the library implementing this plugin.
146 base::FilePath GetPluginPath();
147
148 // Returns a combination of PluginQuirks.
149 int GetQuirks() const { return quirks_; }
150
151 // Informs the plugin that the view it is in has gained or lost focus.
152 void SetContentAreaHasFocus(bool has_focus);
153
154 #if defined(OS_WIN)
155 // Informs the plug-in that an IME has changed its status.
156 void ImeCompositionUpdated(const base::string16& text,
157 const std::vector<int>& clauses,
158 const std::vector<int>& target,
159 int cursor_position);
160
161 // Informs the plugin that IME composition has completed./ If |text| is empty,
162 // IME was cancelled.
163 void ImeCompositionCompleted(const base::string16& text);
164
165 // Returns the IME status retrieved from a plug-in.
166 bool GetIMEStatus(int* input_type, gfx::Rect* caret_rect);
167 #endif
168
169 #if defined(OS_MACOSX) && !defined(USE_AURA)
170 // Informs the plugin that the geometry has changed, as with UpdateGeometry,
171 // but also includes the new buffer context for that new geometry.
172 void UpdateGeometryAndContext(const gfx::Rect& window_rect,
173 const gfx::Rect& clip_rect,
174 gfx::NativeDrawingContext context);
175 // Informs the delegate that the plugin called NPN_Invalidate*. Used as a
176 // trigger for Core Animation drawing.
177 void PluginDidInvalidate();
178 // Returns the delegate currently processing events.
179 static WebPluginDelegateImpl* GetActiveDelegate();
180 // Informs the plugin that the window it is in has gained or lost focus.
181 void SetWindowHasFocus(bool has_focus);
182 // Informs the plugin that its tab or window has been hidden or shown.
183 void SetContainerVisibility(bool is_visible);
184 // Informs the plugin that its containing window's frame has changed.
185 // Frames are in screen coordinates.
186 void WindowFrameChanged(const gfx::Rect& window_frame,
187 const gfx::Rect& view_frame);
188 // Informs the plugin that IME composition has completed.
189 // If |text| is empty, IME was cancelled.
190 void ImeCompositionCompleted(const base::string16& text);
191 // Informs the delegate that the plugin set a Cocoa NSCursor.
192 void SetNSCursor(NSCursor* cursor);
193
194 // Indicates that the windowless plugins will draw directly to the window
195 // context instead of a buffer context.
196 void SetNoBufferContext();
197
198 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia
199 // port to share code with the Darwin / CG port. Later, this will be removed
200 // and all callers will use the Paint defined above.
201 void CGPaint(CGContextRef context, const gfx::Rect& rect);
202 #endif // OS_MACOSX && !USE_AURA
203
204 #if defined(USE_X11)
205 void SetWindowlessShmPixmap(XID shm_pixmap) {
206 windowless_shm_pixmap_ = shm_pixmap;
207 }
208 #endif
209
210 private:
211 friend class base::DeleteHelper<WebPluginDelegateImpl>;
212 friend class WebPluginDelegate;
213
214 explicit WebPluginDelegateImpl(PluginInstance* instance);
215 virtual ~WebPluginDelegateImpl();
216
217 // Called by Initialize() for platform-specific initialization.
218 // If this returns false, the plugin shouldn't be started--see Initialize().
219 bool PlatformInitialize();
220
221 // Called by DestroyInstance(), used for platform-specific destruction.
222 void PlatformDestroyInstance();
223
224 //--------------------------
225 // used for windowed plugins
226 void WindowedUpdateGeometry(const gfx::Rect& window_rect,
227 const gfx::Rect& clip_rect);
228 // Create the native window.
229 // Returns true if the window is created (or already exists).
230 // Returns false if unable to create the window.
231 bool WindowedCreatePlugin();
232
233 // Destroy the native window.
234 void WindowedDestroyWindow();
235
236 // Reposition the native window to be in sync with the given geometry.
237 // Returns true if the native window has moved or been clipped differently.
238 bool WindowedReposition(const gfx::Rect& window_rect,
239 const gfx::Rect& clip_rect);
240
241 // Tells the plugin about the current state of the window.
242 // See NPAPI NPP_SetWindow for more information.
243 void WindowedSetWindow();
244
245 #if defined(OS_WIN)
246 // Registers the window class for our window
247 ATOM RegisterNativeWindowClass();
248
249 // Our WndProc functions.
250 static LRESULT CALLBACK WrapperWindowProc(
251 HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
252 static LRESULT CALLBACK NativeWndProc(
253 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
254 static LRESULT CALLBACK FlashWindowlessWndProc(
255 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
256 static LRESULT CALLBACK DummyWindowProc(
257 HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
258
259 // Used for throttling Flash messages.
260 static void ClearThrottleQueueForWindow(HWND window);
261 static void OnThrottleMessage();
262 static void ThrottleMessage(WNDPROC proc, HWND hwnd, UINT message,
263 WPARAM wParam, LPARAM lParam);
264 #endif
265
266 //----------------------------
267 // used for windowless plugins
268 void WindowlessUpdateGeometry(const gfx::Rect& window_rect,
269 const gfx::Rect& clip_rect);
270 void WindowlessPaint(gfx::NativeDrawingContext hdc, const gfx::Rect& rect);
271
272 // Tells the plugin about the current state of the window.
273 // See NPAPI NPP_SetWindow for more information.
274 void WindowlessSetWindow();
275
276 // Informs the plugin that it has gained or lost keyboard focus (on the Mac,
277 // this just means window first responder status).
278 void SetPluginHasFocus(bool focused);
279
280 // Handles the platform specific details of setting plugin focus. Returns
281 // false if the platform cancelled the focus tranfer.
282 bool PlatformSetPluginHasFocus(bool focused);
283
284 //-----------------------------------------
285 // used for windowed and windowless plugins
286
287 // Does platform-specific event handling. Arguments and return are identical
288 // to HandleInputEvent.
289 bool PlatformHandleInputEvent(const WebKit::WebInputEvent& event,
290 WebCursor::CursorInfo* cursor_info);
291
292 // Closes down and destroys our plugin instance.
293 void DestroyInstance();
294
295
296 // used for windowed plugins
297 // Note: on Mac OS X, the only time the windowed handle is non-zero
298 // is the case of accelerated rendering, which uses a fake window handle to
299 // identify itself back to the browser. It still performs all of its
300 // work offscreen.
301 gfx::PluginWindowHandle windowed_handle_;
302 gfx::Rect windowed_last_pos_;
303
304 bool windowed_did_set_window_;
305
306 // used by windowed and windowless plugins
307 bool windowless_;
308
309 WebPlugin* plugin_;
310 scoped_refptr<PluginInstance> instance_;
311
312 #if defined(OS_WIN)
313 // Original wndproc before we subclassed.
314 WNDPROC plugin_wnd_proc_;
315
316 // Used to throttle WM_USER+1 messages in Flash.
317 uint32 last_message_;
318 bool is_calling_wndproc;
319
320 // An IME emulator used by a windowless plug-in to retrieve IME data through
321 // IMM32 functions.
322 scoped_ptr<WebPluginIMEWin> plugin_ime_;
323 #endif // defined(OS_WIN)
324
325 #if defined(USE_X11)
326 // The SHM pixmap for a windowless plugin.
327 XID windowless_shm_pixmap_;
328 #endif
329
330 #if defined(TOOLKIT_GTK)
331 // The pixmap we're drawing into, for a windowless plugin.
332 GdkPixmap* pixmap_;
333 double first_event_time_;
334
335 // On Linux some plugins assume that the GtkSocket container is in the same
336 // process. So we create a GtkPlug to plug into the browser's container, and
337 // a GtkSocket to hold the plugin. We then send the GtkPlug to the browser
338 // process.
339 GtkWidget* plug_;
340 GtkWidget* socket_;
341
342 // Ensure pixmap_ exists and is at least width by height pixels.
343 void EnsurePixmapAtLeastSize(int width, int height);
344 #endif
345
346 NPWindow window_;
347 gfx::Rect window_rect_;
348 gfx::Rect clip_rect_;
349 int quirks_;
350
351 #if defined(OS_WIN)
352 // Windowless plugins don't have keyboard focus causing issues with the
353 // plugin not receiving keyboard events if the plugin enters a modal
354 // loop like TrackPopupMenuEx or MessageBox, etc.
355 // This is a basic issue with windows activation and focus arising due to
356 // the fact that these windows are created by different threads. Activation
357 // and focus are thread specific states, and if the browser has focus,
358 // the plugin may not have focus.
359 // To fix a majority of these activation issues we create a dummy visible
360 // child window to which we set focus whenever the windowless plugin
361 // receives a WM_LBUTTONDOWN/WM_RBUTTONDOWN message via NPP_HandleEvent.
362
363 HWND dummy_window_for_activation_;
364 HWND dummy_window_parent_;
365 WNDPROC old_dummy_window_proc_;
366 bool CreateDummyWindowForActivation();
367
368 // Returns true if the event passed in needs to be tracked for a potential
369 // modal loop.
370 static bool ShouldTrackEventForModalLoops(NPEvent* event);
371
372 // The message filter hook procedure, which tracks modal loops entered by
373 // a plugin in the course of a NPP_HandleEvent call.
374 static LRESULT CALLBACK HandleEventMessageFilterHook(int code, WPARAM wParam,
375 LPARAM lParam);
376
377 // TrackPopupMenu interceptor. Parameters are the same as the Win32 function
378 // TrackPopupMenu.
379 static BOOL WINAPI TrackPopupMenuPatch(HMENU menu, unsigned int flags, int x,
380 int y, int reserved, HWND window,
381 const RECT* rect);
382
383 // SetCursor interceptor for windowless plugins.
384 static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor);
385
386 // RegEnumKeyExW interceptor.
387 static LONG WINAPI RegEnumKeyExWPatch(
388 HKEY key, DWORD index, LPWSTR name, LPDWORD name_size, LPDWORD reserved,
389 LPWSTR class_name, LPDWORD class_size, PFILETIME last_write_time);
390
391 // GetProcAddress intercepter for windowless plugins.
392 static FARPROC WINAPI GetProcAddressPatch(HMODULE module, LPCSTR name);
393
394 // The mouse hook proc which handles mouse capture in windowed plugins.
395 static LRESULT CALLBACK MouseHookProc(int code, WPARAM wParam,
396 LPARAM lParam);
397
398 // Calls SetCapture/ReleaseCapture based on the message type.
399 static void HandleCaptureForMessage(HWND window, UINT message);
400
401 #elif defined(OS_MACOSX) && !defined(USE_AURA)
402 // Sets window_rect_ to |rect|
403 void SetPluginRect(const gfx::Rect& rect);
404 // Sets content_area_origin to |origin|
405 void SetContentAreaOrigin(const gfx::Point& origin);
406 // Updates everything that depends on the plugin's absolute screen location.
407 void PluginScreenLocationChanged();
408 // Updates anything that depends on plugin visibility.
409 void PluginVisibilityChanged();
410
411 // Starts an IME session.
412 void StartIme();
413
414 // Informs the browser about the updated accelerated drawing surface.
415 void UpdateAcceleratedSurface();
416
417 // Uses a CARenderer to draw the plug-in's layer in our OpenGL surface.
418 void DrawLayerInSurface();
419
420 bool use_buffer_context_;
421 CGContextRef buffer_context_; // Weak ref.
422
423 CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in.
424 WebPluginAcceleratedSurface* surface_; // Weak ref.
425 CARenderer* renderer_; // Renders layer_ to surface_.
426 scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_;
427
428 // The upper-left corner of the web content area in screen coordinates,
429 // relative to an upper-left (0,0).
430 gfx::Point content_area_origin_;
431
432 bool containing_window_has_focus_;
433 bool initial_window_focus_;
434 bool container_is_visible_;
435 bool have_called_set_window_;
436
437 gfx::Rect cached_clip_rect_;
438
439 bool ime_enabled_;
440 int keyup_ignore_count_;
441
442 scoped_ptr<ExternalDragTracker> external_drag_tracker_;
443 #endif // OS_MACOSX && !USE_AURA
444
445 // Called by the message filter hook when the plugin enters a modal loop.
446 void OnModalLoopEntered();
447
448 // Returns true if the message passed in corresponds to a user gesture.
449 static bool IsUserGesture(const WebKit::WebInputEvent& event);
450
451 // The url with which the plugin was instantiated.
452 std::string plugin_url_;
453
454 #if defined(OS_WIN)
455 // Indicates the end of a user gesture period.
456 void OnUserGestureEnd();
457
458 // Handle to the message filter hook
459 HHOOK handle_event_message_filter_hook_;
460
461 // Event which is set when the plugin enters a modal loop in the course
462 // of a NPP_HandleEvent call.
463 HANDLE handle_event_pump_messages_event_;
464
465 // This flag indicates whether we started tracking a user gesture message.
466 bool user_gesture_message_posted_;
467
468 // Runnable Method Factory used to invoke the OnUserGestureEnd method
469 // asynchronously.
470 base::WeakPtrFactory<WebPluginDelegateImpl> user_gesture_msg_factory_;
471
472 // Handle to the mouse hook installed for certain windowed plugins like
473 // flash.
474 HHOOK mouse_hook_;
475 #endif
476
477 // Holds the depth of the HandleEvent callstack.
478 int handle_event_depth_;
479
480 // Holds the current cursor set by the windowless plugin.
481 WebCursor current_windowless_cursor_;
482
483 // Set to true initially and indicates if this is the first npp_setwindow
484 // call received by the plugin.
485 bool first_set_window_call_;
486
487 // True if the plugin thinks it has keyboard focus
488 bool plugin_has_focus_;
489 // True if the plugin element has focus within the web content, regardless of
490 // whether its containing view currently has focus.
491 bool has_webkit_focus_;
492 // True if the containing view currently has focus.
493 // Initially set to true so that plugin focus still works in environments
494 // where SetContentAreaHasFocus is never called. See
495 // https://bugs.webkit.org/show_bug.cgi?id=46013 for details.
496 bool containing_view_has_focus_;
497
498 // True if NPP_New did not return an error.
499 bool creation_succeeded_;
500
501 DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateImpl);
502 };
503
504 } // namespace npapi
505 } // namespace webkit
506
507 #endif // WEBKIT_PLUGINS_NPAPI_WEBPLUGIN_DELEGATE_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698