summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-31 04:32:30 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-31 04:32:30 +0000
commite612d764f473f54807cb24bedc1b147bb9672ca6 (patch)
tree361f7de9eb49f81e201b6eefafa6cc8d7061d575 /webkit/glue/plugins
parent711abaeaaec2bb552d9fe161200778f449fd2da0 (diff)
downloadchromium_src-e612d764f473f54807cb24bedc1b147bb9672ca6.zip
chromium_src-e612d764f473f54807cb24bedc1b147bb9672ca6.tar.gz
chromium_src-e612d764f473f54807cb24bedc1b147bb9672ca6.tar.bz2
Move plugin-related files in webkit/glue to webkit/glue/plugins to make them
easier to find. With a random subset of files in webkit/glue, it's impossible to predict where you should find a file. No code change TEST=none BUG=none Review URL: http://codereview.chromium.org/1559008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43177 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/gtk_plugin_container_manager.cc4
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container.cc2
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container_manager.cc2
-rw-r--r--webkit/glue/plugins/npapi_extension_thunk.cc4
-rw-r--r--webkit/glue/plugins/plugin_host.cc6
-rw-r--r--webkit/glue/plugins/plugin_instance.cc4
-rw-r--r--webkit/glue/plugins/plugin_lib.h4
-rw-r--r--webkit/glue/plugins/plugin_list.h2
-rw-r--r--webkit/glue/plugins/plugin_stream_url.cc4
-rw-r--r--webkit/glue/plugins/plugin_stream_url.h4
-rw-r--r--webkit/glue/plugins/webplugin.cc23
-rw-r--r--webkit/glue/plugins/webplugin.h194
-rw-r--r--webkit/glue/plugins/webplugin_delegate.h161
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc2
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm6
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_win.cc2
-rw-r--r--webkit/glue/plugins/webplugin_impl.cc1207
-rw-r--r--webkit/glue/plugins/webplugin_impl.h321
-rw-r--r--webkit/glue/plugins/webplugin_impl_unittest.cc232
-rw-r--r--webkit/glue/plugins/webplugin_page_delegate.h69
-rw-r--r--webkit/glue/plugins/webplugininfo.h47
22 files changed, 2279 insertions, 25 deletions
diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.cc b/webkit/glue/plugins/gtk_plugin_container_manager.cc
index 53b6f4d..9d9ee4b 100644
--- a/webkit/glue/plugins/gtk_plugin_container_manager.cc
+++ b/webkit/glue/plugins/gtk_plugin_container_manager.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,7 @@
#include "base/logging.h"
#include "gfx/gtk_util.h"
#include "webkit/glue/plugins/gtk_plugin_container.h"
-#include "webkit/glue/webplugin.h"
+#include "webkit/glue/plugins/webplugin.h"
GtkWidget* GtkPluginContainerManager::CreatePluginContainer(
gfx::PluginWindowHandle id) {
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container.cc b/webkit/glue/plugins/mac_accelerated_surface_container.cc
index 7d9ae67..8eca9d2 100644
--- a/webkit/glue/plugins/mac_accelerated_surface_container.cc
+++ b/webkit/glue/plugins/mac_accelerated_surface_container.cc
@@ -6,8 +6,8 @@
#include "app/surface/io_surface_support_mac.h"
#include "base/logging.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/mac_accelerated_surface_container_manager.h"
+#include "webkit/glue/plugins/webplugin.h"
MacAcceleratedSurfaceContainer::MacAcceleratedSurfaceContainer()
: x_(0),
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc b/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc
index a149661..635348f 100644
--- a/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc
+++ b/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc
@@ -5,8 +5,8 @@
#include "webkit/glue/plugins/mac_accelerated_surface_container_manager.h"
#include "base/logging.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/mac_accelerated_surface_container.h"
+#include "webkit/glue/plugins/webplugin.h"
MacAcceleratedSurfaceContainerManager::MacAcceleratedSurfaceContainerManager()
: current_id_(0) {
diff --git a/webkit/glue/plugins/npapi_extension_thunk.cc b/webkit/glue/plugins/npapi_extension_thunk.cc
index 0c25655..141d960 100644
--- a/webkit/glue/plugins/npapi_extension_thunk.cc
+++ b/webkit/glue/plugins/npapi_extension_thunk.cc
@@ -9,10 +9,10 @@
#include "base/utf_string_conversions.h"
#include "third_party/npapi/bindings/npapi_extensions.h"
#include "webkit/glue/plugins/plugin_instance.h"
+#include "webkit/glue/plugins/webplugin.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
#include "webkit/glue/scoped_clipboard_writer_glue.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/webplugin.h"
-#include "webkit/glue/webplugin_delegate.h"
// FindInstance()
// Finds a PluginInstance from an NPP.
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index b262188..bc2a6f2 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,14 +16,14 @@
#include "net/base/net_util.h"
#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
#include "webkit/default_plugin/default_plugin_shared.h"
-#include "webkit/glue/webplugininfo.h"
-#include "webkit/glue/webplugin_delegate.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/npapi_extension_thunk.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
+#include "webkit/glue/plugins/webplugininfo.h"
#include "third_party/npapi/bindings/npapi_extensions.h"
#include "third_party/npapi/bindings/npruntime.h"
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index 037d043..db5ccbf 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -10,13 +10,13 @@
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "webkit/glue/webplugin.h"
-#include "webkit/glue/webplugin_delegate.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_host.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/plugins/plugin_string_stream.h"
+#include "webkit/glue/plugins/webplugin.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
#include "net/base/escape.h"
#if defined(OS_MACOSX)
diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h
index 6af2893..dc0b304 100644
--- a/webkit/glue/plugins/plugin_lib.h
+++ b/webkit/glue/plugins/plugin_lib.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
#include "base/ref_counted.h"
#include "build/build_config.h"
#include "webkit/glue/plugins/plugin_list.h"
-#include "webkit/glue/webplugin.h"
+#include "webkit/glue/plugins/webplugin.h"
struct WebPluginInfo;
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index b80d83b..d4aa31c 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -14,7 +14,7 @@
#include "base/file_path.h"
#include "base/lock.h"
#include "third_party/npapi/bindings/nphostapi.h"
-#include "webkit/glue/webplugininfo.h"
+#include "webkit/glue/plugins/webplugininfo.h"
class GURL;
diff --git a/webkit/glue/plugins/plugin_stream_url.cc b/webkit/glue/plugins/plugin_stream_url.cc
index 38f7edd..6694139 100644
--- a/webkit/glue/plugins/plugin_stream_url.cc
+++ b/webkit/glue/plugins/plugin_stream_url.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/glue/plugins/plugin_stream_url.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/plugin_host.h"
#include "webkit/glue/plugins/plugin_instance.h"
+#include "webkit/glue/plugins/webplugin.h"
namespace NPAPI {
diff --git a/webkit/glue/plugins/plugin_stream_url.h b/webkit/glue/plugins/plugin_stream_url.h
index 7d3f59a..688723c 100644
--- a/webkit/glue/plugins/plugin_stream_url.h
+++ b/webkit/glue/plugins/plugin_stream_url.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,8 @@
#define WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_URL_H__
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/plugin_stream.h"
+#include "webkit/glue/plugins/webplugin.h"
#include "googleurl/src/gurl.h"
namespace NPAPI {
diff --git a/webkit/glue/plugins/webplugin.cc b/webkit/glue/plugins/webplugin.cc
new file mode 100644
index 0000000..6443318
--- /dev/null
+++ b/webkit/glue/plugins/webplugin.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/webplugin.h"
+
+namespace webkit_glue {
+
+WebPluginGeometry::WebPluginGeometry()
+ : window(gfx::kNullPluginWindow),
+ rects_valid(false),
+ visible(false) {
+}
+
+bool WebPluginGeometry::Equals(const WebPluginGeometry& rhs) const {
+ return window == rhs.window &&
+ window_rect == rhs.window_rect &&
+ clip_rect == rhs.clip_rect &&
+ cutout_rects == rhs.cutout_rects &&
+ rects_valid == rhs.rects_valid &&
+ visible == rhs.visible;
+}
+} // namespace webkit_glue
diff --git a/webkit/glue/plugins/webplugin.h b/webkit/glue/plugins/webplugin.h
new file mode 100644
index 0000000..cde5fce
--- /dev/null
+++ b/webkit/glue/plugins/webplugin.h
@@ -0,0 +1,194 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_WEBPLUGIN_H_
+#define WEBKIT_GLUE_WEBPLUGIN_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "gfx/native_widget_types.h"
+#include "gfx/rect.h"
+
+// TODO(port): this typedef is obviously incorrect on non-Windows
+// platforms, but now a lot of code now accidentally depends on them
+// existing. #ifdef out these declarations and fix all the users.
+typedef void* HANDLE;
+
+class GURL;
+struct NPObject;
+
+namespace WebKit {
+class WebFrame;
+}
+
+namespace webkit_glue {
+
+class WebPluginDelegate;
+class WebPluginParentView;
+class WebPluginResourceClient;
+
+// Describes the new location for a plugin window.
+struct WebPluginGeometry {
+ WebPluginGeometry();
+
+ bool Equals(const WebPluginGeometry& rhs) const;
+
+ // On Windows, this is the plugin window in the plugin process.
+ // On X11, this is the XID of the plugin-side GtkPlug containing the
+ // GtkSocket hosting the actual plugin window.
+ //
+ // On Mac OS X, all of the plugin types are currently "windowless"
+ // (window == 0) except for the special case of the GPU plugin,
+ // which currently performs rendering on behalf of the Pepper 3D API
+ // and WebGL. The GPU plugin uses a simple integer for the
+ // PluginWindowHandle which is used to map to a side data structure
+ // containing information about the plugin. Soon this plugin will be
+ // generalized, at which point this mechanism will be rethought or
+ // removed.
+ gfx::PluginWindowHandle window;
+ gfx::Rect window_rect;
+ // Clip rect (include) and cutouts (excludes), relative to
+ // window_rect origin.
+ gfx::Rect clip_rect;
+ std::vector<gfx::Rect> cutout_rects;
+ bool rects_valid;
+ bool visible;
+};
+
+// The WebKit side of a plugin implementation. It provides wrappers around
+// operations that need to interact with the frame and other WebCore objects.
+class WebPlugin {
+ public:
+ virtual ~WebPlugin() {}
+
+ // Called by the plugin delegate to let the WebPlugin know if the plugin is
+ // windowed (i.e. handle is not NULL) or windowless (handle is NULL). This
+ // tells the WebPlugin to send mouse/keyboard events to the plugin delegate,
+ // as well as the information about the HDC for paint operations.
+ virtual void SetWindow(gfx::PluginWindowHandle window) = 0;
+
+ // Whether input events should be sent to the delegate.
+ virtual void SetAcceptsInputEvents(bool accepts) = 0;
+
+ // Called by the plugin delegate to let it know that the window is being
+ // destroyed.
+ virtual void WillDestroyWindow(gfx::PluginWindowHandle window) = 0;
+#if defined(OS_WIN)
+ // The pump_messages_event is a event handle which is valid only for
+ // windowless plugins and is used in NPP_HandleEvent calls to pump messages
+ // if the plugin enters a modal loop.
+ // Cancels a pending request.
+ virtual void SetWindowlessPumpEvent(HANDLE pump_messages_event) = 0;
+#endif
+ virtual void CancelResource(unsigned long id) = 0;
+ virtual void Invalidate() = 0;
+ virtual void InvalidateRect(const gfx::Rect& rect) = 0;
+
+ // Returns the NPObject for the browser's window object.
+ virtual NPObject* GetWindowScriptNPObject() = 0;
+
+ // Returns the DOM element that loaded the plugin.
+ virtual NPObject* GetPluginElement() = 0;
+
+ // Cookies
+ virtual void SetCookie(const GURL& url,
+ const GURL& first_party_for_cookies,
+ const std::string& cookie) = 0;
+ virtual std::string GetCookies(const GURL& url,
+ const GURL& first_party_for_cookies) = 0;
+
+ // Shows a modal HTML dialog containing the given URL. json_arguments are
+ // passed to the dialog via the DOM 'window.chrome.dialogArguments', and the
+ // retval is the string returned by 'window.chrome.send("DialogClose",
+ // retval)'.
+ virtual void ShowModalHTMLDialog(const GURL& url, int width, int height,
+ const std::string& json_arguments,
+ std::string* json_retval) = 0;
+
+ // When a default plugin has downloaded the plugin list and finds it is
+ // available, it calls this method to notify the renderer. Also it will update
+ // the status when user clicks on the plugin to install.
+ virtual void OnMissingPluginStatus(int status) = 0;
+
+ // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated
+ // by plugins. If the plugin wants notification of the result, notify_id will
+ // be non-zero.
+ virtual void HandleURLRequest(const char* url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ bool popups_allowed) = 0;
+
+ // Cancels document load.
+ virtual void CancelDocumentLoad() = 0;
+
+ // Initiates a HTTP range request for an existing stream.
+ virtual void InitiateHTTPRangeRequest(const char* url,
+ const char* range_info,
+ int range_request_id) = 0;
+
+ // Returns true iff in off the record (Incognito) mode.
+ virtual bool IsOffTheRecord() = 0;
+
+ // Called when the WebPluginResourceClient instance is deleted.
+ virtual void ResourceClientDeleted(
+ WebPluginResourceClient* resource_client) {}
+
+ // Defers the loading of the resource identified by resource_id. This is
+ // controlled by the defer parameter.
+ virtual void SetDeferResourceLoading(unsigned long resource_id,
+ bool defer) = 0;
+
+#if defined(OS_MACOSX)
+ // Synthesize a fake window handle for the plug-in to identify the instance
+ // to the browser, allowing mapping to a surface for hardware accelleration
+ // of plug-in content. The browser generates the handle which is then set on
+ // the plug-in.
+ virtual void BindFakePluginWindowHandle() {}
+
+ // Tell the browser (via the renderer) to invalidate because the
+ // accelerated buffers have changed.
+ virtual void AcceleratedFrameBuffersDidSwap(gfx::PluginWindowHandle window) {}
+
+ // Tell the renderer and browser to associate the given plugin handle with
+ // |accelerated_surface_identifier|. The geometry is used to resize any
+ // native "window" (which on the Mac is a CALayer).
+ virtual void SetAcceleratedSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 accelerated_surface_identifier) {}
+#endif
+
+ // Gets the WebPluginDelegate that implements the interface.
+ // This API is only for use with Pepper, and is only overridden
+ // by in-renderer implementations.
+ virtual WebPluginDelegate* delegate() { return NULL; }
+};
+
+// Simpler version of ResourceHandleClient that lends itself to proxying.
+class WebPluginResourceClient {
+ public:
+ virtual ~WebPluginResourceClient() {}
+ virtual void WillSendRequest(const GURL& url) = 0;
+ // The request_is_seekable parameter indicates whether byte range requests
+ // can be issued for the underlying stream.
+ virtual void DidReceiveResponse(const std::string& mime_type,
+ const std::string& headers,
+ uint32 expected_length,
+ uint32 last_modified,
+ bool request_is_seekable) = 0;
+ virtual void DidReceiveData(const char* buffer, int length,
+ int data_offset) = 0;
+ virtual void DidFinishLoading() = 0;
+ virtual void DidFail() = 0;
+ virtual bool IsMultiByteResponseExpected() = 0;
+};
+
+} // namespace webkit_glue
+
+#endif // #ifndef WEBKIT_GLUE_WEBPLUGIN_H_
diff --git a/webkit/glue/plugins/webplugin_delegate.h b/webkit/glue/plugins/webplugin_delegate.h
new file mode 100644
index 0000000..0b08c9e
--- /dev/null
+++ b/webkit/glue/plugins/webplugin_delegate.h
@@ -0,0 +1,161 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_WEBPLUGIN_DELEGATE_H_
+#define WEBKIT_GLUE_WEBPLUGIN_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/string16.h"
+#include "build/build_config.h"
+#include "gfx/native_widget_types.h"
+#include "third_party/npapi/bindings/npapi.h"
+#include "third_party/npapi/bindings/npapi_extensions.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h"
+#include "webkit/glue/plugins/webplugin_2d_device_delegate.h"
+#include "webkit/glue/plugins/webplugin_3d_device_delegate.h"
+#include "webkit/glue/plugins/webplugin_audio_device_delegate.h"
+#include "webkit/glue/plugins/webplugin_file_delegate.h"
+#include "webkit/glue/plugins/webplugin_print_delegate.h"
+
+
+class FilePath;
+class GURL;
+struct NPObject;
+
+namespace WebKit {
+class WebInputEvent;
+struct WebCursorInfo;
+}
+
+namespace gfx {
+class Rect;
+}
+
+namespace webkit_glue {
+
+class WebPlugin;
+class WebPluginResourceClient;
+
+// This is the interface that a plugin implementation needs to provide.
+class WebPluginDelegate : public WebPlugin2DDeviceDelegate,
+ public WebPlugin3DDeviceDelegate,
+ public WebPluginAudioDeviceDelegate,
+ public WebPluginPrintDelegate,
+ public WebPluginFileDelegate {
+ public:
+ virtual ~WebPluginDelegate() {}
+
+ // Initializes the plugin implementation with the given (UTF8) arguments.
+ // Note that the lifetime of WebPlugin must be longer than this delegate.
+ // If this function returns false the plugin isn't started and shouldn't be
+ // called again. If this method succeeds, then the WebPlugin is valid until
+ // PluginDestroyed is called.
+ // The load_manually parameter if true indicates that the plugin data would
+ // be passed from webkit. if false indicates that the plugin should download
+ // the data. This also controls whether the plugin is instantiated as a full
+ // page plugin (NP_FULL) or embedded (NP_EMBED).
+ virtual bool Initialize(const GURL& url,
+ const std::vector<std::string>& arg_names,
+ const std::vector<std::string>& arg_values,
+ WebPlugin* plugin,
+ bool load_manually) = 0;
+
+ // Called when the WebPlugin is being destroyed. This is a signal to the
+ // delegate that it should tear-down the plugin implementation and not call
+ // methods on the WebPlugin again.
+ virtual void PluginDestroyed() = 0;
+
+ // Update the geometry of the plugin. This is a request to move the
+ // plugin, relative to its containing window, to the coords given by
+ // window_rect. Its contents should be clipped to the coords given
+ // by clip_rect, which are relative to the origin of the plugin
+ // window. The clip_rect is in plugin-relative coordinates.
+ virtual void UpdateGeometry(const gfx::Rect& window_rect,
+ const gfx::Rect& clip_rect) = 0;
+
+ // Tells the plugin to paint the damaged rect. |canvas| is only used for
+ // windowless plugins.
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect) = 0;
+
+ // Tells the plugin to print itself.
+ virtual void Print(gfx::NativeDrawingContext hdc) = 0;
+
+ // Informs the plugin that it now has focus. This is only called in
+ // windowless mode.
+ virtual void SetFocus() = 0;
+
+ // For windowless plugins, gives them a user event like mouse/keyboard.
+ // Returns whether the event was handled. This is only called in windowsless
+ // mode. See NPAPI NPP_HandleEvent for more information.
+ virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo* cursor) = 0;
+
+ // Gets the NPObject associated with the plugin for scripting.
+ virtual NPObject* GetPluginScriptableObject() = 0;
+
+ // Receives notification about a resource load that the plugin initiated
+ // for a frame.
+ virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason,
+ int notify_id) = 0;
+
+ // Returns the process id of the process that is running the plugin.
+ virtual int GetProcessId() = 0;
+
+ // The result, UTF-8 encoded, of the script execution is returned via this
+ // function.
+ virtual void SendJavaScriptStream(const GURL& url,
+ const std::string& result,
+ bool success,
+ int notify_id) = 0;
+
+ // Receives notification about data being available.
+ virtual void DidReceiveManualResponse(const GURL& url,
+ const std::string& mime_type,
+ const std::string& headers,
+ uint32 expected_length,
+ uint32 last_modified) = 0;
+
+ // Receives the data.
+ virtual void DidReceiveManualData(const char* buffer, int length) = 0;
+
+ // Indicates end of data load.
+ virtual void DidFinishManualLoading() = 0;
+
+ // Indicates a failure in data receipt.
+ virtual void DidManualLoadFail() = 0;
+
+ // Only supported when the plugin is the default plugin.
+ virtual void InstallMissingPlugin() = 0;
+
+ // Creates a WebPluginResourceClient instance and returns the same.
+ virtual WebPluginResourceClient* CreateResourceClient(
+ unsigned long resource_id,
+ const GURL& url,
+ int notify_id) = 0;
+
+ // Creates a WebPluginResourceClient instance for an existing stream that is
+ // has become seekable.
+ virtual WebPluginResourceClient* CreateSeekableResourceClient(
+ unsigned long resource_id, int range_request_id) = 0;
+
+ // See WebPluginContainerImpl's description of the interface.
+ virtual bool SupportsFind() { return false; }
+ virtual void StartFind(const std::string& search_text,
+ bool case_sensitive,
+ int identifier) {}
+ virtual void SelectFindResult(bool forward) {}
+ virtual void StopFind() {}
+ virtual void NumberOfFindResultsChanged(int total, bool final_result) {}
+ virtual void SelectedFindResultChanged(int index) {}
+
+ // Used for zooming of full page plugins. 0 means reset, while -1 means zoom
+ // out and +1 means zoom in.
+ virtual void Zoom(int factor) {}
+};
+
+} // namespace webkit_glue
+
+#endif // WEBKIT_GLUE_WEBPLUGIN_DELEGATE_H_
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index a66f282..3295a08 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,8 +19,8 @@
#include "gfx/native_widget_types.h"
#include "gfx/rect.h"
#include "third_party/npapi/bindings/npapi.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
#include "webkit/glue/webcursor.h"
-#include "webkit/glue/webplugin_delegate.h"
#if defined(OS_MACOSX)
#include "app/surface/accelerated_surface_mac.h"
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 2c6b239..2501b01 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -20,13 +20,13 @@
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/gtk_plugin_container.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
+#include "webkit/glue/plugins/webplugin.h"
#include "webkit/glue/webkit_glue.h"
#include "third_party/npapi/bindings/npapi_x11.h"
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index 1d0b138..bf74453 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,13 +19,13 @@
#include "base/string_util.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "webkit/default_plugin/plugin_impl.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/coregraphics_private_symbols_mac.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/plugins/plugin_web_event_converter_mac.h"
+#include "webkit/glue/plugins/webplugin.h"
#include "webkit/glue/webkit_glue.h"
#ifndef NP_NO_CARBON
@@ -1125,7 +1125,7 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
if (!(event_converter.get() && event_converter->InitWithEvent(event)))
return false;
void* plugin_event = event_converter->plugin_event();
-
+
if (fabsf(zoom_level - 1.0) > kEpsilon)
event_converter->SetZoomLevel(zoom_level);
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
index 2c31856..1c83565 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
@@ -24,8 +24,8 @@
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
+#include "webkit/glue/plugins/webplugin.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/webplugin.h"
using WebKit::WebCursorInfo;
using WebKit::WebKeyboardEvent;
diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc
new file mode 100644
index 0000000..e701675
--- /dev/null
+++ b/webkit/glue/plugins/webplugin_impl.cc
@@ -0,0 +1,1207 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "gfx/rect.h"
+#include "net/base/escape.h"
+#include "net/base/net_errors.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCookieJar.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebDevToolsAgent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebData.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebHTTPHeaderVisitor.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
+#include "webkit/glue/multipart_response_delegate.h"
+#include "webkit/glue/plugins/plugin_host.h"
+#include "webkit/glue/plugins/plugin_instance.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
+#include "webkit/glue/plugins/webplugin_impl.h"
+#include "webkit/glue/plugins/webplugin_page_delegate.h"
+#include "googleurl/src/gurl.h"
+
+using WebKit::WebCanvas;
+using WebKit::WebConsoleMessage;
+using WebKit::WebCookieJar;
+using WebKit::WebCString;
+using WebKit::WebCursorInfo;
+using WebKit::WebData;
+using WebKit::WebDataSource;
+using WebKit::WebDevToolsAgent;
+using WebKit::WebFrame;
+using WebKit::WebHTTPBody;
+using WebKit::WebHTTPHeaderVisitor;
+using WebKit::WebInputEvent;
+using WebKit::WebKeyboardEvent;
+using WebKit::WebMouseEvent;
+using WebKit::WebPluginContainer;
+using WebKit::WebPluginParams;
+using WebKit::WebRect;
+using WebKit::WebString;
+using WebKit::WebURL;
+using WebKit::WebURLError;
+using WebKit::WebURLLoader;
+using WebKit::WebURLLoaderClient;
+using WebKit::WebURLRequest;
+using WebKit::WebURLResponse;
+using WebKit::WebVector;
+using WebKit::WebView;
+using webkit_glue::MultipartResponseDelegate;
+
+namespace webkit_glue {
+namespace {
+
+// This class handles individual multipart responses. It is instantiated when
+// we receive HTTP status code 206 in the HTTP response. This indicates
+// that the response could have multiple parts each separated by a boundary
+// specified in the response header.
+class MultiPartResponseClient : public WebURLLoaderClient {
+ public:
+ explicit MultiPartResponseClient(WebPluginResourceClient* resource_client)
+ : resource_client_(resource_client) {
+ Clear();
+ }
+
+ virtual void willSendRequest(
+ WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
+ virtual void didSendData(
+ WebURLLoader*, unsigned long long, unsigned long long) {}
+
+ // Called when the multipart parser encounters an embedded multipart
+ // response.
+ virtual void didReceiveResponse(
+ WebURLLoader*, const WebURLResponse& response) {
+ if (!MultipartResponseDelegate::ReadContentRanges(
+ response,
+ &byte_range_lower_bound_,
+ &byte_range_upper_bound_)) {
+ NOTREACHED();
+ return;
+ }
+
+ resource_response_ = response;
+ }
+
+ // Receives individual part data from a multipart response.
+ virtual void didReceiveData(
+ WebURLLoader*, const char* data, int data_size) {
+ // TODO(ananta)
+ // We should defer further loads on multipart resources on the same lines
+ // as regular resources requested by plugins to prevent reentrancy.
+ resource_client_->DidReceiveData(
+ data, data_size, byte_range_lower_bound_);
+ }
+
+ virtual void didFinishLoading(WebURLLoader*) {}
+ virtual void didFail(WebURLLoader*, const WebURLError&) {}
+
+ void Clear() {
+ resource_response_.reset();
+ byte_range_lower_bound_ = 0;
+ byte_range_upper_bound_ = 0;
+ }
+
+ private:
+ WebURLResponse resource_response_;
+ // The lower bound of the byte range.
+ int byte_range_lower_bound_;
+ // The upper bound of the byte range.
+ int byte_range_upper_bound_;
+ // The handler for the data.
+ WebPluginResourceClient* resource_client_;
+};
+
+class HeaderFlattener : public WebHTTPHeaderVisitor {
+ public:
+ HeaderFlattener(std::string* buf) : buf_(buf) {
+ }
+
+ virtual void visitHeader(const WebString& name, const WebString& value) {
+ // TODO(darin): Should we really exclude headers with an empty value?
+ if (!name.isEmpty() && !value.isEmpty()) {
+ buf_->append(name.utf8());
+ buf_->append(": ");
+ buf_->append(value.utf8());
+ buf_->append("\n");
+ }
+ }
+
+ private:
+ std::string* buf_;
+};
+
+std::string GetAllHeaders(const WebURLResponse& response) {
+ // TODO(darin): It is possible for httpStatusText to be empty and still have
+ // an interesting response, so this check seems wrong.
+ std::string result;
+ const WebString& status = response.httpStatusText();
+ if (status.isEmpty())
+ return result;
+
+ // TODO(darin): Shouldn't we also report HTTP version numbers?
+ result = StringPrintf("HTTP %d ", response.httpStatusCode());
+ result.append(status.utf8());
+ result.append("\n");
+
+ HeaderFlattener flattener(&result);
+ response.visitHTTPHeaderFields(&flattener);
+
+ return result;
+}
+
+struct ResponseInfo {
+ GURL url;
+ std::string mime_type;
+ uint32 last_modified;
+ uint32 expected_length;
+};
+
+void GetResponseInfo(const WebURLResponse& response,
+ ResponseInfo* response_info) {
+ response_info->url = response.url();
+ response_info->mime_type = response.mimeType().utf8();
+
+ // Measured in seconds since 12:00 midnight GMT, January 1, 1970.
+ response_info->last_modified =
+ static_cast<uint32>(response.lastModifiedDate());
+
+ // If the length comes in as -1, then it indicates that it was not
+ // read off the HTTP headers. We replicate Safari webkit behavior here,
+ // which is to set it to 0.
+ response_info->expected_length =
+ static_cast<uint32>(std::max(response.expectedContentLength(), 0LL));
+
+ WebString content_encoding =
+ response.httpHeaderField(WebString::fromUTF8("Content-Encoding"));
+ if (!content_encoding.isNull() &&
+ !EqualsASCII(content_encoding, "identity")) {
+ // Don't send the compressed content length to the plugin, which only
+ // cares about the decoded length.
+ response_info->expected_length = 0;
+ }
+}
+
+} // namespace
+
+// WebKit::WebPlugin ----------------------------------------------------------
+
+bool WebPluginImpl::initialize(WebPluginContainer* container) {
+ if (!page_delegate_)
+ return false;
+
+ std::string actual_mime_type;
+ WebPluginDelegate* plugin_delegate = page_delegate_->CreatePluginDelegate(
+ plugin_url_, mime_type_, &actual_mime_type);
+ if (!plugin_delegate)
+ return NULL;
+
+ // Set the container before Initialize because the plugin may
+ // synchronously call NPN_GetValue to get its container during its
+ // initialization.
+ SetContainer(container);
+ bool ok = plugin_delegate->Initialize(
+ plugin_url_, arg_names_, arg_values_, this, load_manually_);
+ if (!ok) {
+ plugin_delegate->PluginDestroyed();
+ return false;
+ }
+
+ if (!actual_mime_type.empty())
+ mime_type_ = actual_mime_type;
+ delegate_ = plugin_delegate;
+
+ return true;
+}
+
+void WebPluginImpl::destroy() {
+ SetContainer(NULL);
+ MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+}
+
+NPObject* WebPluginImpl::scriptableObject() {
+ return delegate_->GetPluginScriptableObject();
+}
+
+void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& paint_rect) {
+ if (!delegate_)
+ return;
+
+ // Note that |canvas| is only used when in windowless mode.
+ delegate_->Paint(canvas, paint_rect);
+}
+
+void WebPluginImpl::updateGeometry(
+ const WebRect& window_rect, const WebRect& clip_rect,
+ const WebVector<WebRect>& cutout_rects, bool is_visible) {
+ WebPluginGeometry new_geometry;
+ new_geometry.window = window_;
+ new_geometry.window_rect = window_rect;
+ new_geometry.clip_rect = clip_rect;
+ new_geometry.visible = is_visible;
+ new_geometry.rects_valid = true;
+ for (size_t i = 0; i < cutout_rects.size(); ++i)
+ new_geometry.cutout_rects.push_back(cutout_rects[i]);
+
+ // Only send DidMovePlugin if the geometry changed in some way.
+ if (window_ &&
+ page_delegate_ &&
+ (first_geometry_update_ || !new_geometry.Equals(geometry_))) {
+ page_delegate_->DidMovePlugin(new_geometry);
+ }
+
+ // Only UpdateGeometry if either the window or clip rects have changed.
+ if (first_geometry_update_ ||
+ new_geometry.window_rect != geometry_.window_rect ||
+ new_geometry.clip_rect != geometry_.clip_rect) {
+ // Notify the plugin that its parameters have changed.
+ delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect);
+ }
+
+ // Initiate a download on the plugin url. This should be done for the
+ // first update geometry sequence. We need to ensure that the plugin
+ // receives the geometry update before it starts receiving data.
+ if (first_geometry_update_) {
+ // An empty url corresponds to an EMBED tag with no src attribute.
+ if (!load_manually_ && plugin_url_.is_valid()) {
+ // The Flash plugin hangs for a while if it receives data before
+ // receiving valid plugin geometry. By valid geometry we mean the
+ // geometry received by a call to setFrameRect in the Webkit
+ // layout code path. To workaround this issue we download the
+ // plugin source url on a timer.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, method_factory_.NewRunnableMethod(
+ &WebPluginImpl::OnDownloadPluginSrcUrl), 0);
+ }
+ }
+
+ first_geometry_update_ = false;
+ geometry_ = new_geometry;
+}
+
+void WebPluginImpl::updateFocus(bool focused) {
+ if (focused && accepts_input_events_)
+ delegate_->SetFocus();
+}
+
+void WebPluginImpl::updateVisibility(bool visible) {
+ if (!window_ || !page_delegate_)
+ return;
+
+ WebPluginGeometry move;
+ move.window = window_;
+ move.window_rect = gfx::Rect();
+ move.clip_rect = gfx::Rect();
+ move.rects_valid = false;
+ move.visible = visible;
+
+ page_delegate_->DidMovePlugin(move);
+}
+
+bool WebPluginImpl::acceptsInputEvents() {
+ return accepts_input_events_;
+}
+
+bool WebPluginImpl::handleInputEvent(
+ const WebInputEvent& event, WebCursorInfo& cursor_info) {
+ return delegate_->HandleInputEvent(event, &cursor_info);
+}
+
+void WebPluginImpl::didReceiveResponse(const WebURLResponse& response) {
+ ignore_response_error_ = false;
+
+ ResponseInfo response_info;
+ GetResponseInfo(response, &response_info);
+
+ delegate_->DidReceiveManualResponse(
+ response_info.url,
+ response_info.mime_type,
+ GetAllHeaders(response),
+ response_info.expected_length,
+ response_info.last_modified);
+}
+
+void WebPluginImpl::didReceiveData(const char* data, int data_length) {
+ delegate_->DidReceiveManualData(data, data_length);
+}
+
+void WebPluginImpl::didFinishLoading() {
+ delegate_->DidFinishManualLoading();
+}
+
+void WebPluginImpl::didFailLoading(const WebURLError& error) {
+ if (!ignore_response_error_)
+ delegate_->DidManualLoadFail();
+}
+
+void WebPluginImpl::didFinishLoadingFrameRequest(
+ const WebURL& url, void* notify_data) {
+ if (delegate_) {
+ // We're converting a void* into an arbitrary int id. Though
+ // these types are the same size on all the platforms we support,
+ // the compiler may complain as though they are different, so to
+ // make the casting gods happy go through an intptr_t (the union
+ // of void* and int) rather than converting straight across.
+ delegate_->DidFinishLoadWithReason(
+ url, NPRES_DONE, reinterpret_cast<intptr_t>(notify_data));
+ }
+}
+
+void WebPluginImpl::didFailLoadingFrameRequest(
+ const WebURL& url, void* notify_data, const WebURLError& error) {
+ if (!delegate_)
+ return;
+
+ NPReason reason =
+ error.reason == net::ERR_ABORTED ? NPRES_USER_BREAK : NPRES_NETWORK_ERR;
+ // See comment in didFinishLoadingFrameRequest about the cast here.
+ delegate_->DidFinishLoadWithReason(
+ url, reason, reinterpret_cast<intptr_t>(notify_data));
+}
+
+bool WebPluginImpl::supportsPaginatedPrint() {
+ if (!delegate_)
+ return false;
+ return delegate_->PrintSupportsPrintExtension();
+}
+
+int WebPluginImpl::printBegin(const WebRect& printable_area, int printer_dpi) {
+ if (!delegate_)
+ return 0;
+
+ if (!supportsPaginatedPrint())
+ return 0;
+
+ return delegate_->PrintBegin(printable_area, printer_dpi);
+}
+
+bool WebPluginImpl::printPage(int page_number, WebCanvas* canvas) {
+ if (!delegate_)
+ return false;
+
+ return delegate_->PrintPage(page_number, canvas);
+}
+
+void WebPluginImpl::printEnd() {
+ if (delegate_)
+ delegate_->PrintEnd();
+}
+
+
+// -----------------------------------------------------------------------------
+
+WebPluginImpl::WebPluginImpl(
+ WebFrame* webframe, const WebPluginParams& params,
+ const base::WeakPtr<WebPluginPageDelegate>& page_delegate)
+ : windowless_(false),
+ window_(NULL),
+ accepts_input_events_(false),
+ page_delegate_(page_delegate),
+ webframe_(webframe),
+ delegate_(NULL),
+ container_(NULL),
+ plugin_url_(params.url),
+ load_manually_(params.loadManually),
+ first_geometry_update_(true),
+ ignore_response_error_(false),
+ mime_type_(params.mimeType.utf8()),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
+ StringToLowerASCII(&mime_type_);
+
+ for (size_t i = 0; i < params.attributeNames.size(); ++i) {
+ arg_names_.push_back(params.attributeNames[i].utf8());
+ arg_values_.push_back(params.attributeValues[i].utf8());
+ }
+}
+
+WebPluginImpl::~WebPluginImpl() {
+}
+
+void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
+#if defined(OS_MACOSX)
+ // The only time this is called twice, and the second time with a
+ // non-zero PluginWindowHandle, is the case when this WebPluginImpl
+ // is created on behalf of the GPU plugin. This entire code path
+ // will go away soon, as soon as the GPU plugin becomes the GPU
+ // process, so it is being separated out for easy deletion.
+
+ // The logic we want here is: if (window) DCHECK(!window_);
+ DCHECK(!(window_ && window));
+ window_ = window;
+ // Lie to ourselves about being windowless even if we got a fake
+ // plugin window handle, so we continue to get input events.
+ windowless_ = true;
+ accepts_input_events_ = true;
+ // We do not really need to notify the page delegate that a plugin
+ // window was created -- so don't.
+#else
+ if (window) {
+ DCHECK(!windowless_);
+ window_ = window;
+ accepts_input_events_ = false;
+ if (page_delegate_) {
+ // Tell the view delegate that the plugin window was created, so that it
+ // can create necessary container widgets.
+ page_delegate_->CreatedPluginWindow(window);
+ }
+ } else {
+ DCHECK(!window_); // Make sure not called twice.
+ windowless_ = true;
+ accepts_input_events_ = true;
+ }
+#endif
+}
+
+void WebPluginImpl::WillDestroyWindow(gfx::PluginWindowHandle window) {
+ DCHECK_EQ(window, window_);
+ window_ = NULL;
+ if (page_delegate_)
+ page_delegate_->WillDestroyPluginWindow(window);
+}
+
+GURL WebPluginImpl::CompleteURL(const char* url) {
+ if (!webframe_) {
+ NOTREACHED();
+ return GURL();
+ }
+ // TODO(darin): Is conversion from UTF8 correct here?
+ return webframe_->completeURL(WebString::fromUTF8(url));
+}
+
+void WebPluginImpl::CancelResource(unsigned long id) {
+ for (size_t i = 0; i < clients_.size(); ++i) {
+ if (clients_[i].id == id) {
+ if (clients_[i].loader.get()) {
+ clients_[i].loader->setDefersLoading(false);
+ clients_[i].loader->cancel();
+ RemoveClient(i);
+ }
+ return;
+ }
+ }
+}
+
+bool WebPluginImpl::SetPostData(WebURLRequest* request,
+ const char *buf,
+ uint32 length) {
+ std::vector<std::string> names;
+ std::vector<std::string> values;
+ std::vector<char> body;
+ bool rv = NPAPI::PluginHost::SetPostData(buf, length, &names, &values, &body);
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ request->addHTTPHeaderField(WebString::fromUTF8(names[i]),
+ WebString::fromUTF8(values[i]));
+ }
+
+ WebString content_type_header = WebString::fromUTF8("Content-Type");
+ const WebString& content_type =
+ request->httpHeaderField(content_type_header);
+ if (content_type.isEmpty()) {
+ request->setHTTPHeaderField(
+ content_type_header,
+ WebString::fromUTF8("application/x-www-form-urlencoded"));
+ }
+
+ WebHTTPBody http_body;
+ if (body.size()) {
+ http_body.initialize();
+ http_body.appendData(WebData(&body[0], body.size()));
+ }
+ request->setHTTPBody(http_body);
+
+ return rv;
+}
+
+WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame(
+ const char* url,
+ bool is_javascript_url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ Referrer referrer_flag) {
+ // If there is no target, there is nothing to do
+ if (!target)
+ return NOT_ROUTED;
+
+ // This could happen if the WebPluginContainer was already deleted.
+ if (!webframe_)
+ return NOT_ROUTED;
+
+ WebString target_str = WebString::fromUTF8(target);
+
+ // Take special action for JavaScript URLs
+ if (is_javascript_url) {
+ WebFrame* target_frame =
+ webframe_->view()->findFrameByName(target_str, webframe_);
+ // For security reasons, do not allow JavaScript on frames
+ // other than this frame.
+ if (target_frame != webframe_) {
+ // TODO(darin): Localize this message.
+ const char kMessage[] =
+ "Ignoring cross-frame javascript URL load requested by plugin.";
+ webframe_->addMessageToConsole(
+ WebConsoleMessage(WebConsoleMessage::LevelError,
+ WebString::fromUTF8(kMessage)));
+ return ROUTED;
+ }
+
+ // Route javascript calls back to the plugin.
+ return NOT_ROUTED;
+ }
+
+ // If we got this far, we're routing content to a target frame.
+ // Go fetch the URL.
+
+ GURL complete_url = CompleteURL(url);
+
+ if (strcmp(method, "GET") != 0) {
+ // We're only going to route HTTP/HTTPS requests
+ if (!(complete_url.SchemeIs("http") || complete_url.SchemeIs("https")))
+ return INVALID_URL;
+ }
+
+ WebURLRequest request(complete_url);
+ SetReferrer(&request, referrer_flag);
+
+ request.setHTTPMethod(WebString::fromUTF8(method));
+ request.setFirstPartyForCookies(
+ webframe_->document().firstPartyForCookies());
+ if (len > 0) {
+ if (!SetPostData(&request, buf, len)) {
+ // Uhoh - we're in trouble. There isn't a good way
+ // to recover at this point. Break out.
+ NOTREACHED();
+ return ROUTED;
+ }
+ }
+
+ container_->loadFrameRequest(
+ request, target_str, notify_id != 0, reinterpret_cast<void*>(notify_id));
+ return ROUTED;
+}
+
+NPObject* WebPluginImpl::GetWindowScriptNPObject() {
+ if (!webframe_) {
+ NOTREACHED();
+ return NULL;
+ }
+ return webframe_->windowObject();
+}
+
+NPObject* WebPluginImpl::GetPluginElement() {
+ return container_->scriptableObjectForElement();
+}
+
+void WebPluginImpl::SetCookie(const GURL& url,
+ const GURL& first_party_for_cookies,
+ const std::string& cookie) {
+ if (!page_delegate_)
+ return;
+
+ WebCookieJar* cookie_jar = page_delegate_->GetCookieJar();
+ if (!cookie_jar) {
+ DLOG(WARNING) << "No cookie jar!";
+ return;
+ }
+
+ cookie_jar->setCookie(
+ url, first_party_for_cookies, WebString::fromUTF8(cookie));
+}
+
+std::string WebPluginImpl::GetCookies(const GURL& url,
+ const GURL& first_party_for_cookies) {
+ if (!page_delegate_)
+ return std::string();
+
+ WebCookieJar* cookie_jar = page_delegate_->GetCookieJar();
+ if (!cookie_jar) {
+ DLOG(WARNING) << "No cookie jar!";
+ return std::string();
+ }
+
+ return UTF16ToUTF8(cookie_jar->cookies(url, first_party_for_cookies));
+}
+
+void WebPluginImpl::ShowModalHTMLDialog(const GURL& url, int width, int height,
+ const std::string& json_arguments,
+ std::string* json_retval) {
+ if (page_delegate_) {
+ page_delegate_->ShowModalHTMLDialogForPlugin(
+ url, gfx::Size(width, height), json_arguments, json_retval);
+ }
+}
+
+void WebPluginImpl::OnMissingPluginStatus(int status) {
+ NOTREACHED();
+}
+
+void WebPluginImpl::Invalidate() {
+ if (container_)
+ container_->invalidate();
+}
+
+void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) {
+ if (container_)
+ container_->invalidateRect(rect);
+}
+
+void WebPluginImpl::OnDownloadPluginSrcUrl() {
+ HandleURLRequestInternal(
+ plugin_url_.spec().c_str(), "GET", NULL, NULL, 0, 0, false, DOCUMENT_URL);
+}
+
+WebPluginResourceClient* WebPluginImpl::GetClientFromLoader(
+ WebURLLoader* loader) {
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info)
+ return client_info->client;
+ return NULL;
+}
+
+WebPluginImpl::ClientInfo* WebPluginImpl::GetClientInfoFromLoader(
+ WebURLLoader* loader) {
+ for (size_t i = 0; i < clients_.size(); ++i) {
+ if (clients_[i].loader.get() == loader)
+ return &clients_[i];
+ }
+
+ NOTREACHED();
+ return 0;
+}
+
+void WebPluginImpl::willSendRequest(WebURLLoader* loader,
+ WebURLRequest& request,
+ const WebURLResponse&) {
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
+ if (client)
+ client->WillSendRequest(request.url());
+}
+
+void WebPluginImpl::didSendData(WebURLLoader* loader,
+ unsigned long long bytes_sent,
+ unsigned long long total_bytes_to_be_sent) {
+}
+
+void WebPluginImpl::didReceiveResponse(WebURLLoader* loader,
+ const WebURLResponse& response) {
+ static const int kHttpPartialResponseStatusCode = 206;
+ static const int kHttpResponseSuccessStatusCode = 200;
+
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
+ if (!client)
+ return;
+
+ ResponseInfo response_info;
+ GetResponseInfo(response, &response_info);
+
+ bool request_is_seekable = true;
+ if (client->IsMultiByteResponseExpected()) {
+ if (response.httpStatusCode() == kHttpPartialResponseStatusCode) {
+ HandleHttpMultipartResponse(response, client);
+ return;
+ } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) {
+ // If the client issued a byte range request and the server responds with
+ // HTTP 200 OK, it indicates that the server does not support byte range
+ // requests.
+ // We need to emulate Firefox behavior by doing the following:-
+ // 1. Destroy the plugin instance in the plugin process. Ensure that
+ // existing resource requests initiated for the plugin instance
+ // continue to remain valid.
+ // 2. Create a new plugin instance and notify it about the response
+ // received here.
+ if (!ReinitializePluginForResponse(loader)) {
+ NOTREACHED();
+ return;
+ }
+
+ // The server does not support byte range requests. No point in creating
+ // seekable streams.
+ request_is_seekable = false;
+
+ delete client;
+ client = NULL;
+
+ // Create a new resource client for this request.
+ for (size_t i = 0; i < clients_.size(); ++i) {
+ if (clients_[i].loader.get() == loader) {
+ WebPluginResourceClient* resource_client =
+ delegate_->CreateResourceClient(clients_[i].id, plugin_url_, 0);
+ clients_[i].client = resource_client;
+ client = resource_client;
+ break;
+ }
+ }
+
+ DCHECK(client != NULL);
+ }
+ }
+
+ // Calling into a plugin could result in reentrancy if the plugin yields
+ // control to the OS like entering a modal loop etc. Prevent this by
+ // stopping further loading until the plugin notifies us that it is ready to
+ // accept data
+ loader->setDefersLoading(true);
+
+ client->DidReceiveResponse(
+ response_info.mime_type,
+ GetAllHeaders(response),
+ response_info.expected_length,
+ response_info.last_modified,
+ request_is_seekable);
+
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent()) {
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info)
+ devtools_agent->didReceiveResponse(client_info->id, response);
+ }
+
+ // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP
+ // error codes in the stream header and as a result, was unaware of the
+ // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF
+ // destroy the stream and invoke the NPP_DestroyStream function on the
+ // plugin if the HTTP request fails.
+ const GURL& url = response.url();
+ if (url.SchemeIs("http") || url.SchemeIs("https")) {
+ if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) {
+ // The plugin instance could be in the process of deletion here.
+ // Verify if the WebPluginResourceClient instance still exists before
+ // use.
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info) {
+ client_info->pending_failure_notification = true;
+ }
+ }
+ }
+}
+
+void WebPluginImpl::didReceiveData(WebURLLoader* loader,
+ const char *buffer,
+ int length) {
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
+ if (!client)
+ return;
+
+ // ClientInfo can be removed from clients_ vector by next statements.
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent()) {
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info)
+ devtools_agent->didReceiveData(client_info->id, length);
+ }
+ MultiPartResponseHandlerMap::iterator index =
+ multi_part_response_map_.find(client);
+ if (index != multi_part_response_map_.end()) {
+ MultipartResponseDelegate* multi_part_handler = (*index).second;
+ DCHECK(multi_part_handler != NULL);
+ multi_part_handler->OnReceivedData(buffer, length);
+ } else {
+ loader->setDefersLoading(true);
+ client->DidReceiveData(buffer, length, 0);
+ }
+}
+
+void WebPluginImpl::didFinishLoading(WebURLLoader* loader) {
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info && client_info->client) {
+ MultiPartResponseHandlerMap::iterator index =
+ multi_part_response_map_.find(client_info->client);
+ if (index != multi_part_response_map_.end()) {
+ delete (*index).second;
+ multi_part_response_map_.erase(index);
+ if (page_delegate_)
+ page_delegate_->DidStopLoadingForPlugin();
+ }
+ loader->setDefersLoading(true);
+ WebPluginResourceClient* resource_client = client_info->client;
+ // The ClientInfo can get deleted in the call to DidFinishLoading below.
+ // It is not safe to access this structure after that.
+ client_info->client = NULL;
+ resource_client->DidFinishLoading();
+
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent())
+ devtools_agent->didFinishLoading(client_info->id);
+ }
+}
+
+void WebPluginImpl::didFail(WebURLLoader* loader,
+ const WebURLError& error) {
+ ClientInfo* client_info = GetClientInfoFromLoader(loader);
+ if (client_info && client_info->client) {
+ loader->setDefersLoading(true);
+ WebPluginResourceClient* resource_client = client_info->client;
+ // The ClientInfo can get deleted in the call to DidFail below.
+ // It is not safe to access this structure after that.
+ client_info->client = NULL;
+ resource_client->DidFail();
+
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent())
+ devtools_agent->didFailLoading(client_info->id, error);
+ }
+}
+
+void WebPluginImpl::RemoveClient(size_t i) {
+ clients_.erase(clients_.begin() + i);
+}
+
+void WebPluginImpl::RemoveClient(WebURLLoader* loader) {
+ for (size_t i = 0; i < clients_.size(); ++i) {
+ if (clients_[i].loader.get() == loader) {
+ RemoveClient(i);
+ return;
+ }
+ }
+}
+
+void WebPluginImpl::SetContainer(WebPluginContainer* container) {
+ if (!container)
+ TearDownPluginInstance(NULL);
+ container_ = container;
+}
+
+void WebPluginImpl::HandleURLRequest(const char* url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ bool popups_allowed) {
+ // GetURL/PostURL requests initiated explicitly by plugins should specify the
+ // plugin SRC url as the referrer if it is available.
+ HandleURLRequestInternal(
+ url, method, target, buf, len, notify_id, popups_allowed, PLUGIN_SRC);
+}
+
+void WebPluginImpl::HandleURLRequestInternal(const char* url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ bool popups_allowed,
+ Referrer referrer_flag) {
+ // For this request, we either route the output to a frame
+ // because a target has been specified, or we handle the request
+ // here, i.e. by executing the script if it is a javascript url
+ // or by initiating a download on the URL, etc. There is one special
+ // case in that the request is a javascript url and the target is "_self",
+ // in which case we route the output to the plugin rather than routing it
+ // to the plugin's frame.
+ bool is_javascript_url = StartsWithASCII(url, "javascript:", false);
+ RoutingStatus routing_status = RouteToFrame(
+ url, is_javascript_url, method, target, buf, len, notify_id,
+ referrer_flag);
+ if (routing_status == ROUTED)
+ return;
+
+ if (is_javascript_url) {
+ GURL gurl(url);
+ WebString result = container_->executeScriptURL(gurl, popups_allowed);
+
+ // delegate_ could be NULL because executeScript caused the container to
+ // be deleted.
+ if (delegate_) {
+ delegate_->SendJavaScriptStream(
+ gurl, result.utf8(), !result.isNull(), notify_id);
+ }
+
+ return;
+ }
+
+ unsigned long resource_id = GetNextResourceId();
+ if (!resource_id)
+ return;
+
+ GURL complete_url = CompleteURL(url);
+ WebPluginResourceClient* resource_client = delegate_->CreateResourceClient(
+ resource_id, complete_url, notify_id);
+ if (!resource_client)
+ return;
+
+ // If the RouteToFrame call returned a failure then inform the result
+ // back to the plugin asynchronously.
+ if ((routing_status == INVALID_URL) ||
+ (routing_status == GENERAL_FAILURE)) {
+ resource_client->DidFail();
+ return;
+ }
+
+ // CreateResourceClient() sends a synchronous IPC message so it's possible
+ // that TearDownPluginInstance() may have been called in the nested
+ // message loop. If so, don't start the request.
+ if (!delegate_)
+ return;
+
+ InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf,
+ len, NULL, referrer_flag);
+}
+
+unsigned long WebPluginImpl::GetNextResourceId() {
+ if (!webframe_)
+ return 0;
+ WebView* view = webframe_->view();
+ if (!view)
+ return 0;
+ return view->createUniqueIdentifierForRequest();
+}
+
+bool WebPluginImpl::InitiateHTTPRequest(unsigned long resource_id,
+ WebPluginResourceClient* client,
+ const GURL& url,
+ const char* method,
+ const char* buf,
+ int buf_len,
+ const char* range_info,
+ Referrer referrer_flag) {
+ if (!client) {
+ NOTREACHED();
+ return false;
+ }
+
+ ClientInfo info;
+ info.id = resource_id;
+ info.client = client;
+ info.request.initialize();
+ info.request.setURL(url);
+ info.request.setFirstPartyForCookies(
+ webframe_->document().firstPartyForCookies());
+ info.request.setRequestorProcessID(delegate_->GetProcessId());
+ info.request.setTargetType(WebURLRequest::TargetIsObject);
+ info.request.setHTTPMethod(WebString::fromUTF8(method));
+ info.pending_failure_notification = false;
+
+ if (range_info) {
+ info.request.addHTTPHeaderField(WebString::fromUTF8("Range"),
+ WebString::fromUTF8(range_info));
+ }
+
+ if (strcmp(method, "POST") == 0) {
+ // Adds headers or form data to a request. This must be called before
+ // we initiate the actual request.
+ SetPostData(&info.request, buf, buf_len);
+ }
+
+ SetReferrer(&info.request, referrer_flag);
+
+ // Sets the routing id to associate the ResourceRequest with the RenderView.
+ webframe_->dispatchWillSendRequest(info.request);
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent()) {
+ devtools_agent->identifierForInitialRequest(resource_id, webframe_,
+ info.request);
+ devtools_agent->willSendRequest(resource_id, info.request);
+ }
+
+ info.loader.reset(WebKit::webKitClient()->createURLLoader());
+ if (!info.loader.get())
+ return false;
+ info.loader->loadAsynchronously(info.request, this);
+
+ clients_.push_back(info);
+ return true;
+}
+
+void WebPluginImpl::CancelDocumentLoad() {
+ if (webframe_) {
+ ignore_response_error_ = true;
+ webframe_->stopLoading();
+ }
+}
+
+void WebPluginImpl::InitiateHTTPRangeRequest(
+ const char* url, const char* range_info, int range_request_id) {
+ unsigned long resource_id = GetNextResourceId();
+ if (!resource_id)
+ return;
+
+ GURL complete_url = CompleteURL(url);
+
+ WebPluginResourceClient* resource_client =
+ delegate_->CreateSeekableResourceClient(resource_id, range_request_id);
+ InitiateHTTPRequest(
+ resource_id, resource_client, complete_url, "GET", NULL, 0, range_info,
+ load_manually_ ? NO_REFERRER : PLUGIN_SRC);
+}
+
+void WebPluginImpl::SetDeferResourceLoading(unsigned long resource_id,
+ bool defer) {
+ std::vector<ClientInfo>::iterator client_index = clients_.begin();
+ while (client_index != clients_.end()) {
+ ClientInfo& client_info = *client_index;
+
+ if (client_info.id == resource_id) {
+ client_info.loader->setDefersLoading(defer);
+
+ // If we determined that the request had failed via the HTTP headers
+ // in the response then we send out a failure notification to the
+ // plugin process, as certain plugins don't handle HTTP failure codes
+ // correctly.
+ if (!defer && client_info.client &&
+ client_info.pending_failure_notification) {
+ // The ClientInfo and the iterator can become invalid due to the call
+ // to DidFail below.
+ WebPluginResourceClient* resource_client = client_info.client;
+ client_info.loader->cancel();
+ clients_.erase(client_index++);
+ resource_client->DidFail();
+
+ // Report that resource loading finished.
+ if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent())
+ devtools_agent->didFinishLoading(resource_id);
+ }
+ break;
+ }
+ client_index++;
+ }
+}
+
+void WebPluginImpl::HandleHttpMultipartResponse(
+ const WebURLResponse& response, WebPluginResourceClient* client) {
+ std::string multipart_boundary;
+ if (!MultipartResponseDelegate::ReadMultipartBoundary(
+ response, &multipart_boundary)) {
+ NOTREACHED();
+ return;
+ }
+
+ if (page_delegate_)
+ page_delegate_->DidStartLoadingForPlugin();
+
+ MultiPartResponseClient* multi_part_response_client =
+ new MultiPartResponseClient(client);
+
+ MultipartResponseDelegate* multi_part_response_handler =
+ new MultipartResponseDelegate(multi_part_response_client, NULL,
+ response,
+ multipart_boundary);
+ multi_part_response_map_[client] = multi_part_response_handler;
+}
+
+bool WebPluginImpl::ReinitializePluginForResponse(
+ WebURLLoader* loader) {
+ WebFrame* webframe = webframe_;
+ if (!webframe)
+ return false;
+
+ WebView* webview = webframe->view();
+ if (!webview)
+ return false;
+
+ WebPluginContainer* container_widget = container_;
+
+ // Destroy the current plugin instance.
+ TearDownPluginInstance(loader);
+
+ container_ = container_widget;
+ webframe_ = webframe;
+
+ std::string actual_mime_type;
+ WebPluginDelegate* plugin_delegate = page_delegate_->CreatePluginDelegate(
+ plugin_url_, mime_type_, &actual_mime_type);
+
+ bool ok = plugin_delegate->Initialize(
+ plugin_url_, arg_names_, arg_values_, this, load_manually_);
+
+ if (!ok) {
+ container_ = NULL;
+ // TODO(iyengar) Should we delete the current plugin instance here?
+ return false;
+ }
+
+ mime_type_ = actual_mime_type;
+ delegate_ = plugin_delegate;
+
+ // Force a geometry update to occur to ensure that the plugin becomes
+ // visible.
+ container_->reportGeometry();
+
+ // The plugin move sequences accumulated via DidMove are sent to the browser
+ // whenever the renderer paints. Force a paint here to ensure that changes
+ // to the plugin window are propagated to the browser.
+ container_->invalidate();
+ return true;
+}
+
+void WebPluginImpl::TearDownPluginInstance(
+ WebURLLoader* loader_to_ignore) {
+ // The container maintains a list of JSObjects which are related to this
+ // plugin. Tell the frame we're gone so that it can invalidate all of
+ // those sub JSObjects.
+ if (container_)
+ container_->clearScriptObjects();
+
+ if (delegate_) {
+ // Call PluginDestroyed() first to prevent the plugin from calling us back
+ // in the middle of tearing down the render tree.
+ delegate_->PluginDestroyed();
+ delegate_ = NULL;
+ }
+
+ // Cancel any pending requests because otherwise this deleted object will
+ // be called by the ResourceDispatcher.
+ std::vector<ClientInfo>::iterator client_index = clients_.begin();
+ while (client_index != clients_.end()) {
+ ClientInfo& client_info = *client_index;
+
+ if (loader_to_ignore == client_info.loader) {
+ client_index++;
+ continue;
+ }
+
+ if (client_info.loader.get())
+ client_info.loader->cancel();
+
+ client_index = clients_.erase(client_index);
+ }
+
+ // This needs to be called now and not in the destructor since the
+ // webframe_ might not be valid anymore.
+ webframe_ = NULL;
+ method_factory_.RevokeAll();
+}
+
+void WebPluginImpl::SetReferrer(WebKit::WebURLRequest* request,
+ Referrer referrer_flag) {
+ switch (referrer_flag) {
+ case DOCUMENT_URL:
+ webframe_->setReferrerForRequest(*request, GURL());
+ break;
+
+ case PLUGIN_SRC:
+ webframe_->setReferrerForRequest(*request, plugin_url_);
+ break;
+
+ default:
+ break;
+ }
+}
+
+WebDevToolsAgent* WebPluginImpl::GetDevToolsAgent() {
+ if (!webframe_)
+ return NULL;
+ WebView* view = webframe_->view();
+ if (!view)
+ return NULL;
+ return view->devToolsAgent();
+}
+
+} // namespace webkit_glue
diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h
new file mode 100644
index 0000000..fd6ea25
--- /dev/null
+++ b/webkit/glue/plugins/webplugin_impl.h
@@ -0,0 +1,321 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_WEBPLUGIN_IMPL_H_
+#define WEBKIT_GLUE_WEBPLUGIN_IMPL_H_
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/linked_ptr.h"
+#include "base/task.h"
+#include "base/weak_ptr.h"
+#include "gfx/native_widget_types.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
+#include "webkit/glue/plugins/webplugin.h"
+
+class WebViewDelegate;
+
+namespace WebKit {
+class WebDevToolsAgent;
+class WebFrame;
+class WebPluginContainer;
+class WebURLResponse;
+class WebURLLoader;
+class WebURLRequest;
+}
+
+namespace webkit_glue {
+
+class MultipartResponseDelegate;
+class WebPluginDelegate;
+class WebPluginPageDelegate;
+
+// This is the WebKit side of the plugin implementation that forwards calls,
+// after changing out of WebCore types, to a delegate. The delegate may
+// be in a different process.
+class WebPluginImpl : public WebPlugin,
+ public WebKit::WebPlugin,
+ public WebKit::WebURLLoaderClient {
+ public:
+ WebPluginImpl(
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params,
+ const base::WeakPtr<WebPluginPageDelegate>& page_delegate);
+ virtual ~WebPluginImpl();
+
+ // Helper function for sorting post data.
+ static bool SetPostData(WebKit::WebURLRequest* request,
+ const char* buf,
+ uint32 length);
+
+ virtual WebPluginDelegate* delegate() { return delegate_; }
+
+ private:
+ // WebKit::WebPlugin methods:
+ virtual bool initialize(
+ WebKit::WebPluginContainer* container);
+ virtual void destroy();
+ virtual NPObject* scriptableObject();
+ virtual void paint(
+ WebKit::WebCanvas* canvas, const WebKit::WebRect& paint_rect);
+ virtual void updateGeometry(
+ const WebKit::WebRect& frame_rect, const WebKit::WebRect& clip_rect,
+ const WebKit::WebVector<WebKit::WebRect>& cut_outs, bool is_visible);
+ virtual void updateFocus(bool focused);
+ virtual void updateVisibility(bool visible);
+ virtual bool acceptsInputEvents();
+ virtual bool handleInputEvent(
+ const WebKit::WebInputEvent& event, WebKit::WebCursorInfo& cursor_info);
+ virtual void didReceiveResponse(const WebKit::WebURLResponse& response);
+ virtual void didReceiveData(const char* data, int data_length);
+ virtual void didFinishLoading();
+ virtual void didFailLoading(const WebKit::WebURLError& error);
+ virtual void didFinishLoadingFrameRequest(
+ const WebKit::WebURL& url, void* notify_data);
+ virtual void didFailLoadingFrameRequest(
+ const WebKit::WebURL& url, void* notify_data,
+ const WebKit::WebURLError& error);
+ virtual bool supportsPaginatedPrint();
+ virtual int printBegin(const WebKit::WebRect& printable_area,
+ int printer_dpi);
+ virtual bool printPage(int page_number, WebKit::WebCanvas* canvas);
+ virtual void printEnd();
+
+ // WebPlugin implementation:
+ void SetWindow(gfx::PluginWindowHandle window);
+
+ // Whether input events should be sent to the delegate.
+ virtual void SetAcceptsInputEvents(bool accepts) {
+ accepts_input_events_ = accepts;
+ }
+
+ void WillDestroyWindow(gfx::PluginWindowHandle window);
+#if defined(OS_WIN)
+ void SetWindowlessPumpEvent(HANDLE pump_messages_event) { }
+#endif
+
+ // Given a (maybe partial) url, completes using the base url.
+ GURL CompleteURL(const char* url);
+
+ // Executes the script passed in. The notify_needed and notify_data arguments
+ // are passed in by the plugin process. These indicate whether the plugin
+ // expects a notification on script execution. We pass them back to the
+ // plugin as is. This avoids having to track the notification arguments in
+ // the plugin process.
+ bool ExecuteScript(const std::string& url, const std::wstring& script,
+ bool notify_needed, intptr_t notify_data,
+ bool popups_allowed);
+
+ enum RoutingStatus {
+ ROUTED,
+ NOT_ROUTED,
+ INVALID_URL,
+ GENERAL_FAILURE
+ };
+
+ // Determines the referrer value sent along with outgoing HTTP requests
+ // issued by plugins.
+ enum Referrer {
+ PLUGIN_SRC,
+ DOCUMENT_URL,
+ NO_REFERRER
+ };
+
+ // Given a download request, check if we need to route the output to a frame.
+ // Returns ROUTED if the load is done and routed to a frame, NOT_ROUTED or
+ // corresponding error codes otherwise.
+ RoutingStatus RouteToFrame(const char* url,
+ bool is_javascript_url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ Referrer referrer_flag);
+
+ // Cancels a pending request.
+ void CancelResource(unsigned long id);
+
+ // Returns the next avaiable resource id. Returns 0 if the operation fails.
+ // It may fail if the page has already been closed.
+ unsigned long GetNextResourceId();
+
+ // Initiates HTTP GET/POST requests.
+ // Returns true on success.
+ bool InitiateHTTPRequest(unsigned long resource_id,
+ WebPluginResourceClient* client,
+ const GURL& url,
+ const char* method,
+ const char* buf,
+ int len,
+ const char* range_info,
+ Referrer referrer_flag);
+
+ gfx::Rect GetWindowClipRect(const gfx::Rect& rect);
+
+ NPObject* GetWindowScriptNPObject();
+ NPObject* GetPluginElement();
+
+ void SetCookie(const GURL& url,
+ const GURL& first_party_for_cookies,
+ const std::string& cookie);
+ std::string GetCookies(const GURL& url,
+ const GURL& first_party_for_cookies);
+
+ void ShowModalHTMLDialog(const GURL& url, int width, int height,
+ const std::string& json_arguments,
+ std::string* json_retval);
+ void OnMissingPluginStatus(int status);
+ void Invalidate();
+ void InvalidateRect(const gfx::Rect& rect);
+
+ // Sets the actual Widget for the plugin.
+ void SetContainer(WebKit::WebPluginContainer* container);
+
+ // Destroys the plugin instance.
+ // The response_handle_to_ignore parameter if not NULL indicates the
+ // resource handle to be left valid during plugin shutdown.
+ void TearDownPluginInstance(WebKit::WebURLLoader* loader_to_ignore);
+
+ // WebURLLoaderClient implementation. We implement this interface in the
+ // renderer process, and then use the simple WebPluginResourceClient interface
+ // to relay the callbacks to the plugin.
+ virtual void willSendRequest(WebKit::WebURLLoader* loader,
+ WebKit::WebURLRequest& request,
+ const WebKit::WebURLResponse&);
+ virtual void didSendData(WebKit::WebURLLoader* loader,
+ unsigned long long bytes_sent,
+ unsigned long long total_bytes_to_be_sent);
+ virtual void didReceiveResponse(WebKit::WebURLLoader* loader,
+ const WebKit::WebURLResponse& response);
+ virtual void didReceiveData(WebKit::WebURLLoader* loader, const char *buffer,
+ int length);
+ virtual void didFinishLoading(WebKit::WebURLLoader* loader);
+ virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError&);
+
+ // Helper function to remove the stored information about a resource
+ // request given its index in m_clients.
+ void RemoveClient(size_t i);
+
+ // Helper function to remove the stored information about a resource
+ // request given a handle.
+ void RemoveClient(WebKit::WebURLLoader* loader);
+
+ void HandleURLRequest(const char* url,
+ const char *method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ bool popups_allowed);
+
+ void CancelDocumentLoad();
+
+ void InitiateHTTPRangeRequest(
+ const char* url, const char* range_info, int pending_request_id);
+
+ void SetDeferResourceLoading(unsigned long resource_id, bool defer);
+
+ // Ignore in-process plugins mode for this flag.
+ bool IsOffTheRecord() { return false; }
+
+ // Handles HTTP multipart responses, i.e. responses received with a HTTP
+ // status code of 206.
+ void HandleHttpMultipartResponse(const WebKit::WebURLResponse& response,
+ WebPluginResourceClient* client);
+
+ void HandleURLRequestInternal(const char* url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ int notify_id,
+ bool popups_allowed,
+ Referrer referrer_flag);
+
+ // Tears down the existing plugin instance and creates a new plugin instance
+ // to handle the response identified by the loader parameter.
+ bool ReinitializePluginForResponse(WebKit::WebURLLoader* loader);
+
+ // Delayed task for downloading the plugin source URL.
+ void OnDownloadPluginSrcUrl();
+
+ struct ClientInfo {
+ unsigned long id;
+ WebPluginResourceClient* client;
+ WebKit::WebURLRequest request;
+ bool pending_failure_notification;
+ linked_ptr<WebKit::WebURLLoader> loader;
+ };
+
+ // Helper functions
+ WebPluginResourceClient* GetClientFromLoader(WebKit::WebURLLoader* loader);
+ ClientInfo* GetClientInfoFromLoader(WebKit::WebURLLoader* loader);
+
+ // Helper function to set the referrer on the request passed in.
+ void SetReferrer(WebKit::WebURLRequest* request, Referrer referrer_flag);
+
+ // Returns DevToolsAgent for the frame or 0.
+ WebKit::WebDevToolsAgent* GetDevToolsAgent();
+
+ std::vector<ClientInfo> clients_;
+
+ bool windowless_;
+ gfx::PluginWindowHandle window_;
+ bool accepts_input_events_;
+ base::WeakPtr<WebPluginPageDelegate> page_delegate_;
+ WebKit::WebFrame* webframe_;
+
+ WebPluginDelegate* delegate_;
+
+ // This is just a weak reference.
+ WebKit::WebPluginContainer* container_;
+
+ typedef std::map<WebPluginResourceClient*,
+ webkit_glue::MultipartResponseDelegate*>
+ MultiPartResponseHandlerMap;
+ // Tracks HTTP multipart response handlers instantiated for
+ // a WebPluginResourceClient instance.
+ MultiPartResponseHandlerMap multi_part_response_map_;
+
+ // The plugin source URL.
+ GURL plugin_url_;
+
+ // Indicates if the download would be initiated by the plugin or us.
+ bool load_manually_;
+
+ // Indicates if this is the first geometry update received by the plugin.
+ bool first_geometry_update_;
+
+ // Set to true if the next response error should be ignored.
+ bool ignore_response_error_;
+
+ // The current plugin geometry and clip rectangle.
+ WebPluginGeometry geometry_;
+
+ // The mime type of the plugin.
+ std::string mime_type_;
+
+ // Holds the list of argument names and values passed to the plugin. We keep
+ // these so that we can re-initialize the plugin if we need to.
+ std::vector<std::string> arg_names_;
+ std::vector<std::string> arg_values_;
+
+ ScopedRunnableMethodFactory<WebPluginImpl> method_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebPluginImpl);
+};
+
+} // namespace webkit_glue
+
+#endif // #ifndef WEBKIT_GLUE_WEBPLUGIN_IMPL_H_
diff --git a/webkit/glue/plugins/webplugin_impl_unittest.cc b/webkit/glue/plugins/webplugin_impl_unittest.cc
new file mode 100644
index 0000000..e70e39a
--- /dev/null
+++ b/webkit/glue/plugins/webplugin_impl_unittest.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
+#include "webkit/glue/plugins/webplugin_impl.h"
+
+using WebKit::WebHTTPBody;
+using WebKit::WebString;
+using WebKit::WebURLRequest;
+using webkit_glue::WebPluginImpl;
+
+namespace {
+
+class WebPluginImplTest : public testing::Test {
+};
+
+}
+
+static std::string GetHeader(const WebURLRequest& request, const char* name) {
+ std::string result;
+ TrimWhitespace(
+ request.httpHeaderField(WebString::fromUTF8(name)).utf8(),
+ TRIM_ALL,
+ &result);
+ return result;
+}
+
+static std::string GetBodyText(const WebURLRequest& request) {
+ const WebHTTPBody& body = request.httpBody();
+ if (body.isNull())
+ return std::string();
+
+ std::string result;
+ size_t i = 0;
+ WebHTTPBody::Element element;
+ while (body.elementAt(i++, element)) {
+ if (element.type == WebHTTPBody::Element::TypeData) {
+ result.append(element.data.data(), element.data.size());
+ } else {
+ NOTREACHED() << "unexpected element type encountered!";
+ }
+ }
+ return result;
+}
+
+// The Host functions for NPN_PostURL and NPN_PostURLNotify
+// need to parse out some HTTP headers. Make sure it works
+// with the following tests
+
+TEST(WebPluginImplTest, PostParserSimple) {
+ // Test a simple case with headers & data
+ const char *ex1 = "foo: bar\nContent-length: 10\n\nabcdefghij";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
+ EXPECT_EQ("abcdefghij", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserLongHeader) {
+ // Test a simple case with long headers
+ const char *ex1 = "foo: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n\nabcdefghij";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ(100U, GetHeader(request, "foo").length());
+}
+
+TEST(WebPluginImplTest, PostParserManyHeaders) {
+ // Test a simple case with long headers
+ const char *ex1 = "h1:h1\nh2:h2\nh3:h3\nh4:h4\nh5:h5\nh6:h6\nh7:h7\nh8:h8\nh9:h9\nh10:h10\n\nbody";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("h1", GetHeader(request, "h1"));
+ EXPECT_EQ("h2", GetHeader(request, "h2"));
+ EXPECT_EQ("h3", GetHeader(request, "h3"));
+ EXPECT_EQ("h4", GetHeader(request, "h4"));
+ EXPECT_EQ("h5", GetHeader(request, "h5"));
+ EXPECT_EQ("h6", GetHeader(request, "h6"));
+ EXPECT_EQ("h7", GetHeader(request, "h7"));
+ EXPECT_EQ("h8", GetHeader(request, "h8"));
+ EXPECT_EQ("h9", GetHeader(request, "h9"));
+ EXPECT_EQ("h10", GetHeader(request, "h10"));
+ EXPECT_EQ("body", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserDuplicateHeaders) {
+ // Test a simple case with long headers
+ // What value gets returned doesn't really matter. It shouldn't error
+ // out.
+ const char *ex1 = "h1:h1\nh1:h2\n\nbody";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+}
+
+TEST(WebPluginImplTest, PostParserNoHeaders) {
+ // Test a simple case with no headers but with data
+ const char *ex1 = "\nabcdefghij";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ(0U, GetHeader(request, "foo").length());
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
+ EXPECT_EQ("abcdefghij", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserNoBody) {
+ // Test a simple case with headers and no body
+ const char *ex1 = "Foo:bar\n\n";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
+ EXPECT_EQ(0U, GetBodyText(request).length());
+}
+
+TEST(WebPluginImplTest, PostParserBodyWithNewLines) {
+ // Test a simple case with headers and no body
+ const char *ex1 = "Foo:bar\n\n\n\nabcdefg\n\nabcdefg";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ(GetBodyText(request), "\n\nabcdefg\n\nabcdefg");
+}
+
+TEST(WebPluginImplTest, PostParserErrorNoBody) {
+ // Test with headers and no body
+ const char *ex1 = "Foo:bar\n";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+}
+
+TEST(WebPluginImplTest, PostParserErrorEmpty) {
+ // Test with an empty string
+ const char *ex1 = "";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+}
+
+TEST(WebPluginImplTest, PostParserEmptyName) {
+ // Test an error case with an empty header name field
+ const char *ex1 = "foo:bar\n:blat\n\nbody";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ("body", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserEmptyValue) {
+ // Test an error case with an empty value field
+ const char *ex1 = "foo:bar\nbar:\n\nbody";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ("body", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserCRLF) {
+ // Test an error case with an empty value field
+ const char *ex1 = "foo: bar\r\nbar:\r\n\r\nbody\r\n\r\nbody2";
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ static_cast<uint32>(strlen(ex1)));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ("body\r\n\r\nbody2", GetBodyText(request));
+}
+
+TEST(WebPluginImplTest, PostParserBodyWithBinaryData) {
+ // Test a simple case with headers and binary data.
+ char ex1[33] = "foo: bar\nContent-length: 10\n\n";
+ unsigned int binary_data = 0xFFFFFFF0;
+ memcpy(ex1 + strlen("foo: bar\nContent-length: 10\n\n"), &binary_data,
+ sizeof(binary_data));
+
+ WebURLRequest request;
+ request.initialize();
+ bool rv = WebPluginImpl::SetPostData(&request, ex1,
+ sizeof(ex1)/sizeof(ex1[0]));
+ EXPECT_EQ(true, rv);
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
+
+ std::string body = GetBodyText(request);
+
+ EXPECT_EQ(0xF0, (unsigned char)body[0]);
+ EXPECT_EQ(0xFF, (unsigned char)body[1]);
+ EXPECT_EQ(0xFF, (unsigned char)body[2]);
+ EXPECT_EQ(0xFF, (unsigned char)body[3]);
+}
diff --git a/webkit/glue/plugins/webplugin_page_delegate.h b/webkit/glue/plugins/webplugin_page_delegate.h
new file mode 100644
index 0000000..8bc5723
--- /dev/null
+++ b/webkit/glue/plugins/webplugin_page_delegate.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_WEBPLUGIN_PAGE_DELEGATE_
+#define WEBKIT_GLUE_WEBPLUGIN_PAGE_DELEGATE_
+
+#include "gfx/native_widget_types.h"
+
+class GURL;
+
+namespace WebKit {
+class WebCookieJar;
+}
+
+namespace webkit_glue {
+
+class WebPluginDelegate;
+struct WebPluginGeometry;
+
+// Used by the WebPlugin to communicate back to the containing page.
+class WebPluginPageDelegate {
+ public:
+ // This method is called to create a WebPluginDelegate implementation when a
+ // new plugin is instanced. See webkit_glue::CreateWebPluginDelegateHelper
+ // for a default WebPluginDelegate implementation.
+ virtual WebPluginDelegate* CreatePluginDelegate(
+ const GURL& url,
+ const std::string& mime_type,
+ std::string* actual_mime_type) = 0;
+
+ // Called when a windowed plugin is created.
+ // Lets the view delegate create anything it is using to wrap the plugin.
+ virtual void CreatedPluginWindow(
+ gfx::PluginWindowHandle handle) = 0;
+
+ // Called when a windowed plugin is closing.
+ // Lets the view delegate shut down anything it is using to wrap the plugin.
+ virtual void WillDestroyPluginWindow(
+ gfx::PluginWindowHandle handle) = 0;
+
+ // Keeps track of the necessary window move for a plugin window that resulted
+ // from a scroll operation. That way, all plugin windows can be moved at the
+ // same time as each other and the page.
+ virtual void DidMovePlugin(
+ const WebPluginGeometry& move) = 0;
+
+ // Notifies the parent view that a load has begun.
+ virtual void DidStartLoadingForPlugin() = 0;
+
+ // Notifies the parent view that all loads are finished.
+ virtual void DidStopLoadingForPlugin() = 0;
+
+ // Asks the browser to show a modal HTML dialog. The dialog is passed the
+ // given arguments as a JSON string, and returns its result as a JSON string
+ // through json_retval.
+ virtual void ShowModalHTMLDialogForPlugin(
+ const GURL& url,
+ const gfx::Size& size,
+ const std::string& json_arguments,
+ std::string* json_retval) = 0;
+
+ // The WebCookieJar to use for this plugin.
+ virtual WebKit::WebCookieJar* GetCookieJar() = 0;
+};
+
+} // namespace webkit_glue
+
+#endif // WEBKIT_GLUE_WEBPLUGIN_PAGE_DELEGATE_H_
diff --git a/webkit/glue/plugins/webplugininfo.h b/webkit/glue/plugins/webplugininfo.h
new file mode 100644
index 0000000..21f34df
--- /dev/null
+++ b/webkit/glue/plugins/webplugininfo.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_WEBPLUGININFO_H_
+#define WEBKIT_GLUE_WEBPLUGININFO_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+
+// Describes a mime type entry for a plugin.
+struct WebPluginMimeType {
+ // The name of the mime type (e.g., "application/x-shockwave-flash").
+ std::string mime_type;
+
+ // A list of all the file extensions for this mime type.
+ std::vector<std::string> file_extensions;
+
+ // Description of the mime type.
+ std::wstring description;
+};
+
+// Describes an available NPAPI plugin.
+struct WebPluginInfo {
+ // The name of the plugin (i.e. Flash).
+ std::wstring name;
+
+ // The path to the plugin file (DLL/bundle/library).
+ FilePath path;
+
+ // The version number of the plugin file (may be OS-specific)
+ std::wstring version;
+
+ // A description of the plugin that we get from its version info.
+ std::wstring desc;
+
+ // A list of all the mime types that this plugin supports.
+ std::vector<WebPluginMimeType> mime_types;
+
+ // Whether the plugin is enabled.
+ bool enabled;
+};
+
+#endif // WEBKIT_GLUE_WEBPLUGININFO_H_