libcef: Update due to underlying chromium changes.

- External plugin loading support is now provided by webkit/glue/plugins so the libcef/plugins directory has been eliminated, with related changes.
- Modify the CefPluginInfo structure to use a more friendly data organization format.
- Remove CefUnregisterPlugin() as it is no longer functional.
- WebViewDelegate::ShowContextMenu() now receives the menu type as a bit-masked flag, so adjust the API accordingly.
- WebViewDelegate::GetContainingView() now returns a gfx::NativeViewId instead of a gfx::NativeView.
- Modify BrowserRequestContext because GetUserAgent() is now a virtual method of URLRequestContext.
- The data buffer in RequestProxy is now a net::IOBuffer.
- Add webkit_glue::GetScreenInfo().

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@10 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2009-01-29 16:36:37 +00:00
parent 1b6fa403ab
commit 73027bb5a9
32 changed files with 139 additions and 4060 deletions

View File

@ -14,3 +14,4 @@ Date | CEF Revision | Chromium Revision
2009-01-14 | /trunk@6 | /trunk@8029 2009-01-14 | /trunk@6 | /trunk@8029
2009-01-21 | /trunk@8 | /trunk@8386 2009-01-21 | /trunk@8 | /trunk@8386
2009-01-27 | /trunk@9 | /trunk@8751 2009-01-27 | /trunk@9 | /trunk@8751
2009-01-29 | /trunk@10 | /trunk@8875

View File

@ -401,23 +401,10 @@ public:
std::wstring& mimeType, std::wstring& mimeType,
int loadFlags) =0; int loadFlags) =0;
// Various context menu types supported by chrome.
enum MenuType
{
MENUTYPE_NONE = 0,
MENUTYPE_PAGE,
MENUTYPE_FRAME,
MENUTYPE_LINK,
MENUTYPE_IMAGE,
MENUTYPE_IMAGE_LINK,
MENUTYPE_SELECTION,
MENUTYPE_EDITABLE
};
// Structure representing menu information // Structure representing menu information
struct MenuInfo struct MenuInfo
{ {
MenuType menuType; int typeFlags;
int x; int x;
int y; int y;
std::wstring linkUrl; std::wstring linkUrl;
@ -430,8 +417,28 @@ public:
std::string securityInfo; std::string securityInfo;
}; };
// The MenuInfo typeFlags value will be a combination of the following
enum MenuTypeBits {
// No node is selected
MENUTYPE_NONE = 0x0,
// The top page is selected
MENUTYPE_PAGE = 0x1,
// A subframe page is selected
MENUTYPE_FRAME = 0x2,
// A link is selected
MENUTYPE_LINK = 0x4,
// An image is selected
MENUTYPE_IMAGE = 0x8,
// There is a textual or mixed selection that is selected
MENUTYPE_SELECTION = 0x10,
// An editable element is selected
MENUTYPE_EDITABLE = 0x20,
// A misspelled word is selected
MENUTYPE_MISSPELLED_WORD = 0x40,
};
// The MenuInfo editFlags value will be a combination of the following // The MenuInfo editFlags value will be a combination of the following
enum MenuCapability enum MenuCapabilityBits
{ {
CAN_DO_NONE = 0x0, CAN_DO_NONE = 0x0,
CAN_UNDO = 0x1, CAN_UNDO = 0x1,

View File

@ -32,6 +32,7 @@
#define _CEF_PLUGIN_H #define _CEF_PLUGIN_H
#include <string> #include <string>
#include <vector>
#include "webkit/glue/plugins/nphostapi.h" #include "webkit/glue/plugins/nphostapi.h"
#include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npapi.h"
@ -42,35 +43,43 @@
// See https://developer.mozilla.org/En/Gecko_Plugin_API_Reference for complete // See https://developer.mozilla.org/En/Gecko_Plugin_API_Reference for complete
// documentation on how to use the Netscape Plugin API. // documentation on how to use the Netscape Plugin API.
// This structure fully describes a plugin. // This structure describes a mime type entry for a plugin.
struct CefPluginVersionInfo { struct CefPluginMimeType {
// Unique name used to identify a plugin. The unique name is used in place // The actual mime type.
// of the file path that would be available with normal plugin DLLs. std::wstring mime_type;
std::wstring unique_name;
std::wstring product_name; // A list of all the file extensions for this mime type.
std::vector<std::wstring> file_extensions;
// Description of the mime type.
std::wstring description; std::wstring description;
std::wstring version;
// List of supported mime type values, delimited with a pipe (|) character.
std::wstring mime_types;
// List of supported file extensions, delimited with a pipe (|) character.
std::wstring file_extensions;
// List of descriptions for the file extensions, delimited with a pipe (|)
// character.
std::wstring file_open_names;
}; };
// This structure provides version information and entry point functions. // This structure provides attribute information and entry point functions for
// a plugin.
struct CefPluginInfo { struct CefPluginInfo {
CefPluginVersionInfo version_info; // The unique name that identifies the plugin.
std::wstring unique_name;
// The friendly display name of the plugin.
std::wstring display_name;
// The version string of the plugin.
std::wstring version;
// A description of the plugin.
std::wstring description;
// A list of all the mime types that this plugin supports.
std::vector<CefPluginMimeType> mime_types;
// Entry point function pointers.
NP_GetEntryPointsFunc np_getentrypoints; NP_GetEntryPointsFunc np_getentrypoints;
NP_InitializeFunc np_initialize; NP_InitializeFunc np_initialize;
NP_ShutdownFunc np_shutdown; NP_ShutdownFunc np_shutdown;
}; };
// Register the plugin with the system. // Register a plugin with the system.
bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info); bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info);
// Unregister the plugin with the system.
bool CefUnregisterPlugin(const struct CefPluginInfo& plugin_info);
#endif // _CEF_PLUGIN_H #endif // _CEF_PLUGIN_H

View File

@ -27,8 +27,6 @@ void BrowserRequestContext::Init(
bool no_proxy) { bool no_proxy) {
cookie_store_ = new net::CookieMonster(); cookie_store_ = new net::CookieMonster();
user_agent_ = webkit_glue::GetUserAgent();
// hard-code A-L and A-C for test shells // hard-code A-L and A-C for test shells
accept_language_ = "en-us,en"; accept_language_ = "en-us,en";
accept_charset_ = "iso-8859-1,*,utf-8"; accept_charset_ = "iso-8859-1,*,utf-8";
@ -53,3 +51,7 @@ BrowserRequestContext::~BrowserRequestContext() {
delete proxy_service_; delete proxy_service_;
} }
const std::string& BrowserRequestContext::GetUserAgent(
const GURL& url) const {
return webkit_glue::GetUserAgent(url);
}

View File

@ -23,6 +23,8 @@ class BrowserRequestContext : public URLRequestContext {
~BrowserRequestContext(); ~BrowserRequestContext();
virtual const std::string& GetUserAgent(const GURL& url) const;
private: private:
void Init(const std::wstring& cache_path, net::HttpCache::Mode cache_mode, void Init(const std::wstring& cache_path, net::HttpCache::Mode cache_mode,
bool no_proxy); bool no_proxy);

View File

@ -43,6 +43,7 @@
#include "base/thread.h" #include "base/thread.h"
#include "base/waitable_event.h" #include "base/waitable_event.h"
#include "net/base/cookie_monster.h" #include "net/base/cookie_monster.h"
#include "net/base/io_buffer.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
#include "net/base/upload_data.h" #include "net/base/upload_data.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
@ -112,7 +113,7 @@ class RequestProxy : public URLRequest::Delegate,
public: public:
// Takes ownership of the params. // Takes ownership of the params.
RequestProxy(CefRefPtr<CefBrowser> browser) RequestProxy(CefRefPtr<CefBrowser> browser)
: browser_(browser) : browser_(browser), buf_(new net::IOBuffer(kDataSize))
{ {
} }
@ -164,7 +165,7 @@ class RequestProxy : public URLRequest::Delegate,
// Make a local copy of buf_, since AsyncReadData reuses it. // Make a local copy of buf_, since AsyncReadData reuses it.
scoped_array<char> buf_copy(new char[bytes_read]); scoped_array<char> buf_copy(new char[bytes_read]);
memcpy(buf_copy.get(), buf_, bytes_read); memcpy(buf_copy.get(), buf_->data(), bytes_read);
// Continue reading more data into buf_ // Continue reading more data into buf_
// Note: Doing this before notifying our peer ensures our load events get // Note: Doing this before notifying our peer ensures our load events get
@ -282,7 +283,7 @@ class RequestProxy : public URLRequest::Delegate,
void AsyncReadData() { void AsyncReadData() {
if(resource_stream_.get()) { if(resource_stream_.get()) {
// Read from the handler-provided resource stream // Read from the handler-provided resource stream
int bytes_read = resource_stream_->Read(buf_, 1, sizeof(buf_)); int bytes_read = resource_stream_->Read(buf_->data(), 1, kDataSize);
if(bytes_read > 0) { if(bytes_read > 0) {
OnReceivedData(bytes_read); OnReceivedData(bytes_read);
} else { } else {
@ -297,7 +298,7 @@ class RequestProxy : public URLRequest::Delegate,
if (request_->status().is_success()) { if (request_->status().is_success()) {
int bytes_read; int bytes_read;
if (request_->Read(buf_, sizeof(buf_), &bytes_read) && bytes_read) { if (request_->Read(buf_, kDataSize, &bytes_read) && bytes_read) {
OnReceivedData(bytes_read); OnReceivedData(bytes_read);
} else if (!request_->status().is_io_pending()) { } else if (!request_->status().is_io_pending()) {
Done(); Done();
@ -388,7 +389,7 @@ class RequestProxy : public URLRequest::Delegate,
static const int kDataSize = 16*1024; static const int kDataSize = 16*1024;
// read buffer for async IO // read buffer for async IO
char buf_[kDataSize]; scoped_refptr<net::IOBuffer> buf_;
CefRefPtr<CefBrowser> browser_; CefRefPtr<CefBrowser> browser_;
@ -428,7 +429,7 @@ class SyncRequestProxy : public RequestProxy {
} }
virtual void OnReceivedData(int bytes_read) { virtual void OnReceivedData(int bytes_read) {
result_->data.append(buf_, bytes_read); result_->data.append(buf_->data(), bytes_read);
AsyncReadData(); // read more (may recurse) AsyncReadData(); // read more (may recurse)
} }

View File

@ -167,4 +167,8 @@ bool IsLinkVisited(uint64 link_hash) {
return false; return false;
} }
ScreenInfo GetScreenInfo(gfx::NativeViewId window) {
return GetScreenInfoHelper(gfx::NativeViewFromId(window));
}
} // namespace webkit_glue } // namespace webkit_glue

View File

@ -5,7 +5,6 @@
#include "precompiled_libcef.h" #include "precompiled_libcef.h"
#include "browser_webkit_glue.h" #include "browser_webkit_glue.h"
#include "plugins/browser_plugin_list.h"
#include <atlcore.h> #include <atlcore.h>
#include <atlbase.h> #include <atlbase.h>
@ -47,7 +46,6 @@ HCURSOR LoadCursor(int cursor_id) {
bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
NPAPI::BrowserPluginList::Singleton()->GetPlugins(refresh, plugins);
return true; return true;
} }

View File

@ -17,6 +17,7 @@
#include "base/file_util.h" #include "base/file_util.h"
#include "base/gfx/gdi_util.h" #include "base/gfx/gdi_util.h"
#include "base/gfx/point.h" #include "base/gfx/point.h"
#include "base/gfx/native_widget_types.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/trace_event.h" #include "base/trace_event.h"
@ -469,9 +470,9 @@ void BrowserWebViewDelegate::SetUserStyleSheetLocation(const GURL& location) {
// WebWidgetDelegate --------------------------------------------------------- // WebWidgetDelegate ---------------------------------------------------------
gfx::NativeView BrowserWebViewDelegate::GetContainingView(WebWidget* webwidget) { gfx::NativeViewId BrowserWebViewDelegate::GetContainingView(WebWidget* webwidget) {
if (WebWidgetHost* host = GetHostForWidget(webwidget)) if (WebWidgetHost* host = GetHostForWidget(webwidget))
return host->window_handle(); return gfx::IdFromNativeView(host->window_handle());
return NULL; return NULL;
} }

View File

@ -78,7 +78,7 @@ class BrowserWebViewDelegate : public base::RefCounted<BrowserWebViewDelegate>,
virtual void StartDragging(WebView* webview, virtual void StartDragging(WebView* webview,
const WebDropData& drop_data); const WebDropData& drop_data);
virtual void ShowContextMenu(WebView* webview, virtual void ShowContextMenu(WebView* webview,
ContextNode::Type type, ContextNode in_node,
int x, int x,
int y, int y,
const GURL& link_url, const GURL& link_url,
@ -178,7 +178,7 @@ class BrowserWebViewDelegate : public base::RefCounted<BrowserWebViewDelegate>,
virtual int GetHistoryForwardListCount(); virtual int GetHistoryForwardListCount();
// WebWidgetDelegate // WebWidgetDelegate
virtual gfx::NativeView GetContainingView(WebWidget* webwidget); virtual gfx::NativeViewId GetContainingView(WebWidget* webwidget);
virtual void DidInvalidateRect(WebWidget* webwidget, const gfx::Rect& rect); virtual void DidInvalidateRect(WebWidget* webwidget, const gfx::Rect& rect);
virtual void DidScrollRect(WebWidget* webwidget, int dx, int dy, virtual void DidScrollRect(WebWidget* webwidget, int dx, int dy,
const gfx::Rect& clip_rect); const gfx::Rect& clip_rect);

View File

@ -14,8 +14,6 @@
#include "browser_navigation_controller.h" #include "browser_navigation_controller.h"
#include "browser_impl.h" #include "browser_impl.h"
#include "context.h" #include "context.h"
#include "plugins/browser_webplugin_delegate_impl.h"
#include "plugins/browser_plugin_list.h"
#include <objidl.h> #include <objidl.h>
#include <shlobj.h> #include <shlobj.h>
@ -50,7 +48,7 @@ WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
const std::string& mime_type, const std::string& mime_type,
const std::string& clsid, const std::string& clsid,
std::string* actual_mime_type) { std::string* actual_mime_type) {
HWND hwnd = GetContainingView(webview); HWND hwnd = gfx::NativeViewFromId(GetContainingView(webview));
if (!hwnd) if (!hwnd)
return NULL; return NULL;
@ -67,20 +65,6 @@ WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
return WebPluginDelegateImpl::Create(info.path, mime_type, hwnd); return WebPluginDelegateImpl::Create(info.path, mime_type, hwnd);
} }
// second, look for plugins using the embedded plugin list
CefPluginInfo plugin_info;
if (NPAPI::BrowserPluginList::Singleton()->GetPluginInfo(url, mime_type,
clsid,
allow_wildcard,
&plugin_info,
actual_mime_type)) {
if (actual_mime_type && !actual_mime_type->empty())
return BrowserWebPluginDelegateImpl::Create(plugin_info,
*actual_mime_type, hwnd);
else
return BrowserWebPluginDelegateImpl::Create(plugin_info, mime_type, hwnd);
}
return NULL; return NULL;
} }
@ -211,7 +195,7 @@ static void AddMenuSeparator(HMENU menu, int index)
} }
void BrowserWebViewDelegate::ShowContextMenu(WebView* webview, void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
ContextNode::Type type, ContextNode in_node,
int x, int x,
int y, int y,
const GURL& link_url, const GURL& link_url,
@ -244,7 +228,7 @@ void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
if(handler.get()) { if(handler.get()) {
// Gather menu information // Gather menu information
CefHandler::MenuInfo menuInfo; CefHandler::MenuInfo menuInfo;
menuInfo.menuType = static_cast<CefHandler::MenuType>(type); menuInfo.typeFlags = in_node.type;
menuInfo.x = screen_pt.x; menuInfo.x = screen_pt.x;
menuInfo.y = screen_pt.y; menuInfo.y = screen_pt.y;
menuInfo.linkUrl = UTF8ToWide(link_url.spec().c_str()).c_str(); menuInfo.linkUrl = UTF8ToWide(link_url.spec().c_str()).c_str();
@ -263,8 +247,7 @@ void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
} }
// Build the correct default context menu // Build the correct default context menu
switch(type) { if (in_node.type & ContextNode::EDITABLE) {
case ContextNode::EDITABLE:
menu = CreatePopupMenu(); menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_UNDO, L"Undo", AddMenuItem(browser_, menu, -1, CefHandler::ID_UNDO, L"Undo",
!!(edit_flags & ContextNode::CAN_UNDO), label_list); !!(edit_flags & ContextNode::CAN_UNDO), label_list);
@ -282,14 +265,11 @@ void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
AddMenuSeparator(menu, -1); AddMenuSeparator(menu, -1);
AddMenuItem(browser_, menu, -1, CefHandler::ID_SELECTALL, L"Select All", AddMenuItem(browser_, menu, -1, CefHandler::ID_SELECTALL, L"Select All",
!!(edit_flags & ContextNode::CAN_SELECT_ALL), label_list); !!(edit_flags & ContextNode::CAN_SELECT_ALL), label_list);
break; } else if(in_node.type & ContextNode::SELECTION) {
case ContextNode::SELECTION:
menu = CreatePopupMenu(); menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_COPY, L"Copy", AddMenuItem(browser_, menu, -1, CefHandler::ID_COPY, L"Copy",
!!(edit_flags & ContextNode::CAN_COPY), label_list); !!(edit_flags & ContextNode::CAN_COPY), label_list);
break; } else if(in_node.type & (ContextNode::PAGE | ContextNode::FRAME)) {
case ContextNode::PAGE:
case ContextNode::FRAME:
menu = CreatePopupMenu(); menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_NAV_BACK, L"Back", AddMenuItem(browser_, menu, -1, CefHandler::ID_NAV_BACK, L"Back",
browser_->UIT_CanGoBack(), label_list); browser_->UIT_CanGoBack(), label_list);
@ -300,7 +280,6 @@ void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
true, label_list); true, label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_VIEWSOURCE, L"View Source", AddMenuItem(browser_, menu, -1, CefHandler::ID_VIEWSOURCE, L"View Source",
true, label_list); true, label_list);
break;
} }
if(menu) { if(menu) {

View File

@ -8,7 +8,7 @@
#include "browser_impl.h" #include "browser_impl.h"
#include "browser_resource_loader_bridge.h" #include "browser_resource_loader_bridge.h"
#include "browser_request_context.h" #include "browser_request_context.h"
#include "plugins/browser_plugin_list.h" #include "../include/cef_nplugin.h"
#include "base/at_exit.h" #include "base/at_exit.h"
#include "base/command_line.h" #include "base/command_line.h"
@ -19,6 +19,9 @@
#include "base/stats_table.h" #include "base/stats_table.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "net/base/net_module.h" #include "net/base/net_module.h"
#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include <commctrl.h> #include <commctrl.h>
@ -71,29 +74,40 @@ bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info)
void CefContext::UIT_RegisterPlugin(struct CefPluginInfo* plugin_info) void CefContext::UIT_RegisterPlugin(struct CefPluginInfo* plugin_info)
{ {
REQUIRE_UIT(); REQUIRE_UIT();
NPAPI::BrowserPluginList::Singleton()->AddPlugin(*plugin_info);
delete plugin_info;
}
// Unregister the plugin with the system. NPAPI::PluginVersionInfo info;
bool CefUnregisterPlugin(const struct CefPluginInfo& plugin_info)
{
if(!_Context.get())
return false;
CefPluginInfo* pPluginInfo = new CefPluginInfo; info.path = FilePath(plugin_info->unique_name);
*pPluginInfo = plugin_info; info.product_name = plugin_info->display_name;
info.file_description = plugin_info->description;
info.file_version =plugin_info->version;
PostTask(FROM_HERE, NewRunnableMethod(_Context.get(), for(size_t i = 0; i < plugin_info->mime_types.size(); ++i) {
&CefContext::UIT_UnregisterPlugin, pPluginInfo)); if(i > 0) {
info.mime_types += L"|";
info.file_extensions += L"|";
info.type_descriptions += L"|";
}
return true; info.mime_types += plugin_info->mime_types[i].mime_type;
} info.type_descriptions += plugin_info->mime_types[i].description;
for(size_t j = 0;
j < plugin_info->mime_types[i].file_extensions.size(); ++j) {
if(j > 0) {
info.file_extensions += L",";
}
info.file_extensions += plugin_info->mime_types[i].file_extensions[j];
}
}
info.np_getentrypoints = plugin_info->np_getentrypoints;
info.np_initialize = plugin_info->np_initialize;
info.np_shutdown = plugin_info->np_shutdown;
NPAPI::PluginList::RegisterInternalPlugin(info);
NPAPI::PluginList::Singleton()->LoadPlugin(FilePath(info.path));
void CefContext::UIT_UnregisterPlugin(struct CefPluginInfo* plugin_info)
{
REQUIRE_UIT();
NPAPI::BrowserPluginList::Singleton()->RemovePlugin(*plugin_info);
delete plugin_info; delete plugin_info;
} }

View File

@ -197,78 +197,6 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="plugins"
>
<File
RelativePath=".\plugins\browser_mozilla_extensions.cc"
>
</File>
<File
RelativePath=".\plugins\browser_mozilla_extensions.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_instance.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_instance.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_lib.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_lib.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_list.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_list.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_stream.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_stream.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_stream_url.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_stream_url.h"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_stream_win.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_string_stream.cc"
>
</File>
<File
RelativePath=".\plugins\browser_plugin_string_stream.h"
>
</File>
<File
RelativePath=".\plugins\browser_webplugin_delegate_impl.cc"
>
</File>
<File
RelativePath=".\plugins\browser_webplugin_delegate_impl.h"
>
</File>
</Filter>
<File <File
RelativePath=".\browser_drag_delegate.cc" RelativePath=".\browser_drag_delegate.cc"
> >

View File

@ -1,373 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "browser_mozilla_extensions.h"
#include "browser_plugin_instance.h"
#include <algorithm>
#include "base/logging.h"
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_service.h"
#include "net/proxy/proxy_resolver_winhttp.h"
#include "third_party/npapi/bindings/npapi.h"
#include "webkit/glue/webkit_glue.h"
#define QI_SUPPORTS_IID(iid, iface) \
QI_SUPPORTS_IID_(iid, iface::GetIID(), iface)
#define QI_SUPPORTS_IID_(src_iid, iface_iid, iface) \
if (iid.Equals(iface_iid)) { \
AddRef(); \
*result = static_cast<iface*>(this); \
return NS_OK; \
}
namespace NPAPI
{
void BrowserMozillaExtensionApi::DetachFromInstance() {
plugin_instance_ = NULL;
}
bool BrowserMozillaExtensionApi::FindProxyForUrl(const char* url,
std::string* proxy) {
bool result = false;
if ((!url) || (!proxy)) {
NOTREACHED();
return result;
}
scoped_ptr<net::ProxyService> proxy_service(net::ProxyService::Create(NULL));
if (!proxy_service.get()) {
NOTREACHED();
return result;
}
net::ProxyInfo proxy_info;
if (proxy_service->ResolveProxy(GURL(std::string(url)),
&proxy_info,
NULL,
NULL) == net::OK) {
if (!proxy_info.is_direct()) {
std::string winhttp_proxy = proxy_info.proxy_server();
// Winhttp returns proxy in the the following format:
// - HTTP proxy: "111.111.111.111:11"
// -.SOCKS proxy: "socks=111.111.111.111:11"
// - Mixed proxy: "http=111.111.111.111:11; socks=222.222.222.222:22"
//
// We need to translate this into the following format:
// i) "DIRECT" -- no proxy
// ii) "PROXY xxx.xxx.xxx.xxx" -- use proxy
// iii) "SOCKS xxx.xxx.xxx.xxx" -- use SOCKS
// iv) Mixed. e.g. "PROXY 111.111.111.111;PROXY 112.112.112.112",
// "PROXY 111.111.111.111;SOCKS 112.112.112.112"....
StringToLowerASCII(winhttp_proxy);
if (std::string::npos == winhttp_proxy.find('=')) {
// Proxy is in the form: "111.111.111.111:11"
winhttp_proxy.insert(0, "http ");
} else {
// Proxy is in the following form.
// -.SOCKS proxy: "socks=111.111.111.111:11"
// - Mixed proxy: "http=111.111.111.111:11; socks=222.222.222.222:22"
// in this case just replace the '=' with a space
std::replace_if(winhttp_proxy.begin(),
winhttp_proxy.end(),
std::bind2nd(std::equal_to<char>(), '='), ' ');
}
*proxy = winhttp_proxy;
result = true;
}
}
return result;
}
// nsISupports implementation
NS_IMETHODIMP BrowserMozillaExtensionApi::QueryInterface(REFNSIID iid,
void** result) {
static const nsIID knsISupportsIID = NS_ISUPPORTS_IID;
QI_SUPPORTS_IID_(iid, knsISupportsIID, nsIServiceManager)
QI_SUPPORTS_IID(iid, nsIServiceManager)
QI_SUPPORTS_IID(iid, nsIPluginManager)
QI_SUPPORTS_IID(iid, nsIPluginManager2)
QI_SUPPORTS_IID(iid, nsICookieStorage)
NOTREACHED();
return NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP_(nsrefcnt) BrowserMozillaExtensionApi::AddRef(void) {
return InterlockedIncrement(reinterpret_cast<LONG*>(&ref_count_));
}
NS_IMETHODIMP_(nsrefcnt) BrowserMozillaExtensionApi::Release(void) {
DCHECK(static_cast<int>(ref_count_) > 0);
if (InterlockedDecrement(reinterpret_cast<LONG*>(&ref_count_)) == 0) {
delete this;
return 0;
}
return ref_count_;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::GetService(REFNSIID class_guid,
REFNSIID iid,
void** result) {
static const nsIID kPluginManagerCID = NS_PLUGINMANAGER_CID;
static const nsIID kCookieStorageCID = NS_COOKIESTORAGE_CID;
nsresult rv = NS_ERROR_FAILURE;
if ((class_guid.Equals(kPluginManagerCID)) ||
(class_guid.Equals(kCookieStorageCID))) {
rv = QueryInterface(iid, result);
}
DCHECK(rv == NS_OK);
return rv;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::GetServiceByContractID(
const char* contract_id,
REFNSIID iid,
void** result) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::IsServiceInstantiated(REFNSIID class_guid,
REFNSIID iid,
PRBool* result) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::IsServiceInstantiatedByContractID(
const char* contract_id,
REFNSIID iid,
PRBool* result) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::GetValue(nsPluginManagerVariable variable,
void * value) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::ReloadPlugins(PRBool reloadPages) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::UserAgent(
const char** resultingAgentString) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::GetURL(
nsISupports* pluginInst,
const char* url,
const char* target,
nsIPluginStreamListener* streamListener,
const char* altHost,
const char* referrer,
PRBool forceJSEnabled) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::PostURL(
nsISupports* pluginInst,
const char* url,
unsigned int postDataLen,
const char* postData,
PRBool isFile,
const char* target,
nsIPluginStreamListener* streamListener,
const char* altHost,
const char* referrer,
PRBool forceJSEnabled ,
unsigned int postHeadersLength,
const char* postHeaders) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::RegisterPlugin(
REFNSIID aCID,
const char *aPluginName,
const char *aDescription,
const char * * aMimeTypes,
const char * * aMimeDescriptions,
const char * * aFileExtensions,
PRInt32 aCount) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::UnregisterPlugin(REFNSIID aCID) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::GetURLWithHeaders(
nsISupports* pluginInst,
const char* url,
const char* target /* = NULL */,
nsIPluginStreamListener* streamListener /* = NULL */,
const char* altHost /* = NULL */,
const char* referrer /* = NULL */,
PRBool forceJSEnabled /* = PR_FALSE */,
PRUint32 getHeadersLength /* = 0 */,
const char* getHeaders /* = NULL */){
NOTREACHED();
return NS_ERROR_FAILURE;
}
// nsIPluginManager2
NS_IMETHODIMP BrowserMozillaExtensionApi::BeginWaitCursor() {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::EndWaitCursor() {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::SupportsURLProtocol(const char* aProtocol,
PRBool* aResult) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::NotifyStatusChange(nsIPlugin* aPlugin,
nsresult aStatus) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::FindProxyForURL(
const char* aURL,
char** aResult) {
std::string proxy = "DIRECT";
FindProxyForUrl(aURL, &proxy);
// Allocate this using the NPAPI allocator. The plugin will call
// NPN_Free to free this.
char* result = static_cast<char*>(NPN_MemAlloc(proxy.length() + 1));
strncpy(result, proxy.c_str(), proxy.length() + 1);
*aResult = result;
return NS_OK;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::RegisterWindow(
nsIEventHandler* handler,
nsPluginPlatformWindowRef window) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::UnregisterWindow(
nsIEventHandler* handler,
nsPluginPlatformWindowRef win) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::AllocateMenuID(nsIEventHandler* aHandler,
PRBool aIsSubmenu,
PRInt16 *aResult) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::DeallocateMenuID(nsIEventHandler* aHandler,
PRInt16 aMenuID) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::HasAllocatedMenuID(nsIEventHandler* aHandler,
PRInt16 aMenuID,
PRBool* aResult) {
NOTREACHED();
return NS_ERROR_FAILURE;
}
// nsICookieStorage
NS_IMETHODIMP BrowserMozillaExtensionApi::GetCookie(
const char* url,
void* cookie_buffer,
PRUint32& buffer_size) {
if ((!url) || (!cookie_buffer)) {
return NS_ERROR_INVALID_ARG;
}
if (!plugin_instance_)
return NS_ERROR_FAILURE;
WebPlugin* webplugin = plugin_instance_->webplugin();
if (!webplugin)
return NS_ERROR_FAILURE;
// Bypass third-party cookie blocking by using the url as the policy_url.
GURL cookies_url((std::string(url)));
std::string cookies = webplugin->GetCookies(cookies_url, cookies_url);
if (cookies.empty())
return NS_ERROR_FAILURE;
if(cookies.length() >= buffer_size)
return NS_ERROR_FAILURE;
strncpy(static_cast<char*>(cookie_buffer),
cookies.c_str(),
cookies.length() + 1);
buffer_size = cookies.length();
return NS_OK;
}
NS_IMETHODIMP BrowserMozillaExtensionApi::SetCookie(
const char* url,
const void* cookie_buffer,
PRUint32 buffer_size){
if ((!url) || (!cookie_buffer) || (!buffer_size)) {
return NS_ERROR_INVALID_ARG;
}
if (!plugin_instance_)
return NS_ERROR_FAILURE;
WebPlugin* webplugin = plugin_instance_->webplugin();
if (!webplugin)
return NS_ERROR_FAILURE;
std::string cookie(static_cast<const char*>(cookie_buffer),
buffer_size);
GURL cookies_url((std::string(url)));
webplugin->SetCookie(cookies_url,
cookies_url,
cookie);
return NS_OK;
}
} // namespace NPAPI

View File

@ -1,101 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_MOZILLA_EXTENSIONS_H
#define _BROWSER_MOZILLA_EXTENSIONS_H
#include <string>
// Include npapi first to avoid definition clashes due to
// XP_WIN
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/mozilla/include/nsIServiceManager.h"
#include "third_party/mozilla/include/nsIPluginManager2.h"
#include "third_party/mozilla/include/nsICookieStorage.h"
#include "third_party/mozilla/include/nsError.h"
#include "base/ref_counted.h"
// NS_DECL_NSIPLUGINMANAGER doesn't include methods described as "C++" in the
// nsIPluginManager.idl.
#define NS_DECL_NSIPLUGINMANAGER_FIXED \
NS_DECL_NSIPLUGINMANAGER \
NS_IMETHOD \
GetURL(nsISupports* pluginInst, \
const char* url, \
const char* target = NULL, \
nsIPluginStreamListener* streamListener = NULL, \
const char* altHost = NULL, \
const char* referrer = NULL, \
PRBool forceJSEnabled = PR_FALSE); \
NS_IMETHOD \
PostURL(nsISupports* pluginInst, \
const char* url, \
PRUint32 postDataLen, \
const char* postData, \
PRBool isFile = PR_FALSE, \
const char* target = NULL, \
nsIPluginStreamListener* streamListener = NULL, \
const char* altHost = NULL, \
const char* referrer = NULL, \
PRBool forceJSEnabled = PR_FALSE, \
PRUint32 postHeadersLength = 0, \
const char* postHeaders = NULL); \
NS_IMETHOD \
GetURLWithHeaders(nsISupports* pluginInst, \
const char* url, \
const char* target = NULL, \
nsIPluginStreamListener* streamListener = NULL, \
const char* altHost = NULL, \
const char* referrer = NULL, \
PRBool forceJSEnabled = PR_FALSE, \
PRUint32 getHeadersLength = 0, \
const char* getHeaders = NULL);
// Avoid dependence on the nsIsupportsImpl.h and so on.
#ifndef NS_DECL_ISUPPORTS
#define NS_DECL_ISUPPORTS \
NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void);
#endif // NS_DECL_ISUPPORTS
namespace NPAPI
{
class BrowserPluginInstance;
// Implementation of extended Mozilla interfaces needed to support
// Sun's new Java plugin.
class BrowserMozillaExtensionApi : public nsIServiceManager,
public nsIPluginManager2,
public nsICookieStorage {
public:
BrowserMozillaExtensionApi(BrowserPluginInstance* plugin_instance) :
plugin_instance_(plugin_instance), ref_count_(0) {
}
void DetachFromInstance();
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEMANAGER
NS_DECL_NSIPLUGINMANAGER_FIXED
NS_DECL_NSIPLUGINMANAGER2
NS_DECL_NSICOOKIESTORAGE
protected:
bool FindProxyForUrl(const char* url, std::string* proxy);
protected:
scoped_refptr<NPAPI::BrowserPluginInstance> plugin_instance_;
unsigned long ref_count_;
};
} // namespace NPAPI
#endif // _BROWSER_MOZILLA_EXTENSIONS_H

View File

@ -1,512 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "browser_plugin_instance.h"
#include "browser_plugin_lib.h"
#include "browser_plugin_stream_url.h"
#include "browser_plugin_string_stream.h"
#if defined(OS_WIN)
#include "browser_mozilla_extensions.h"
#endif
#include "base/file_util.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/thread_local.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webplugin.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_host.h"
#include "net/base/escape.h"
namespace NPAPI {
// Use TLS to store the PluginInstance object during its creation. We need to
// pass this instance to the service manager (MozillaExtensionApi) created as a
// result of NPN_GetValue in the context of NP_Initialize.
static base::LazyInstance<base::ThreadLocalPointer<BrowserPluginInstance> >
lazy_tls(base::LINKER_INITIALIZED);
BrowserPluginInstance::BrowserPluginInstance(BrowserPluginLib *plugin,
const std::string &mime_type)
: plugin_(plugin),
npp_(0),
host_(PluginHost::Singleton()),
npp_functions_(plugin->functions()),
#if defined(OS_WIN)
hwnd_(0),
#endif
windowless_(false),
transparent_(true),
webplugin_(0),
mime_type_(mime_type),
get_notify_data_(NULL),
use_mozilla_user_agent_(false),
message_loop_(MessageLoop::current()),
load_manually_(false),
in_close_streams_(false) {
npp_ = new NPP_t();
npp_->ndata = 0;
npp_->pdata = 0;
memset(&zero_padding_, 0, sizeof(zero_padding_));
DCHECK(message_loop_);
}
BrowserPluginInstance::~BrowserPluginInstance() {
CloseStreams();
if (npp_ != 0) {
delete npp_;
npp_ = 0;
}
if (plugin_)
plugin_->CloseInstance();
}
BrowserPluginStreamUrl *BrowserPluginInstance::CreateStream(int resource_id,
const std::string &url,
const std::string &mime_type,
bool notify_needed,
void *notify_data) {
BrowserPluginStreamUrl *stream = new BrowserPluginStreamUrl(
resource_id, GURL(url), this, notify_needed, notify_data);
AddStream(stream);
return stream;
}
void BrowserPluginInstance::AddStream(BrowserPluginStream* stream) {
open_streams_.push_back(stream);
}
void BrowserPluginInstance::RemoveStream(BrowserPluginStream* stream) {
if (in_close_streams_)
return;
std::vector<scoped_refptr<BrowserPluginStream> >::iterator stream_index;
for (stream_index = open_streams_.begin();
stream_index != open_streams_.end(); ++stream_index) {
if (*stream_index == stream) {
open_streams_.erase(stream_index);
break;
}
}
}
bool BrowserPluginInstance::IsValidStream(const NPStream* stream) {
std::vector<scoped_refptr<BrowserPluginStream> >::iterator stream_index;
for (stream_index = open_streams_.begin();
stream_index != open_streams_.end(); ++stream_index) {
if ((*stream_index)->stream() == stream)
return true;
}
return false;
}
void BrowserPluginInstance::CloseStreams() {
in_close_streams_ = true;
for (unsigned int index = 0; index < open_streams_.size(); ++index) {
// Close all streams on the way down.
open_streams_[index]->Close(NPRES_USER_BREAK);
}
open_streams_.clear();
in_close_streams_ = false;
}
#if defined(OS_WIN)
bool BrowserPluginInstance::HandleEvent(UINT message, WPARAM wParam, LPARAM lParam) {
if (!windowless_)
return false;
NPEvent windowEvent;
windowEvent.event = message;
windowEvent.lParam = static_cast<uint32>(lParam);
windowEvent.wParam = static_cast<uint32>(wParam);
return NPP_HandleEvent(&windowEvent) != 0;
}
#endif
bool BrowserPluginInstance::Start(const GURL& url,
char** const param_names,
char** const param_values,
int param_count,
bool load_manually) {
load_manually_ = load_manually;
instance_url_ = url;
unsigned short mode = load_manually_ ? NP_FULL : NP_EMBED;
npp_->ndata = this;
NPError err = NPP_New(mode, param_count,
const_cast<char **>(param_names), const_cast<char **>(param_values));
return err == NPERR_NO_ERROR;
}
NPObject *BrowserPluginInstance::GetPluginScriptableObject() {
NPObject *value = NULL;
NPError error = NPP_GetValue(NPPVpluginScriptableNPObject, &value);
if (error != NPERR_NO_ERROR || value == NULL)
return NULL;
return value;
}
void BrowserPluginInstance::SetURLLoadData(const GURL& url,
void* notify_data) {
get_url_ = url;
get_notify_data_ = notify_data;
}
// WebPluginLoadDelegate methods
void BrowserPluginInstance::DidFinishLoadWithReason(NPReason reason) {
if (!get_url_.is_empty()) {
NPP_URLNotify(get_url_.spec().c_str(), reason, get_notify_data_);
}
get_url_ = GURL();
get_notify_data_ = NULL;
}
// NPAPI methods
NPError BrowserPluginInstance::NPP_New(unsigned short mode,
short argc,
char *argn[],
char *argv[]) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->newp != 0);
DCHECK(argc >= 0);
if (npp_functions_->newp != 0) {
return npp_functions_->newp(
(NPMIMEType)mime_type_.c_str(), npp_, mode, argc, argn, argv, NULL);
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
void BrowserPluginInstance::NPP_Destroy() {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->newp != 0);
if (npp_functions_->destroy != 0) {
NPSavedData *savedData = 0;
npp_functions_->destroy(npp_, &savedData);
// TODO: Support savedData. Technically, these need to be
// saved on a per-URL basis, and then only passed
// to new instances of the plugin at the same URL.
// Sounds like a huge security risk. When we do support
// these, we should pass them back to the PluginLib
// to be stored there.
DCHECK(savedData == 0);
}
#if defined(OS_WIN)
// Clean up back references to this instance if any
if (mozilla_extenstions_) {
mozilla_extenstions_->DetachFromInstance();
mozilla_extenstions_ = NULL;
}
#endif
for (unsigned int file_index = 0; file_index < files_created_.size();
file_index++) {
file_util::Delete(files_created_[file_index], false);
}
}
NPError BrowserPluginInstance::NPP_SetWindow(NPWindow *window) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->setwindow != 0);
if (npp_functions_->setwindow != 0) {
return npp_functions_->setwindow(npp_, window);
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
NPError BrowserPluginInstance::NPP_NewStream(NPMIMEType type,
NPStream *stream,
NPBool seekable,
unsigned short *stype) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->newstream != 0);
if (npp_functions_->newstream != 0) {
return npp_functions_->newstream(npp_, type, stream, seekable, stype);
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
NPError BrowserPluginInstance::NPP_DestroyStream(NPStream *stream,
NPReason reason) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->destroystream != 0);
if (stream == NULL || (stream->ndata == NULL) ||
!IsValidStream(stream))
return NPERR_INVALID_INSTANCE_ERROR;
if (npp_functions_->destroystream != 0) {
NPError result = npp_functions_->destroystream(npp_, stream, reason);
stream->ndata = NULL;
return result;
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
int BrowserPluginInstance::NPP_WriteReady(NPStream *stream) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->writeready != 0);
if (npp_functions_->writeready != 0) {
return npp_functions_->writeready(npp_, stream);
}
return NULL;
}
int BrowserPluginInstance::NPP_Write(NPStream *stream,
int offset,
int len,
void *buffer) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->write != 0);
if (npp_functions_->write != 0) {
return npp_functions_->write(npp_, stream, offset, len, buffer);
}
return NULL;
}
void BrowserPluginInstance::NPP_StreamAsFile(NPStream *stream,
const char *fname) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->asfile != 0);
if (npp_functions_->asfile != 0) {
npp_functions_->asfile(npp_, stream, fname);
}
// Creating a temporary FilePath instance on the stack as the explicit
// FilePath constructor with StringType as an argument causes a compiler
// error when invoked via vector push back.
FilePath file_name = FilePath::FromWStringHack(UTF8ToWide(fname));
files_created_.push_back(file_name);
}
void BrowserPluginInstance::NPP_URLNotify(const char *url,
NPReason reason,
void *notifyData) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->urlnotify != 0);
if (npp_functions_->urlnotify != 0) {
npp_functions_->urlnotify(npp_, url, reason, notifyData);
}
}
NPError BrowserPluginInstance::NPP_GetValue(NPPVariable variable, void *value) {
DCHECK(npp_functions_ != 0);
// getvalue is NULL for Shockwave
if (npp_functions_->getvalue != 0) {
return npp_functions_->getvalue(npp_, variable, value);
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
NPError BrowserPluginInstance::NPP_SetValue(NPNVariable variable, void *value) {
DCHECK(npp_functions_ != 0);
if (npp_functions_->setvalue != 0) {
return npp_functions_->setvalue(npp_, variable, value);
}
return NPERR_INVALID_FUNCTABLE_ERROR;
}
short BrowserPluginInstance::NPP_HandleEvent(NPEvent *event) {
DCHECK(npp_functions_ != 0);
DCHECK(npp_functions_->event != 0);
if (npp_functions_->event != 0) {
return npp_functions_->event(npp_, (void*)event);
}
return false;
}
bool BrowserPluginInstance::NPP_Print(NPPrint* platform_print) {
DCHECK(npp_functions_ != 0);
if (npp_functions_->print != 0) {
npp_functions_->print(npp_, platform_print);
return true;
}
return false;
}
void BrowserPluginInstance::SendJavaScriptStream(const std::string& url,
const std::wstring& result,
bool success,
bool notify_needed,
int notify_data) {
if (success) {
BrowserPluginStringStream *stream =
new BrowserPluginStringStream(this, url, notify_needed,
reinterpret_cast<void*>(notify_data));
AddStream(stream);
stream->SendToPlugin(WideToUTF8(result), "text/html");
} else {
// NOTE: Sending an empty stream here will crash MacroMedia
// Flash 9. Just send the URL Notify.
if (notify_needed) {
this->NPP_URLNotify(url.c_str(), NPRES_DONE,
reinterpret_cast<void*>(notify_data));
}
}
}
void BrowserPluginInstance::DidReceiveManualResponse(const std::string& url,
const std::string& mime_type,
const std::string& headers,
uint32 expected_length,
uint32 last_modified) {
DCHECK(load_manually_);
std::string response_url = url;
if (response_url.empty()) {
response_url = instance_url_.spec();
}
bool cancel = false;
plugin_data_stream_ = CreateStream(-1, url, mime_type, false, NULL);
plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length,
last_modified, true, &cancel);
AddStream(plugin_data_stream_.get());
}
void BrowserPluginInstance::DidReceiveManualData(const char* buffer,
int length) {
DCHECK(load_manually_);
if (plugin_data_stream_.get() != NULL) {
plugin_data_stream_->DidReceiveData(buffer, length, 0);
}
}
void BrowserPluginInstance::DidFinishManualLoading() {
DCHECK(load_manually_);
if (plugin_data_stream_.get() != NULL) {
plugin_data_stream_->DidFinishLoading();
plugin_data_stream_->Close(NPRES_DONE);
plugin_data_stream_ = NULL;
}
}
void BrowserPluginInstance::DidManualLoadFail() {
DCHECK(load_manually_);
if (plugin_data_stream_.get() != NULL) {
plugin_data_stream_->DidFail();
plugin_data_stream_ = NULL;
}
}
void BrowserPluginInstance::PluginThreadAsyncCall(void (*func)(void *),
void *userData) {
message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &BrowserPluginInstance::OnPluginThreadAsyncCall, func, userData));
}
void BrowserPluginInstance::OnPluginThreadAsyncCall(void (*func)(void *),
void *userData) {
#if defined(OS_WIN)
// We are invoking an arbitrary callback provided by a third
// party plugin. It's better to wrap this into an exception
// block to protect us from crashes.
__try {
func(userData);
} __except(EXCEPTION_EXECUTE_HANDLER) {
// Maybe we can disable a crashing plugin.
// But for now, just continue.
}
#else
NOTIMPLEMENTED();
#endif
}
BrowserPluginInstance* BrowserPluginInstance::SetInitializingInstance(
BrowserPluginInstance* instance) {
BrowserPluginInstance* old_instance = lazy_tls.Pointer()->Get();
lazy_tls.Pointer()->Set(instance);
return old_instance;
}
BrowserPluginInstance* BrowserPluginInstance::GetInitializingInstance() {
return lazy_tls.Pointer()->Get();
}
NPError BrowserPluginInstance::GetServiceManager(void** service_manager) {
#if defined(OS_WIN)
if (!mozilla_extenstions_) {
mozilla_extenstions_ = new BrowserMozillaExtensionApi(this);
}
DCHECK(mozilla_extenstions_);
mozilla_extenstions_->QueryInterface(nsIServiceManager::GetIID(),
service_manager);
#else
NOTIMPLEMENTED();
#endif
return NPERR_NO_ERROR;
}
void BrowserPluginInstance::PushPopupsEnabledState(bool enabled) {
popups_enabled_stack_.push(enabled);
}
void BrowserPluginInstance::PopPopupsEnabledState() {
popups_enabled_stack_.pop();
}
void BrowserPluginInstance::RequestRead(NPStream* stream,
NPByteRange* range_list) {
std::string range_info = "bytes=";
while (range_list) {
range_info += IntToString(range_list->offset);
range_info += "-";
range_info += IntToString(range_list->offset + range_list->length - 1);
range_list = range_list->next;
if (range_list) {
range_info += ",";
}
}
if (plugin_data_stream_) {
if (plugin_data_stream_->stream() == stream) {
webplugin_->CancelDocumentLoad();
plugin_data_stream_ = NULL;
}
}
// The lifetime of a NPStream instance depends on the BrowserPluginStream
// instance which owns it. When a plugin invokes NPN_RequestRead on a seekable
// stream, we don't want to create a new stream when the corresponding
// response is received. We send over a cookie which represents the
// BrowserPluginStream instance which is sent back from the renderer when the
// response is received.
std::vector<scoped_refptr<BrowserPluginStream> >::iterator stream_index;
for (stream_index = open_streams_.begin();
stream_index != open_streams_.end(); ++stream_index) {
BrowserPluginStream* plugin_stream = *stream_index;
if (plugin_stream->stream() == stream) {
// A stream becomes seekable the first time NPN_RequestRead
// is called on it.
plugin_stream->set_seekable(true);
webplugin_->InitiateHTTPRangeRequest(
stream->url, range_info.c_str(),
plugin_stream,
plugin_stream->notify_needed(),
plugin_stream->notify_data());
break;
}
}
}
} // namespace NPAPI

View File

@ -1,262 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
// TODO: Need to deal with NPAPI's NPSavedData.
// I haven't seen plugins use it yet.
#ifndef _BROWSER_PLUGIN_INSTANCE_H
#define _BROWSER_PLUGIN_INSTANCE_H
#include <string>
#include <vector>
#include <stack>
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/nphostapi.h"
#include "googleurl/src/gurl.h"
#include "third_party/npapi/bindings/npapi.h"
class WebPlugin;
class MessageLoop;
namespace NPAPI
{
class BrowserPluginLib;
class BrowserPluginStream;
class BrowserPluginStreamUrl;
class BrowserPluginDataStream;
class BrowserMozillaExtensionApi;
class PluginHost;
// A BrowserPluginInstance is an active, running instance of a Plugin.
// A single plugin may have many BrowserPluginInstances.
class BrowserPluginInstance : public base::RefCountedThreadSafe<BrowserPluginInstance> {
public:
// Create a new instance of a plugin. The BrowserPluginInstance
// will hold a reference to the plugin.
BrowserPluginInstance(BrowserPluginLib *plugin, const std::string &mime_type);
virtual ~BrowserPluginInstance();
// Activates the instance by calling NPP_New.
// This should be called after our instance is all
// setup from the host side and we are ready to receive
// requests from the plugin. We must not call any
// functions on the plugin instance until start has
// been called.
//
// url: The instance URL.
// param_names: the list of names of attributes passed via the
// element.
// param_values: the list of values corresponding to param_names
// param_count: number of attributes
// load_manually: 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)
//
bool Start(const GURL& url,
char** const param_names,
char** const param_values,
int param_count,
bool load_manually);
// NPAPI's instance identifier for this instance
NPP npp() { return npp_; }
#if defined(OS_WIN)
// Get/Set for the instance's HWND.
HWND window_handle() { return hwnd_; }
void set_window_handle(HWND value) { hwnd_ = value; }
#endif
// Get/Set whether this instance is in Windowless mode.
// Default is false.
bool windowless() { return windowless_; }
void set_windowless(bool value) { windowless_ = value; }
// Get/Set whether this instance is transparent.
// This only applies to windowless plugins. Transparent
// plugins require that webkit paint the background.
// Default is true.
bool transparent() { return transparent_; }
void set_transparent(bool value) { transparent_ = value; }
// Get/Set the WebPlugin associated with this instance
WebPlugin* webplugin() { return webplugin_; }
void set_web_plugin(WebPlugin* webplugin) { webplugin_ = webplugin; }
// Get the mimeType for this plugin stream
const std::string &mime_type() { return mime_type_; }
NPAPI::BrowserPluginLib* plugin_lib() { return plugin_; }
#if defined(OS_WIN)
// Handles a windows native message which this BrowserPluginInstance should deal
// with. Returns true if the event is handled, false otherwise.
bool HandleEvent(UINT message, WPARAM wParam, LPARAM lParam);
#endif
// Creates a stream for sending an URL. If notify_needed
// is true, it will send a notification to the plugin
// when the stream is complete; otherwise it will not.
// Set object_url to true if the load is for the object tag's
// url, or false if it's for a url that the plugin
// fetched through NPN_GetUrl[Notify].
BrowserPluginStreamUrl *CreateStream(int resource_id,
const std::string &url,
const std::string &mime_type,
bool notify_needed,
void *notify_data);
// For each instance, we track all streams. When the
// instance closes, all remaining streams are also
// closed. All streams associated with this instance
// should call AddStream so that they can be cleaned
// up when the instance shuts down.
void AddStream(BrowserPluginStream* stream);
// This is called when a stream is closed. We remove the stream from the
// list, which releases the reference maintained to the stream.
void RemoveStream(BrowserPluginStream* stream);
// Closes all open streams on this instance.
void CloseStreams();
// Have the plugin create it's script object.
NPObject *GetPluginScriptableObject();
// WebViewDelegate methods that we implement. This is for handling
// callbacks during getURLNotify.
virtual void DidFinishLoadWithReason(NPReason reason);
// Helper method to set some persistent data for getURLNotify since
// resource fetches happen async.
void SetURLLoadData(const GURL& url, void* notify_data);
// If true, send the Mozilla user agent instead of Chrome's to the plugin.
bool use_mozilla_user_agent() { return use_mozilla_user_agent_; }
void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; }
// Helper that implements NPN_PluginThreadAsyncCall semantics
void PluginThreadAsyncCall(void (*func)(void *),
void *userData);
//
// NPAPI methods for calling the Plugin Instance
//
NPError NPP_New(unsigned short, short, char *[], char *[]);
NPError NPP_SetWindow(NPWindow *);
NPError NPP_NewStream(NPMIMEType, NPStream *, NPBool, unsigned short *);
NPError NPP_DestroyStream(NPStream *, NPReason);
int NPP_WriteReady(NPStream *);
int NPP_Write(NPStream *, int, int, void *);
void NPP_StreamAsFile(NPStream *, const char *);
void NPP_URLNotify(const char *, NPReason, void *);
NPError NPP_GetValue(NPPVariable, void *);
NPError NPP_SetValue(NPNVariable, void *);
short NPP_HandleEvent(NPEvent *);
void NPP_Destroy();
bool NPP_Print(NPPrint* platform_print);
void SendJavaScriptStream(const std::string& url, const std::wstring& result,
bool success, bool notify_needed, int notify_data);
void DidReceiveManualResponse(const std::string& url,
const std::string& mime_type,
const std::string& headers,
uint32 expected_length,
uint32 last_modified);
void DidReceiveManualData(const char* buffer, int length);
void DidFinishManualLoading();
void DidManualLoadFail();
NPError GetServiceManager(void** service_manager);
static BrowserPluginInstance* SetInitializingInstance(BrowserPluginInstance* instance);
static BrowserPluginInstance* GetInitializingInstance();
void PushPopupsEnabledState(bool enabled);
void PopPopupsEnabledState();
bool popups_allowed() const {
return popups_enabled_stack_.empty() ? false : popups_enabled_stack_.top();
}
// Initiates byte range reads for plugins.
void RequestRead(NPStream* stream, NPByteRange* range_list);
private:
void OnPluginThreadAsyncCall(void (*func)(void *),
void *userData);
bool IsValidStream(const NPStream* stream);
// This is a hack to get the real player plugin to work with chrome
// The real player plugin dll(nppl3260) when loaded by firefox is loaded via
// the NS COM API which is analogous to win32 COM. So the NPAPI functions in
// the plugin are invoked via an interface by firefox. The plugin instance
// handle which is passed to every NPAPI method is owned by the real player
// plugin, i.e. it expects the ndata member to point to a structure which
// it knows about. Eventually it dereferences this structure and compares
// a member variable at offset 0x24(Version 6.0.11.2888) /2D (Version
// 6.0.11.3088) with 0 and on failing this check, takes a different code
// path which causes a crash. Safari and Opera work with version 6.0.11.2888
// by chance as their ndata structure contains a 0 at the location which real
// player checks:(. They crash with version 6.0.11.3088 as well. The
// following member just adds a 96 byte padding to our BrowserPluginInstance class
// which is passed in the ndata member. This magic number works correctly on
// Vista with UAC on or off :(.
// NOTE: Please dont change the ordering of the member variables
// New members should be added after this padding array.
// TODO(iyengar) : Disassemble the Realplayer ndata structure and look into
// the possiblity of conforming to it (http://b/issue?id=936667). We
// could also log a bug with Real, which would save the effort.
uint8 zero_padding_[96];
scoped_refptr<NPAPI::BrowserPluginLib> plugin_;
NPP npp_;
scoped_refptr<PluginHost> host_;
NPPluginFuncs* npp_functions_;
std::vector<scoped_refptr<BrowserPluginStream> > open_streams_;
#if defined(OS_WIN)
HWND hwnd_;
#endif
bool windowless_;
bool transparent_;
WebPlugin* webplugin_;
std::string mime_type_;
GURL get_url_;
void* get_notify_data_;
bool use_mozilla_user_agent_;
#if defined(OS_WIN)
scoped_refptr<BrowserMozillaExtensionApi> mozilla_extenstions_;
#endif
MessageLoop* message_loop_;
scoped_refptr<BrowserPluginStreamUrl> plugin_data_stream_;
GURL instance_url_;
// This flag if true indicates that the plugin data would be passed from
// webkit. if false indicates that the plugin should download the data.
bool load_manually_;
// Stack indicating if popups are to be enabled for the outgoing
// NPN_GetURL/NPN_GetURLNotify calls.
std::stack<bool> popups_enabled_stack_;
// True if in CloseStreams().
bool in_close_streams_;
// List of files created for the current plugin instance. File names are
// added to the list every time the NPP_StreamAsFile function is called.
std::vector<FilePath> files_created_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginInstance);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_INSTANCE_H

View File

@ -1,175 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "config.h"
#include "browser_plugin_lib.h"
#include "browser_plugin_instance.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_host.h"
#include "net/base/mime_util.h"
namespace NPAPI
{
BrowserPluginLib::PluginMap* BrowserPluginLib::loaded_libs_;
BrowserPluginLib* BrowserPluginLib::GetOrCreatePluginLib(const struct CefPluginInfo& plugin_info) {
// We can only have one BrowserPluginLib object per plugin as it controls the
// per instance function calls (i.e. NP_Initialize and NP_Shutdown). So we
// keep a (non-ref counted) map of BrowserPluginLib objects.
if (!loaded_libs_)
loaded_libs_ = new PluginMap();
PluginMap::const_iterator iter =
loaded_libs_->find(plugin_info.version_info.unique_name);
if (iter != loaded_libs_->end())
return iter->second;
WebPluginInfo* info = CreateWebPluginInfo(plugin_info.version_info);
return new BrowserPluginLib(info, plugin_info);
}
BrowserPluginLib::BrowserPluginLib(WebPluginInfo* info,
const CefPluginInfo& plugin_info)
: web_plugin_info_(info),
plugin_info_(plugin_info),
initialized_(false),
saved_data_(0),
instance_count_(0) {
memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
(*loaded_libs_)[info->path.BaseName().value()] = this;
}
BrowserPluginLib::~BrowserPluginLib() {
if (saved_data_ != 0) {
// TODO - delete the savedData object here
}
}
NPPluginFuncs *BrowserPluginLib::functions() {
return &plugin_funcs_;
}
bool BrowserPluginLib::SupportsType(const std::string &mime_type,
bool allow_wildcard) {
// Webkit will ask for a plugin to handle empty mime types.
if (mime_type.empty())
return false;
for (size_t i = 0; i < web_plugin_info_->mime_types.size(); ++i) {
const WebPluginMimeType& mime_info = web_plugin_info_->mime_types[i];
if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
if (!allow_wildcard && (mime_info.mime_type == "*")) {
continue;
}
return true;
}
}
return false;
}
NPError BrowserPluginLib::NP_Initialize() {
if (initialized_)
return NPERR_NO_ERROR;
PluginHost *host = PluginHost::Singleton();
if (host == 0)
return NPERR_GENERIC_ERROR;
NPError rv = plugin_info_.np_initialize(host->host_functions());
initialized_ = (rv == NPERR_NO_ERROR);
if(initialized_) {
plugin_funcs_.size = sizeof(plugin_funcs_);
plugin_funcs_.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
if (plugin_info_.np_getentrypoints(&plugin_funcs_) != NPERR_NO_ERROR)
rv = false;
}
return rv;
}
void BrowserPluginLib::NP_Shutdown(void) {
DCHECK(initialized_);
plugin_info_.np_shutdown();
}
BrowserPluginInstance *BrowserPluginLib::CreateInstance(const std::string &mime_type) {
// The PluginInstance class uses the PluginLib member only for calling
// CloseInstance() from the PluginInstance destructor. We explicitly call
// CloseInstance() from BrowserWebPluginDelegateImpl::DestroyInstance().
BrowserPluginInstance *new_instance =
new BrowserPluginInstance(this, mime_type);
instance_count_++;
DCHECK(new_instance != 0);
return new_instance;
}
void BrowserPluginLib::CloseInstance() {
instance_count_--;
if (instance_count_ == 0) {
NP_Shutdown();
initialized_ = false;
loaded_libs_->erase(web_plugin_info_->path.BaseName().value());
if (loaded_libs_->empty()) {
delete loaded_libs_;
loaded_libs_ = NULL;
}
}
}
WebPluginInfo* BrowserPluginLib::CreateWebPluginInfo(const CefPluginVersionInfo& plugin_info) {
std::vector<std::string> mime_types, file_extensions;
std::vector<std::wstring> descriptions;
SplitString(base::SysWideToNativeMB(plugin_info.mime_types), '|',
&mime_types);
SplitString(base::SysWideToNativeMB(plugin_info.file_extensions), '|',
&file_extensions);
SplitString(plugin_info.file_open_names, '|', &descriptions);
if (mime_types.empty())
return NULL;
WebPluginInfo *info = new WebPluginInfo();
info->name = plugin_info.product_name;
info->desc = plugin_info.description;
info->version = plugin_info.version;
info->path = FilePath(plugin_info.unique_name);
for (size_t i = 0; i < mime_types.size(); ++i) {
WebPluginMimeType mime_type;
mime_type.mime_type = StringToLowerASCII(mime_types[i]);
if (file_extensions.size() > i)
SplitString(file_extensions[i], ',', &mime_type.file_extensions);
if (descriptions.size() > i) {
mime_type.description = descriptions[i];
// Remove the extension list from the description.
size_t ext = mime_type.description.find(L"(*");
if (ext != std::wstring::npos) {
if (ext > 1 && mime_type.description[ext -1] == ' ')
ext--;
mime_type.description.erase(ext);
}
}
info->mime_types.push_back(mime_type);
}
return info;
}
} // namespace NPAPI

View File

@ -1,89 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_PLUGIN_LIB_H
#define _BROWSER_PLUGIN_LIB_H
#include <string>
#include "../../include/cef_nplugin.h"
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
struct WebPluginInfo;
namespace NPAPI
{
class BrowserPluginInstance;
// A BrowserPluginLib is a single NPAPI Plugin Library, and is the lifecycle
// manager for new PluginInstances.
class BrowserPluginLib : public base::RefCounted<BrowserPluginLib> {
public:
virtual ~BrowserPluginLib();
static BrowserPluginLib* GetOrCreatePluginLib(const struct CefPluginInfo& plugin_info);
// Get the Plugin's function pointer table.
NPPluginFuncs *functions();
// Returns true if this Plugin supports a given mime-type.
// mime_type should be all lower case.
bool SupportsType(const std::string &mime_type, bool allow_wildcard);
// Creates a new instance of this plugin.
BrowserPluginInstance *CreateInstance(const std::string &mime_type);
// Called by the instance when the instance is tearing down.
void CloseInstance();
// Gets information about this plugin and the mime types that it
// supports.
const WebPluginInfo& web_plugin_info() { return *web_plugin_info_; }
const struct CefPluginInfo& plugin_info() { return plugin_info_; }
//
// NPAPI functions
//
// NPAPI method to initialize a Plugin.
// Initialize can be safely called multiple times
NPError NP_Initialize();
// NPAPI method to shutdown a Plugin.
void NP_Shutdown(void);
int instance_count() const { return instance_count_; }
private:
// Creates a new BrowserPluginLib. The WebPluginInfo object is owned by this
// object. internal_plugin_info must not be NULL.
BrowserPluginLib(WebPluginInfo* info,
const CefPluginInfo& plugin_info);
// Creates WebPluginInfo structure based on read in or built in
// CefPluginVersionInfo.
static WebPluginInfo* CreateWebPluginInfo(const CefPluginVersionInfo& info);
scoped_ptr<WebPluginInfo> web_plugin_info_; // supported mime types, description
struct CefPluginInfo plugin_info_;
NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
bool initialized_; // is the plugin initialized
NPSavedData *saved_data_; // persisted plugin info for NPAPI
int instance_count_; // count of plugins in use
// A map of all the insantiated plugins.
typedef base::hash_map<std::wstring, scoped_refptr<BrowserPluginLib> > PluginMap;
static PluginMap* loaded_libs_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginLib);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_LIB_H

View File

@ -1,160 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include <algorithm>
#include <tchar.h>
#include "browser_plugin_list.h"
#include "browser_plugin_lib.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "googleurl/src/gurl.h"
namespace NPAPI
{
scoped_refptr<BrowserPluginList> BrowserPluginList::singleton_;
BrowserPluginList* BrowserPluginList::Singleton() {
if (singleton_.get() == NULL) {
singleton_ = new BrowserPluginList();
}
return singleton_;
}
BrowserPluginList::BrowserPluginList() {
}
BrowserPluginList::~BrowserPluginList() {
plugins_.clear();
}
void BrowserPluginList::AddPlugin(const struct CefPluginInfo& plugin_info) {
scoped_refptr<BrowserPluginLib> new_plugin
= BrowserPluginLib::GetOrCreatePluginLib(plugin_info);
if (!new_plugin.get())
return;
const WebPluginInfo& web_plugin_info = new_plugin->web_plugin_info();
for (size_t i = 0; i < web_plugin_info.mime_types.size(); ++i) {
const std::string &mime_type = web_plugin_info.mime_types[i].mime_type;
if (mime_type == "*")
continue;
if (!SupportsType(mime_type))
plugins_.push_back(new_plugin);
}
}
void BrowserPluginList::RemovePlugin(const struct CefPluginInfo& plugin_info)
{
PluginList::iterator it = plugins_.begin();
for(; it != plugins_.end(); ++it) {
if((*it)->web_plugin_info().path.BaseName().value() ==
plugin_info.version_info.unique_name) {
plugins_.erase(it);
}
}
}
BrowserPluginLib* BrowserPluginList::FindPlugin(const std::string& mime_type,
const std::string& clsid,
bool allow_wildcard) {
DCHECK(mime_type == StringToLowerASCII(mime_type));
for (size_t idx = 0; idx < plugins_.size(); ++idx) {
if (plugins_[idx]->SupportsType(mime_type, allow_wildcard)) {
return plugins_[idx];
}
}
return NULL;
}
BrowserPluginLib* BrowserPluginList::FindPlugin(const GURL &url,
std::string* actual_mime_type) {
std::wstring path = base::SysNativeMBToWide(url.path());
std::wstring extension_wide = file_util::GetFileExtensionFromPath(path);
if (extension_wide.empty())
return NULL;;
std::string extension =
StringToLowerASCII(base::SysWideToNativeMB(extension_wide));
for (size_t idx = 0; idx < plugins_.size(); ++idx) {
if (SupportsExtension(plugins_[idx]->web_plugin_info(), extension,
actual_mime_type)) {
return plugins_[idx];
}
}
return NULL;
}
bool BrowserPluginList::SupportsType(const std::string &mime_type) {
DCHECK(mime_type == StringToLowerASCII(mime_type));
bool allow_wildcard = true;
return (FindPlugin(mime_type, "", allow_wildcard ) != 0);
}
bool BrowserPluginList::SupportsExtension(const WebPluginInfo& info,
const std::string &extension,
std::string* actual_mime_type) {
for (size_t i = 0; i < info.mime_types.size(); ++i) {
const WebPluginMimeType& mime_type = info.mime_types[i];
for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
if (mime_type.file_extensions[j] == extension) {
if (actual_mime_type)
*actual_mime_type = mime_type.mime_type;
return true;
}
}
}
return false;
}
bool BrowserPluginList::GetPlugins(bool refresh,
std::vector<WebPluginInfo>* plugins) {
plugins->resize(plugins_.size());
for (size_t i = 0; i < plugins->size(); ++i)
(*plugins)[i] = plugins_[i]->web_plugin_info();
return true;
}
bool BrowserPluginList::GetPluginInfo(const GURL& url,
const std::string& mime_type,
const std::string& clsid,
bool allow_wildcard,
struct CefPluginInfo* plugin_info,
std::string* actual_mime_type) {
scoped_refptr<BrowserPluginLib> plugin = FindPlugin(mime_type, clsid,
allow_wildcard);
if (plugin.get() == NULL)
plugin = FindPlugin(url, actual_mime_type);
if (plugin.get() == NULL)
return false;
*plugin_info = plugin->plugin_info();
return true;
}
void BrowserPluginList::Shutdown() {
// TODO
}
} // namespace NPAPI

View File

@ -1,99 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
// TODO: Need mechanism to cleanup the static instance
#ifndef _BROWSER_PLUGIN_LIST_H
#define _BROWSER_PLUGIN_LIST_H
#include <string>
#include <vector>
#include "../../include/cef_nplugin.h"
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "webkit/glue/webplugin.h"
class GURL;
namespace NPAPI
{
class BrowserPluginLib;
class PluginInstance;
// The BrowserPluginList is responsible for loading internal NPAPI based
// plugins. Call the LoadPlugin() method to load an internal plugin.
class BrowserPluginList : public base::RefCounted<BrowserPluginList> {
public:
// Gets the one instance of the BrowserPluginList.
static BrowserPluginList* Singleton();
virtual ~BrowserPluginList();
// Add a plugin using the specified info structure.
void AddPlugin(const struct CefPluginInfo& plugin_info);
// Remove the plugin matching the specified info structure.
void RemovePlugin(const struct CefPluginInfo& plugin_info);
// Find a plugin by mime type and clsid.
// If clsid is empty, we will just find the plugin that supports mime type.
// The allow_wildcard parameter controls whether this function returns
// plugins which support wildcard mime types (* as the mime type)
BrowserPluginLib* FindPlugin(const std::string &mime_type,
const std::string& clsid, bool allow_wildcard);
// Find a plugin to by extension. Returns the corresponding mime type.
BrowserPluginLib* FindPlugin(const GURL &url, std::string* actual_mime_type);
// Check if we have any plugin for a given type.
// mime_type must be all lowercase.
bool SupportsType(const std::string &mime_type);
// Returns true if the given WebPluginInfo supports a given file extension.
// extension should be all lower case.
// If mime_type is not NULL, it will be set to the mime type if found.
// The mime type which corresponds to the extension is optionally returned
// back.
static bool SupportsExtension(const WebPluginInfo& info,
const std::string &extension,
std::string* actual_mime_type);
// Shutdown all plugins. Should be called at process teardown.
void Shutdown();
// Get all the plugins
bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins);
// Returns true if a plugin is found for the given url and mime type.
// The mime type which corresponds to the URL is optionally returned
// back.
// The allow_wildcard parameter controls whether this function returns
// plugins which support wildcard mime types (* as the mime type)
bool GetPluginInfo(const GURL& url,
const std::string& mime_type,
const std::string& clsid,
bool allow_wildcard,
struct CefPluginInfo* plugin_info,
std::string* actual_mime_type);
private:
// Constructors are private for singletons
BrowserPluginList();
static scoped_refptr<BrowserPluginList> singleton_;
typedef std::vector<scoped_refptr<BrowserPluginLib> > PluginList;
PluginList plugins_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginList);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_LIST_H

View File

@ -1,248 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
// TODO : Support NP_ASFILEONLY mode
// TODO : Support NP_SEEK mode
// TODO : Support SEEKABLE=true in NewStream
#include "precompiled_libcef.h"
#include "browser_plugin_stream.h"
#include "browser_plugin_instance.h"
#include "base/string_util.h"
#include "base/message_loop.h"
#include "webkit/glue/webkit_glue.h"
#include "googleurl/src/gurl.h"
namespace NPAPI {
BrowserPluginStream::~BrowserPluginStream() {
// always close our temporary files.
CloseTempFile();
free(const_cast<char*>(stream_.url));
}
bool BrowserPluginStream::Open(const std::string &mime_type,
const std::string &headers,
uint32 length,
uint32 last_modified,
bool request_is_seekable) {
headers_ = headers;
NPP id = instance_->npp();
stream_.end = length;
stream_.lastmodified = last_modified;
stream_.pdata = 0;
stream_.ndata = id->ndata;
stream_.notifyData = notify_data_;
bool seekable_stream = false;
if (request_is_seekable && !headers_.empty()) {
stream_.headers = headers_.c_str();
if (headers_.find("Accept-Ranges: bytes") != std::string::npos) {
seekable_stream = true;
}
}
const char *char_mime_type = "application/x-unknown-content-type";
std::string temp_mime_type;
if (!mime_type.empty()) {
char_mime_type = mime_type.c_str();
} else {
GURL gurl(stream_.url);
std::wstring path(UTF8ToWide(gurl.path()));
if (webkit_glue::GetMimeTypeFromFile(path, &temp_mime_type))
char_mime_type = temp_mime_type.c_str();
}
// Silverlight expects a valid mime type
DCHECK(strlen(char_mime_type) != 0);
NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type,
&stream_, seekable_stream,
&requested_plugin_mode_);
if (err != NPERR_NO_ERROR) {
Notify(err);
return false;
}
opened_ = true;
if (requested_plugin_mode_ == NP_SEEK) {
seekable_stream_ = true;
}
// If the plugin has requested certain modes, then we need a copy
// of this file on disk. Open it and save it as we go.
if (requested_plugin_mode_ == NP_ASFILEONLY ||
requested_plugin_mode_ == NP_ASFILE) {
if (OpenTempFile() == false)
return false;
}
mime_type_ = char_mime_type;
return true;
}
int BrowserPluginStream::Write(const char *buffer, const int length,
int data_offset) {
// There may be two streams to write to - the plugin and the file.
// It is unclear what to do if we cannot write to both. The rules of
// this function are that the plugin must consume at least as many
// bytes as returned by the WriteReady call. So, we will attempt to
// write that many to both streams. If we can't write that many bytes
// to each stream, we'll return failure.
DCHECK(opened_);
if (WriteToFile(buffer, length) &&
WriteToPlugin(buffer, length, data_offset))
return length;
return -1;
}
bool BrowserPluginStream::WriteToFile(const char *buf, size_t length) {
// For ASFILEONLY, ASFILE, and SEEK modes, we need to write
// to the disk
if (TempFileIsValid() &&
(requested_plugin_mode_ == NP_ASFILE ||
requested_plugin_mode_ == NP_ASFILEONLY) ) {
size_t totalBytesWritten = 0, bytes;
do {
bytes = WriteBytes(buf, length);
totalBytesWritten += bytes;
} while (bytes > 0U && totalBytesWritten < length);
if (totalBytesWritten != length)
return false;
}
return true;
}
bool BrowserPluginStream::WriteToPlugin(const char *buf, const int length,
const int data_offset) {
// For NORMAL and ASFILE modes, we send the data to the plugin now
if (requested_plugin_mode_ != NP_NORMAL &&
requested_plugin_mode_ != NP_ASFILE &&
requested_plugin_mode_ != NP_SEEK)
return true;
int written = TryWriteToPlugin(buf, length, data_offset);
if (written == -1)
return false;
if (written < length) {
// Buffer the remaining data.
size_t remaining = length - written;
size_t previous_size = delivery_data_.size();
delivery_data_.resize(previous_size + remaining);
data_offset_ = data_offset;
memcpy(&delivery_data_[previous_size], buf + written, remaining);
MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
this, &BrowserPluginStream::OnDelayDelivery));
}
return true;
}
void BrowserPluginStream::OnDelayDelivery() {
// It is possible that the plugin stream may have closed before the task
// was hit.
if (!opened_) {
return;
}
int size = static_cast<int>(delivery_data_.size());
int written = TryWriteToPlugin(&delivery_data_.front(), size,
data_offset_);
if (written > 0) {
// Remove the data that we already wrote.
delivery_data_.erase(delivery_data_.begin(),
delivery_data_.begin() + written);
}
}
int BrowserPluginStream::TryWriteToPlugin(const char *buf, const int length,
const int data_offset) {
int byte_offset = 0;
if (data_offset > 0)
data_offset_ = data_offset;
while (byte_offset < length) {
int bytes_remaining = length - byte_offset;
int bytes_to_write = instance_->NPP_WriteReady(&stream_);
if (bytes_to_write > bytes_remaining)
bytes_to_write = bytes_remaining;
if (bytes_to_write == 0)
return byte_offset;
int bytes_consumed = instance_->NPP_Write(
&stream_, data_offset_, bytes_to_write,
const_cast<char*>(buf + byte_offset));
if (bytes_consumed < 0) {
// The plugin failed, which means that we need to close the stream.
Close(NPRES_NETWORK_ERR);
return -1;
}
if (bytes_consumed == 0) {
// The plugin couldn't take all of the data now.
return byte_offset;
}
// The plugin might report more that we gave it.
bytes_consumed = std::min(bytes_consumed, bytes_to_write);
data_offset_ += bytes_consumed;
byte_offset += bytes_consumed;
}
if (close_on_write_data_)
Close(NPRES_DONE);
return length;
}
bool BrowserPluginStream::Close(NPReason reason) {
if (opened_ == true) {
opened_ = false;
if (delivery_data_.size()) {
if (reason == NPRES_DONE) {
// There is more data to be streamed, don't destroy the stream now.
close_on_write_data_ = true;
return true;
} else {
// Stop any pending data from being streamed
delivery_data_.resize(0);
}
}
// If we have a temp file, be sure to close it.
// Also, allow the plugin to access it now.
if (TempFileIsValid()) {
CloseTempFile();
WriteAsFile();
}
if (stream_.ndata != NULL) {
// Stream hasn't been closed yet.
NPError err = instance_->NPP_DestroyStream(&stream_, reason);
DCHECK(err == NPERR_NO_ERROR);
}
}
Notify(reason);
return true;
}
void BrowserPluginStream::Notify(NPReason reason) {
if (notify_needed_) {
instance_->NPP_URLNotify(stream_.url, reason, notify_data_);
notify_needed_ = false;
}
}
} // namespace NPAPI

View File

@ -1,140 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_PLUGIN_STREAM_H
#define _BROWSER_PLUGIN_STREAM_H
#include <string>
#include <vector>
#include "base/file_path.h"
#include "base/ref_counted.h"
#include "third_party/npapi/bindings/npapi.h"
class WebPluginResourceClient;
namespace NPAPI {
class BrowserPluginInstance;
// Base class for a NPAPI stream. Tracks basic elements
// of a stream for NPAPI notifications and stream position.
class BrowserPluginStream : public base::RefCounted<BrowserPluginStream> {
public:
// Create a new BrowserPluginStream object. If needNotify is true, then the
// plugin will be notified when the stream has been fully sent.
BrowserPluginStream(BrowserPluginInstance *instance,
const char *url,
bool need_notify,
void *notify_data);
virtual ~BrowserPluginStream();
// In case of a redirect, this can be called to update the url. But it must
// be called before Open().
void UpdateUrl(const char* url);
// Opens the stream to the Plugin.
// If the mime-type is not specified, we'll try to find one based on the
// mime-types table and the extension (if any) in the URL.
// If the size of the stream is known, use length to set the size. If
// not known, set length to 0.
// The request_is_seekable parameter indicates whether byte range requests
// can be issued on the stream.
bool Open(const std::string &mime_type,
const std::string &headers,
uint32 length,
uint32 last_modified,
bool request_is_seekable);
// Writes to the stream.
int Write(const char *buf, const int len, int data_offset);
// Write the result as a file.
void WriteAsFile();
// Notify the plugin that a stream is complete.
void Notify(NPReason reason);
// Close the stream.
virtual bool Close(NPReason reason);
virtual WebPluginResourceClient* AsResourceClient() { return NULL; }
// Cancels any HTTP requests initiated by the stream.
virtual void CancelRequest() {}
const NPStream* stream() const { return &stream_; }
// setter/getter for the seekable attribute on the stream.
bool seekable() const { return seekable_stream_; }
void set_seekable(bool seekable) { seekable_stream_ = seekable; }
// getters for reading the notification related attributes on the stream.
bool notify_needed() const { return notify_needed_; }
void* notify_data() const { return notify_data_; }
protected:
BrowserPluginInstance* instance() { return instance_.get(); }
// Check if the stream is open.
bool open() { return opened_; }
private:
// Open a temporary file for this stream.
// If successful, will set temp_file_name_, temp_file_handle_, and
// return true.
bool OpenTempFile();
// Closes the temporary file if it is open.
void CloseTempFile();
// Sends the data to the file. Called From WriteToFile.
size_t WriteBytes(const char *buf, size_t length);
// Sends the data to the file if it's open.
bool WriteToFile(const char *buf, size_t length);
// Sends the data to the plugin. If it's not ready, handles buffering it
// and retrying later.
bool WriteToPlugin(const char *buf, const int length, const int data_offset);
// Send the data to the plugin, returning how many bytes it accepted, or -1
// if an error occurred.
int TryWriteToPlugin(const char *buf, const int length, const int data_offset);
// The callback which calls TryWriteToPlugin.
void OnDelayDelivery();
// Returns true if the temp file is valid and open for writing.
bool TempFileIsValid();
private:
NPStream stream_;
std::string headers_;
scoped_refptr<BrowserPluginInstance> instance_;
bool notify_needed_;
void * notify_data_;
bool close_on_write_data_;
uint16 requested_plugin_mode_;
bool opened_;
#if defined(OS_WIN)
char temp_file_name_[MAX_PATH];
HANDLE temp_file_handle_;
#elif defined(OS_POSIX)
FILE* temp_file_;
FilePath temp_file_path_;
#endif
std::vector<char> delivery_data_;
int data_offset_;
bool seekable_stream_;
std::string mime_type_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginStream);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_STREAM_H

View File

@ -1,88 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "browser_plugin_stream_url.h"
#include "browser_plugin_instance.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/plugin_host.h"
namespace NPAPI {
BrowserPluginStreamUrl::BrowserPluginStreamUrl(
int resource_id,
const GURL &url,
BrowserPluginInstance *instance,
bool notify_needed,
void *notify_data)
: BrowserPluginStream(instance, url.spec().c_str(), notify_needed, notify_data),
url_(url),
id_(resource_id) {
}
BrowserPluginStreamUrl::~BrowserPluginStreamUrl() {
}
bool BrowserPluginStreamUrl::Close(NPReason reason) {
CancelRequest();
bool result = BrowserPluginStream::Close(reason);
instance()->RemoveStream(this);
return result;
}
void BrowserPluginStreamUrl::WillSendRequest(const GURL& url) {
url_ = url;
UpdateUrl(url.spec().c_str());
}
void BrowserPluginStreamUrl::DidReceiveResponse(const std::string& mime_type,
const std::string& headers,
uint32 expected_length,
uint32 last_modified,
bool request_is_seekable,
bool* cancel) {
bool opened = Open(mime_type,
headers,
expected_length,
last_modified,
request_is_seekable);
if (!opened) {
instance()->RemoveStream(this);
*cancel = true;
}
}
void BrowserPluginStreamUrl::DidReceiveData(const char* buffer, int length,
int data_offset) {
if (!open())
return;
if (length > 0)
Write(const_cast<char*>(buffer), length, data_offset);
}
void BrowserPluginStreamUrl::DidFinishLoading() {
if (!seekable()) {
Close(NPRES_DONE);
}
}
void BrowserPluginStreamUrl::DidFail() {
Close(NPRES_NETWORK_ERR);
}
void BrowserPluginStreamUrl::CancelRequest() {
if (id_ > 0) {
if (instance()->webplugin()) {
instance()->webplugin()->CancelResource(id_);
}
id_ = 0;
}
}
} // namespace NPAPI

View File

@ -1,70 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_PLUGIN_STREAM_URL_H
#define _BROWSER_PLUGIN_STREAM_URL_H
#include "browser_plugin_stream.h"
#include "webkit/glue/webplugin.h"
#include "googleurl/src/gurl.h"
namespace NPAPI {
class BrowserPluginInstance;
// A NPAPI Stream based on a URL.
class BrowserPluginStreamUrl : public BrowserPluginStream,
public WebPluginResourceClient {
public:
// Create a new stream for sending to the plugin by fetching
// a URL. If notifyNeeded is set, then the plugin will be notified
// when the stream has been fully sent to the plugin. Initialize
// must be called before the object is used.
BrowserPluginStreamUrl(int resource_id,
const GURL &url,
BrowserPluginInstance *instance,
bool notify_needed,
void *notify_data);
virtual ~BrowserPluginStreamUrl();
// Stop sending the stream to the client.
// Overrides the base Close so we can cancel our fetching the URL if
// it is still loading.
virtual bool Close(NPReason reason);
virtual WebPluginResourceClient* AsResourceClient() {
return static_cast<WebPluginResourceClient*>(this);
}
virtual void CancelRequest();
//
// WebPluginResourceClient methods
//
void WillSendRequest(const GURL& url);
void DidReceiveResponse(const std::string& mime_type,
const std::string& headers,
uint32 expected_length,
uint32 last_modified,
bool request_is_seekable,
bool* cancel);
void DidReceiveData(const char* buffer, int length, int data_offset);
void DidFinishLoading();
void DidFail();
bool IsMultiByteResponseExpected() {
return seekable();
}
private:
GURL url_;
int id_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginStreamUrl);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_STREAM_URL_H

View File

@ -1,99 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "browser_plugin_stream.h"
#include "browser_plugin_instance.h"
#include "base/logging.h"
namespace NPAPI {
BrowserPluginStream::BrowserPluginStream(
BrowserPluginInstance *instance,
const char *url,
bool need_notify,
void *notify_data)
: instance_(instance),
notify_needed_(need_notify),
notify_data_(notify_data),
close_on_write_data_(false),
opened_(false),
requested_plugin_mode_(NP_NORMAL),
temp_file_handle_(INVALID_HANDLE_VALUE),
seekable_stream_(false),
data_offset_(0) {
memset(&stream_, 0, sizeof(stream_));
stream_.url = _strdup(url);
temp_file_name_[0] = '\0';
}
void BrowserPluginStream::UpdateUrl(const char* url) {
DCHECK(!opened_);
free(const_cast<char*>(stream_.url));
stream_.url = _strdup(url);
}
void BrowserPluginStream::WriteAsFile() {
if (requested_plugin_mode_ == NP_ASFILE ||
requested_plugin_mode_ == NP_ASFILEONLY)
instance_->NPP_StreamAsFile(&stream_, temp_file_name_);
}
size_t BrowserPluginStream::WriteBytes(const char *buf, size_t length) {
DWORD bytes;
if (!WriteFile(temp_file_handle_, buf, length, &bytes, 0))
return 0U;
return static_cast<size_t>(bytes);
}
bool BrowserPluginStream::OpenTempFile() {
DCHECK(temp_file_handle_ == INVALID_HANDLE_VALUE);
// The reason for using all the Ascii versions of these filesystem
// calls is that the filename which we pass back to the plugin
// via NPAPI is an ascii filename. Otherwise, we'd use wide-chars.
//
// TODO:
// This is a bug in NPAPI itself, and it needs to be fixed.
// The case which will fail is if a user has a multibyte name,
// but has the system locale set to english. GetTempPathA will
// return junk in this case, causing us to be unable to open the
// file.
char temp_directory[MAX_PATH];
if (GetTempPathA(MAX_PATH, temp_directory) == 0)
return false;
if (GetTempFileNameA(temp_directory, "npstream", 0, temp_file_name_) == 0)
return false;
temp_file_handle_ = CreateFileA(temp_file_name_,
FILE_ALL_ACCESS,
FILE_SHARE_READ,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if (temp_file_handle_ == INVALID_HANDLE_VALUE) {
temp_file_name_[0] = '\0';
return false;
}
return true;
}
void BrowserPluginStream::CloseTempFile() {
if (temp_file_handle_ != INVALID_HANDLE_VALUE) {
CloseHandle(temp_file_handle_);
temp_file_handle_ = INVALID_HANDLE_VALUE;
}
}
bool BrowserPluginStream::TempFileIsValid() {
return temp_file_handle_ != INVALID_HANDLE_VALUE;
}
} // namespace NPAPI

View File

@ -1,34 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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.
#include "precompiled_libcef.h"
#include "browser_plugin_string_stream.h"
namespace NPAPI {
BrowserPluginStringStream::BrowserPluginStringStream(
BrowserPluginInstance *instance,
const std::string &url,
bool notify_needed,
void *notify_data)
: BrowserPluginStream(instance, url.c_str(), notify_needed, notify_data) {
}
BrowserPluginStringStream::~BrowserPluginStringStream() {
}
void BrowserPluginStringStream::SendToPlugin(const std::string &data,
const std::string &mime_type) {
int length = static_cast<int>(data.length());
if (Open(mime_type, std::string(), length, 0, false)) {
// TODO - check if it was not fully sent, and figure out a backup plan.
int written = Write(data.c_str(), length, 0);
NPReason reason = written == length ? NPRES_DONE : NPRES_NETWORK_ERR;
Close(reason);
}
}
}

View File

@ -1,39 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_PLUGIN_STRING_STREAM_H
#define _BROWSER_PLUGIN_STRING_STREAM_H
#include "browser_plugin_stream.h"
namespace NPAPI {
class BrowserPluginInstance;
// An NPAPI stream from a string.
class BrowserPluginStringStream : public BrowserPluginStream {
public:
// Create a new stream for sending to the plugin.
// If notify_needed, will notify the plugin after the data has
// all been sent.
BrowserPluginStringStream(BrowserPluginInstance *instance,
const std::string &url,
bool notify_needed,
void *notify_data);
virtual ~BrowserPluginStringStream();
// Initiates the sending of data to the plugin.
void SendToPlugin(const std::string &data,
const std::string &mime_type);
private:
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginStringStream);
};
} // namespace NPAPI
#endif // _BROWSER_PLUGIN_STRING_STREAM_H

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +0,0 @@
// Copyright (c) 2008 The Chromium Embedded Framework Authors.
// Portions 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 _BROWSER_WEBPLUGIN_DELEGATE_IMPL_H
#define _BROWSER_WEBPLUGIN_DELEGATE_IMPL_H
#include <string>
#include <list>
#include "browser_plugin_lib.h"
#include "base/file_path.h"
#include "base/gfx/native_widget_types.h"
#include "base/iat_patch.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "third_party/npapi/bindings/npapi.h"
#include "webkit/glue/webplugin_delegate.h"
#include "webkit/glue/webcursor.h"
namespace NPAPI {
class BrowserPluginInstance;
};
// An implementation of WebPluginDelegate that proxies all calls to
// the plugin process.
class BrowserWebPluginDelegateImpl : public WebPluginDelegate {
public:
static BrowserWebPluginDelegateImpl* Create(const struct CefPluginInfo& plugin_info,
const std::string& mime_type,
gfx::NativeView containing_view);
static bool IsPluginDelegateWindow(HWND window);
static bool GetPluginNameFromWindow(HWND window, std::wstring *plugin_name);
// Returns true if the window handle passed in is that of the dummy
// activation window for windowless plugins.
static bool IsDummyActivationWindow(HWND window);
// WebPluginDelegate implementation
virtual void PluginDestroyed();
virtual bool Initialize(const GURL& url,
char** argn,
char** argv,
int argc,
WebPlugin* plugin,
bool load_manually);
virtual void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
virtual void Paint(HDC hdc, const gfx::Rect& rect);
virtual void Print(HDC hdc);
virtual void SetFocus(); // only called when windowless
// only called when windowless
virtual bool HandleEvent(NPEvent* event,
WebCursor* cursor);
virtual NPObject* GetPluginScriptableObject();
virtual void DidFinishLoadWithReason(NPReason reason);
virtual int GetProcessId();
virtual void FlushGeometryUpdates() {
}
virtual void SendJavaScriptStream(const std::string& url,
const std::wstring& result,
bool success, bool notify_needed,
int notify_data);
virtual void DidReceiveManualResponse(const std::string& url,
const std::string& mime_type,
const std::string& headers,
uint32 expected_length,
uint32 last_modified);
virtual void DidReceiveManualData(const char* buffer, int length);
virtual void DidFinishManualLoading();
virtual void DidManualLoadFail();
virtual FilePath GetPluginPath();
virtual void InstallMissingPlugin();
virtual WebPluginResourceClient* CreateResourceClient(int resource_id,
const std::string &url,
bool notify_needed,
void *notify_data,
void* stream);
virtual void URLRequestRouted(const std::string&url, bool notify_needed,
void* notify_data);
bool windowless() const { return windowless_ ; }
gfx::Rect rect() const { return window_rect_; }
gfx::Rect clip_rect() const { return clip_rect_; }
enum PluginQuirks {
PLUGIN_QUIRK_SETWINDOW_TWICE = 1,
PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE = 2,
PLUGIN_QUIRK_DONT_CALL_WND_PROC_RECURSIVELY = 4,
PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY = 8,
PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES = 16,
PLUGIN_QUIRK_DIE_AFTER_UNLOAD = 32,
PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU = 64,
PLUGIN_QUIRK_PATCH_SETCURSOR = 128,
PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS = 256,
};
int quirks() { return quirks_; }
private:
BrowserWebPluginDelegateImpl(gfx::NativeView containing_view,
NPAPI::BrowserPluginInstance *instance);
~BrowserWebPluginDelegateImpl();
//--------------------------
// used for windowed plugins
void WindowedUpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
// Create the native window.
// Returns true if the window is created (or already exists).
// Returns false if unable to create the window.
bool WindowedCreatePlugin();
// Destroy the native window.
void WindowedDestroyWindow();
// Reposition the native window to be in sync with the given geometry.
// Returns true if the native window has moved or been clipped differently.
bool WindowedReposition(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
// Tells the plugin about the current state of the window.
// See NPAPI NPP_SetWindow for more information.
void WindowedSetWindow();
// Registers the window class for our window
ATOM RegisterNativeWindowClass();
// Our WndProc functions.
static LRESULT CALLBACK DummyWindowProc(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK NativeWndProc(
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
static LRESULT CALLBACK FlashWindowlessWndProc(
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
// Used for throttling Flash messages.
static void ClearThrottleQueueForWindow(HWND window);
static void OnThrottleMessage();
static void ThrottleMessage(WNDPROC proc, HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
//----------------------------
// used for windowless plugins
void WindowlessUpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
void WindowlessPaint(HDC hdc, const gfx::Rect& rect);
// Tells the plugin about the current state of the window.
// See NPAPI NPP_SetWindow for more information.
void WindowlessSetWindow(bool force_set_window);
//-----------------------------------------
// used for windowed and windowless plugins
NPAPI::BrowserPluginInstance* instance() { return instance_.get(); }
// Closes down and destroys our plugin instance.
void DestroyInstance();
// used for windowed plugins
HWND windowed_handle_;
bool windowed_did_set_window_;
gfx::Rect windowed_last_pos_;
// this is an optimization to avoid calling SetWindow to the plugin
// when it is not necessary. Initially, we need to call SetWindow,
// and after that we only need to call it when the geometry changes.
// use this flag to indicate whether we really need it or not.
bool windowless_needs_set_window_;
// used by windowed and windowless plugins
bool windowless_;
WebPlugin* plugin_;
scoped_refptr<NPAPI::BrowserPluginInstance> instance_;
// Original wndproc before we subclassed.
WNDPROC plugin_wnd_proc_;
// Used to throttle WM_USER+1 messages in Flash.
uint32 last_message_;
bool is_calling_wndproc;
HWND parent_;
NPWindow window_;
gfx::Rect window_rect_;
gfx::Rect clip_rect_;
std::vector<gfx::Rect> cutout_rects_;
int quirks_;
// Windowless plugins don't have keyboard focus causing issues with the
// plugin not receiving keyboard events if the plugin enters a modal
// loop like TrackPopupMenuEx or MessageBox, etc.
// This is a basic issue with windows activation and focus arising due to
// the fact that these windows are created by different threads. Activation
// and focus are thread specific states, and if the browser has focus,
// the plugin may not have focus.
// To fix a majority of these activation issues we create a dummy visible
// child window to which we set focus whenever the windowless plugin
// receives a WM_LBUTTONDOWN/WM_RBUTTONDOWN message via NPP_HandleEvent.
HWND dummy_window_for_activation_;
bool CreateDummyWindowForActivation();
static std::list<MSG> throttle_queue_;
// Returns true if the event passed in needs to be tracked for a potential
// modal loop.
static bool ShouldTrackEventForModalLoops(NPEvent* event);
// The message filter hook procedure, which tracks modal loops entered by
// a plugin in the course of a NPP_HandleEvent call.
static LRESULT CALLBACK HandleEventMessageFilterHook(int code, WPARAM wParam,
LPARAM lParam);
// Called by the message filter hook when the plugin enters a modal loop.
void OnModalLoopEntered();
// Returns true if the message passed in corresponds to a user gesture.
static bool IsUserGestureMessage(unsigned int message);
// Indicates the end of a user gesture period.
void OnUserGestureEnd();
// Handle to the message filter hook
HHOOK handle_event_message_filter_hook_;
// The current instance of the plugin which entered the modal loop.
static BrowserWebPluginDelegateImpl* current_plugin_instance_;
// Event which is set when the plugin enters a modal loop in the course
// of a NPP_HandleEvent call.
HANDLE handle_event_pump_messages_event_;
// Holds the depth of the HandleEvent callstack.
int handle_event_depth_;
// This flag indicates whether we started tracking a user gesture message.
bool user_gesture_message_posted_;
// Runnable Method Factory used to invoke the OnUserGestureEnd method
// asynchronously.
ScopedRunnableMethodFactory<BrowserWebPluginDelegateImpl> user_gesture_msg_factory_;
// The url with which the plugin was instantiated.
std::string plugin_url_;
// The plugin module handle.
HMODULE plugin_module_handle_;
// Helper object for patching the TrackPopupMenu API
static iat_patch::IATPatchFunction iat_patch_track_popup_menu_;
// TrackPopupMenu interceptor. Parameters are the same as the Win32 function
// TrackPopupMenu.
static BOOL WINAPI TrackPopupMenuPatch(HMENU menu, unsigned int flags, int x,
int y, int reserved, HWND window,
const RECT* rect);
// SetCursor interceptor for windowless plugins.
static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor);
// Helper object for patching the SetCursor API
static iat_patch::IATPatchFunction iat_patch_set_cursor_;
// Holds the current cursor set by the windowless plugin.
WebCursor current_windowless_cursor_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserWebPluginDelegateImpl);
};
#endif // #ifndef _BROWSER_WEBPLUGIN_DELEGATE_IMPL_H

View File

@ -37,8 +37,24 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
// Initialize the CEF // Initialize the CEF
CefInitialize(); CefInitialize();
// Structure providing information about the client plugin.
CefPluginInfo plugin_info;
plugin_info.display_name = L"Client Plugin";
plugin_info.unique_name = L"client_plugin";
plugin_info.version = L"1, 0, 0, 1";
plugin_info.description = L"My Example Client Plugin";
CefPluginMimeType mime_type;
mime_type.mime_type = L"application/x-client-plugin";
mime_type.file_extensions.push_back(L"*");
plugin_info.mime_types.push_back(mime_type);
plugin_info.np_getentrypoints = NP_GetEntryPoints;
plugin_info.np_initialize = NP_Initialize;
plugin_info.np_shutdown = NP_Shutdown;
// Register the internal client plugin // Register the internal client plugin
CefRegisterPlugin(ClientPluginInfo); CefRegisterPlugin(plugin_info);
MSG msg; MSG msg;
HACCEL hAccelTable; HACCEL hAccelTable;

View File

@ -18,21 +18,6 @@ NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs); NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs);
NPError API_CALL NP_Shutdown(void); NPError API_CALL NP_Shutdown(void);
// Structure providing information about the client plugin.
const CefPluginInfo ClientPluginInfo = {
{
L"client_plugin",
L"Client Plugin",
L"My Example Client Plugin",
L"1, 0, 0, 1",
L"application/x-client-plugin",
L"*",
L""
},
NP_GetEntryPoints,
NP_Initialize,
NP_Shutdown
};
// Provides the client plugin functionality. // Provides the client plugin functionality.
class ClientPlugin : public CWindowImpl<ClientPlugin> { class ClientPlugin : public CWindowImpl<ClientPlugin> {