libcef:
- Add support for embedded netscape-style plugins. - Add new webkit_glue VisitedLinkHash() and IsLinkVisited() functions required by underlying chromium changes. cefclient: - Add sample netscape-style plugin implementation and related Plugin item on the Tests menu. - Increase the speed of the update timer so that buttons refresh closer to real-time. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@5 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
d0639c9f4e
commit
a08ad505ad
|
@ -10,3 +10,4 @@ Date | CEF Revision | Chromium Revision
|
||||||
2008-12-02 | /trunk@2 | /trunk@6213
|
2008-12-02 | /trunk@2 | /trunk@6213
|
||||||
2008-12-05 | /trunk@3 | /trunk@6430
|
2008-12-05 | /trunk@3 | /trunk@6430
|
||||||
2008-12-13 | /trunk@4 | /trunk@6968
|
2008-12-13 | /trunk@4 | /trunk@6968
|
||||||
|
2008-12-13 | /trunk@5 | /trunk@6975
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright (c) 2008 Marshall A. Greenblatt. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||||
|
// Framework nor the names of its contributors may be used to endorse
|
||||||
|
// or promote products derived from this software without specific prior
|
||||||
|
// written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _CEF_PLUGIN_H
|
||||||
|
#define _CEF_PLUGIN_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "webkit/glue/plugins/nphostapi.h"
|
||||||
|
#include "third_party/npapi/bindings/npapi.h"
|
||||||
|
|
||||||
|
// Netscape plugins are normally built at separate DLLs that are loaded by the
|
||||||
|
// browser when needed. This interface supports the creation of plugins that
|
||||||
|
// are an embedded component of the application. Embedded plugins built using
|
||||||
|
// this interface use the same Netscape Plugin API as DLL-based plugins.
|
||||||
|
// See https://developer.mozilla.org/En/Gecko_Plugin_API_Reference for complete
|
||||||
|
// documentation on how to use the Netscape Plugin API.
|
||||||
|
|
||||||
|
// This structure fully describes a plugin.
|
||||||
|
struct CefPluginVersionInfo {
|
||||||
|
// Unique name used to identify a plugin. The unique name is used in place
|
||||||
|
// of the file path that would be available with normal plugin DLLs.
|
||||||
|
std::wstring unique_name;
|
||||||
|
std::wstring product_name;
|
||||||
|
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.
|
||||||
|
struct CefPluginInfo {
|
||||||
|
CefPluginVersionInfo version_info;
|
||||||
|
NP_GetEntryPointsFunc np_getentrypoints;
|
||||||
|
NP_InitializeFunc np_initialize;
|
||||||
|
NP_ShutdownFunc np_shutdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the plugin with the system.
|
||||||
|
bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info);
|
||||||
|
|
||||||
|
// Unregister the plugin with the system.
|
||||||
|
bool CefUnregisterPlugin(const struct CefPluginInfo& plugin_info);
|
||||||
|
|
||||||
|
#endif // _CEF_PLUGIN_H
|
|
@ -150,4 +150,12 @@ std::string GetDocumentString(WebFrame* frame) {
|
||||||
return StringToStdString(WebCore::createMarkup(core_frame->document()));
|
return StringToStdString(WebCore::createMarkup(core_frame->document()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 VisitedLinkHash(const char* canonical_url, size_t length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinkVisited(uint64 link_hash) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webkit_glue
|
} // namespace webkit_glue
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#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>
|
||||||
|
@ -45,7 +46,9 @@ HCURSOR LoadCursor(int cursor_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
|
bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
|
||||||
return NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
|
NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
|
||||||
|
NPAPI::BrowserPluginList::Singleton()->GetPlugins(refresh, plugins);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnsureFontLoaded(HFONT font) {
|
bool EnsureFontLoaded(HFONT font) {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#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>
|
||||||
|
@ -55,16 +57,33 @@ WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
bool allow_wildcard = true;
|
bool allow_wildcard = true;
|
||||||
WebPluginInfo info;
|
|
||||||
if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
|
|
||||||
allow_wildcard, &info,
|
|
||||||
actual_mime_type))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
|
// first, look for plugins using the normal plugin list
|
||||||
|
WebPluginInfo info;
|
||||||
|
if (NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
|
||||||
|
allow_wildcard, &info,
|
||||||
|
actual_mime_type)) {
|
||||||
if (actual_mime_type && !actual_mime_type->empty())
|
if (actual_mime_type && !actual_mime_type->empty())
|
||||||
return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, hwnd);
|
return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, hwnd);
|
||||||
else
|
else
|
||||||
return WebPluginDelegateImpl::Create(info.file, mime_type, hwnd);
|
return WebPluginDelegateImpl::Create(info.file, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) {
|
void BrowserWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) {
|
||||||
|
|
|
@ -8,6 +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 "base/at_exit.h"
|
#include "base/at_exit.h"
|
||||||
#include "base/icu_util.h"
|
#include "base/icu_util.h"
|
||||||
|
@ -52,6 +53,48 @@ void CefShutdown()
|
||||||
_Context = NULL;
|
_Context = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info)
|
||||||
|
{
|
||||||
|
if(!_Context.get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CefPluginInfo* pPluginInfo = new CefPluginInfo;
|
||||||
|
*pPluginInfo = plugin_info;
|
||||||
|
|
||||||
|
PostTask(FROM_HERE, NewRunnableMethod(_Context.get(),
|
||||||
|
&CefContext::UIT_RegisterPlugin, pPluginInfo));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefContext::UIT_RegisterPlugin(struct CefPluginInfo* plugin_info)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
NPAPI::BrowserPluginList::Singleton()->AddPlugin(*plugin_info);
|
||||||
|
delete plugin_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister the plugin with the system.
|
||||||
|
bool CefUnregisterPlugin(const struct CefPluginInfo& plugin_info)
|
||||||
|
{
|
||||||
|
if(!_Context.get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CefPluginInfo* pPluginInfo = new CefPluginInfo;
|
||||||
|
*pPluginInfo = plugin_info;
|
||||||
|
|
||||||
|
PostTask(FROM_HERE, NewRunnableMethod(_Context.get(),
|
||||||
|
&CefContext::UIT_UnregisterPlugin, pPluginInfo));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefContext::UIT_UnregisterPlugin(struct CefPluginInfo* plugin_info)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
NPAPI::BrowserPluginList::Singleton()->RemovePlugin(*plugin_info);
|
||||||
|
delete plugin_info;
|
||||||
|
}
|
||||||
|
|
||||||
StringPiece GetRawDataResource(HMODULE module, int resource_id) {
|
StringPiece GetRawDataResource(HMODULE module, int resource_id) {
|
||||||
void* data_ptr;
|
void* data_ptr;
|
||||||
|
|
|
@ -38,6 +38,13 @@ public:
|
||||||
// Returns true if the calling thread is the same as the UI thread
|
// Returns true if the calling thread is the same as the UI thread
|
||||||
bool RunningOnUIThread() { return (GetCurrentThreadId() == idthreadui_); }
|
bool RunningOnUIThread() { return (GetCurrentThreadId() == idthreadui_); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// ALL UIT_* METHODS MUST ONLY BE CALLED ON THE UI THREAD //
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void UIT_RegisterPlugin(struct CefPluginInfo* plugin_info);
|
||||||
|
void UIT_UnregisterPlugin(struct CefPluginInfo* plugin_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetMessageLoopForUI(MessageLoopForUI* loop);
|
void SetMessageLoopForUI(MessageLoopForUI* loop);
|
||||||
void NotifyEvent();
|
void NotifyEvent();
|
||||||
|
|
|
@ -184,6 +184,10 @@
|
||||||
RelativePath="..\include\cef.h"
|
RelativePath="..\include\cef.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\cef_nplugin.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\include\cef_ptr.h"
|
RelativePath="..\include\cef_ptr.h"
|
||||||
>
|
>
|
||||||
|
@ -193,6 +197,78 @@
|
||||||
>
|
>
|
||||||
</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"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,373 @@
|
||||||
|
// 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
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
// 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
|
||||||
|
|
|
@ -0,0 +1,512 @@
|
||||||
|
// 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/message_loop.h"
|
||||||
|
#include "base/string_util.h"
|
||||||
|
#include "base/thread_local_storage.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
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO(evanm): don't rely on static initialization.
|
||||||
|
ThreadLocalStorage::Slot BrowserPluginInstance::plugin_instance_tls_index_;
|
||||||
|
|
||||||
|
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(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, &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 =
|
||||||
|
static_cast<BrowserPluginInstance*>(plugin_instance_tls_index_.Get());
|
||||||
|
plugin_instance_tls_index_.Set(instance);
|
||||||
|
return old_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserPluginInstance* BrowserPluginInstance::GetInitializingInstance() {
|
||||||
|
BrowserPluginInstance* instance =
|
||||||
|
static_cast<BrowserPluginInstance*>(plugin_instance_tls_index_.Get());
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -0,0 +1,268 @@
|
||||||
|
// 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 "base/thread_local_storage.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_;
|
||||||
|
// Using TLS to store BrowserPluginInstance 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 ThreadLocalStorage::Slot plugin_instance_tls_index_;
|
||||||
|
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
|
|
@ -0,0 +1,175 @@
|
||||||
|
// 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->file] = 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_->file);
|
||||||
|
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->file = StringToLowerASCII(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
|
|
@ -0,0 +1,89 @@
|
||||||
|
// 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
|
|
@ -0,0 +1,159 @@
|
||||||
|
// 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().file == 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
|
|
@ -0,0 +1,99 @@
|
||||||
|
// 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
|
||||||
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
// 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) {
|
||||||
|
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 (!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
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
// 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.
|
||||||
|
bool Open(const std::string &mime_type,
|
||||||
|
const std::string &headers,
|
||||||
|
uint32 length,
|
||||||
|
uint32 last_modified);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
// 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* cancel) {
|
||||||
|
bool opened = Open(mime_type,
|
||||||
|
headers,
|
||||||
|
expected_length,
|
||||||
|
last_modified);
|
||||||
|
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
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
// 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* cancel);
|
||||||
|
void DidReceiveData(const char* buffer, int length, int data_offset);
|
||||||
|
void DidFinishLoading();
|
||||||
|
void DidFail();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
GURL url_;
|
||||||
|
int id_;
|
||||||
|
|
||||||
|
DISALLOW_EVIL_CONSTRUCTORS(BrowserPluginStreamUrl);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace NPAPI
|
||||||
|
|
||||||
|
#endif // _BROWSER_PLUGIN_STREAM_URL_H
|
|
@ -0,0 +1,99 @@
|
||||||
|
// 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
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
// 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)) {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
// 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
|
@ -0,0 +1,283 @@
|
||||||
|
// 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/iat_patch.h"
|
||||||
|
#include "base/ref_counted.h"
|
||||||
|
#include "base/task.h"
|
||||||
|
#include "webkit/glue/webplugin_delegate.h"
|
||||||
|
#include "third_party/npapi/bindings/npapi.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,
|
||||||
|
HWND containing_window);
|
||||||
|
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,
|
||||||
|
const std::vector<gfx::Rect>& cutout_rects,
|
||||||
|
bool visible);
|
||||||
|
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 std::wstring 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,
|
||||||
|
};
|
||||||
|
|
||||||
|
int quirks() { return quirks_; }
|
||||||
|
|
||||||
|
static void MoveWindow(HWND window,
|
||||||
|
const gfx::Rect& window_rect,
|
||||||
|
const gfx::Rect& clip_rect,
|
||||||
|
const std::vector<gfx::Rect>& cutout_rects,
|
||||||
|
bool visible);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BrowserWebPluginDelegateImpl(HWND containing_window,
|
||||||
|
NPAPI::BrowserPluginInstance *instance);
|
||||||
|
~BrowserWebPluginDelegateImpl();
|
||||||
|
|
||||||
|
//--------------------------
|
||||||
|
// used for windowed plugins
|
||||||
|
void WindowedUpdateGeometry(const gfx::Rect& window_rect,
|
||||||
|
const gfx::Rect& clip_rect,
|
||||||
|
const std::vector<gfx::Rect>& cutout_rects,
|
||||||
|
bool visible);
|
||||||
|
// 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,
|
||||||
|
const std::vector<gfx::Rect>& cutout_rects,
|
||||||
|
bool visible);
|
||||||
|
|
||||||
|
// 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_;
|
||||||
|
|
||||||
|
// We only move/size the plugin window once after its creation. The
|
||||||
|
// rest of the moves are controlled by the browser. This flag controls
|
||||||
|
// this behaviour.
|
||||||
|
bool initial_plugin_resize_done_;
|
||||||
|
|
||||||
|
// 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_;
|
||||||
|
|
||||||
|
// Indicates whether we IAT patched the TrackPopupMenu function.
|
||||||
|
static bool track_popup_menu_patched_;
|
||||||
|
|
||||||
|
// Helper object for patching the import table of Silverlight.
|
||||||
|
static iat_patch::IATPatchFunction iat_patch_helper_;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
DISALLOW_EVIL_CONSTRUCTORS(BrowserWebPluginDelegateImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifndef _BROWSER_WEBPLUGIN_DELEGATE_IMPL_H
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "cefclient.h"
|
#include "cefclient.h"
|
||||||
|
#include "clientplugin.h"
|
||||||
#include "cef.h"
|
#include "cef.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -36,6 +37,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
||||||
// Initialize the CEF
|
// Initialize the CEF
|
||||||
CefInitialize();
|
CefInitialize();
|
||||||
|
|
||||||
|
// Register the internal client plugin
|
||||||
|
CefRegisterPlugin(ClientPluginInfo);
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
HACCEL hAccelTable;
|
HACCEL hAccelTable;
|
||||||
|
|
||||||
|
@ -716,7 +720,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
L"http://www.google.com");
|
L"http://www.google.com");
|
||||||
|
|
||||||
// Start the timer that will be used to update child window state
|
// Start the timer that will be used to update child window state
|
||||||
SetTimer(hWnd, 1, 500, NULL);
|
SetTimer(hWnd, 1, 250, NULL);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -781,6 +785,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
browser->LoadString(html, L"about:blank");
|
browser->LoadString(html, L"about:blank");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
case ID_TESTS_PLUGIN: // Test our custom plugin
|
||||||
|
if(browser.get())
|
||||||
|
{
|
||||||
|
std::wstring html =
|
||||||
|
L"<html><body>Client Plugin:<br>"
|
||||||
|
L"<embed type=\"application/x-client-plugin\""
|
||||||
|
L"width=600 height=40>"
|
||||||
|
L"</body></html>";
|
||||||
|
browser->LoadString(html, L"about:blank");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -58,6 +58,7 @@ BEGIN
|
||||||
POPUP "Tests"
|
POPUP "Tests"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "JavaScript", ID_TESTS_JAVASCRIPT
|
MENUITEM "JavaScript", ID_TESTS_JAVASCRIPT
|
||||||
|
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,14 @@
|
||||||
RelativePath=".\cefclient.rc"
|
RelativePath=".\cefclient.rc"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\clientplugin.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\clientplugin.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Resource.h"
|
RelativePath=".\Resource.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
// 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 "stdafx.h"
|
||||||
|
#include "clientplugin.h"
|
||||||
|
|
||||||
|
// Initialized in NP_Initialize.
|
||||||
|
NPNetscapeFuncs* g_browser = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
NPError NPP_New(NPMIMEType plugin_type, NPP instance, uint16 mode, int16 argc,
|
||||||
|
char* argn[], char* argv[], NPSavedData* saved) {
|
||||||
|
if (instance == NULL)
|
||||||
|
return NPERR_INVALID_INSTANCE_ERROR;
|
||||||
|
|
||||||
|
ClientPlugin* plugin_impl = new ClientPlugin(mode);
|
||||||
|
plugin_impl->Initialize(GetModuleHandle(NULL), instance, plugin_type, argc,
|
||||||
|
argn, argv);
|
||||||
|
instance->pdata = reinterpret_cast<void*>(plugin_impl);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError NPP_Destroy(NPP instance, NPSavedData** save) {
|
||||||
|
ClientPlugin* plugin_impl = reinterpret_cast<ClientPlugin*>(instance->pdata);
|
||||||
|
|
||||||
|
if (plugin_impl) {
|
||||||
|
plugin_impl->Shutdown();
|
||||||
|
delete plugin_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError NPP_SetWindow(NPP instance, NPWindow* window_info) {
|
||||||
|
if (instance == NULL)
|
||||||
|
return NPERR_INVALID_INSTANCE_ERROR;
|
||||||
|
|
||||||
|
if (window_info == NULL)
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
|
||||||
|
ClientPlugin* plugin_impl = reinterpret_cast<ClientPlugin*>(instance->pdata);
|
||||||
|
|
||||||
|
if (plugin_impl == NULL)
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
|
||||||
|
HWND window_handle = reinterpret_cast<HWND>(window_info->window);
|
||||||
|
if (!plugin_impl->SetWindow(window_handle)) {
|
||||||
|
delete plugin_impl;
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
|
||||||
|
{
|
||||||
|
pFuncs->newp = NPP_New;
|
||||||
|
pFuncs->destroy = NPP_Destroy;
|
||||||
|
pFuncs->setwindow = NPP_SetWindow;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs)
|
||||||
|
{
|
||||||
|
g_browser = pFuncs;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError API_CALL NP_Shutdown(void)
|
||||||
|
{
|
||||||
|
g_browser = NULL;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ClientPlugin Implementation
|
||||||
|
|
||||||
|
ClientPlugin::ClientPlugin(int16 mode)
|
||||||
|
: mode_(mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientPlugin::~ClientPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientPlugin::Initialize(HINSTANCE module_handle, NPP instance,
|
||||||
|
NPMIMEType mime_type, int16 argc, char* argn[],
|
||||||
|
char* argv[])
|
||||||
|
{
|
||||||
|
RefreshDisplay();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientPlugin::SetWindow(HWND parent_window)
|
||||||
|
{
|
||||||
|
if (!::IsWindow(parent_window)) {
|
||||||
|
// No window created yet. Ignore this call.
|
||||||
|
if (!IsWindow())
|
||||||
|
return true;
|
||||||
|
// Parent window has been destroyed.
|
||||||
|
Shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT parent_rect;
|
||||||
|
|
||||||
|
if (IsWindow()) {
|
||||||
|
::GetClientRect(parent_window, &parent_rect);
|
||||||
|
SetWindowPos(NULL, &parent_rect, SWP_SHOWWINDOW);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// First time in -- no window created by plugin yet.
|
||||||
|
::GetClientRect(parent_window, &parent_rect);
|
||||||
|
Create(parent_window, parent_rect, NULL, WS_CHILD | WS_BORDER);
|
||||||
|
|
||||||
|
UpdateWindow();
|
||||||
|
ShowWindow(SW_SHOW);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPlugin::Shutdown()
|
||||||
|
{
|
||||||
|
if (IsWindow()) {
|
||||||
|
DestroyWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT ClientPlugin::OnPaint(UINT message, WPARAM wparam, LPARAM lparam,
|
||||||
|
BOOL& handled)
|
||||||
|
{
|
||||||
|
static LPCWSTR text = L"Left click in the green area for a message box!";
|
||||||
|
|
||||||
|
PAINTSTRUCT paint_struct;
|
||||||
|
BeginPaint(&paint_struct);
|
||||||
|
|
||||||
|
RECT client_rect;
|
||||||
|
GetClientRect(&client_rect);
|
||||||
|
|
||||||
|
int old_mode = SetBkMode(paint_struct.hdc, TRANSPARENT);
|
||||||
|
COLORREF old_color = SetTextColor(paint_struct.hdc, RGB(0, 0, 255));
|
||||||
|
|
||||||
|
RECT text_rect = client_rect;
|
||||||
|
DrawText(paint_struct.hdc, text, -1, &text_rect, DT_CENTER | DT_CALCRECT);
|
||||||
|
|
||||||
|
client_rect.top = ((client_rect.bottom - client_rect.top)
|
||||||
|
- (text_rect.bottom - text_rect.top)) / 2;
|
||||||
|
DrawText(paint_struct.hdc, text, -1, &client_rect, DT_CENTER);
|
||||||
|
|
||||||
|
SetBkMode(paint_struct.hdc, old_mode);
|
||||||
|
SetTextColor(paint_struct.hdc, old_color);
|
||||||
|
|
||||||
|
EndPaint(&paint_struct);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT ClientPlugin::OnEraseBackGround(UINT message, WPARAM wparam,
|
||||||
|
LPARAM lparam, BOOL& handled)
|
||||||
|
{
|
||||||
|
HDC paint_device_context = reinterpret_cast<HDC>(wparam);
|
||||||
|
RECT erase_rect;
|
||||||
|
GetClipBox(paint_device_context, &erase_rect);
|
||||||
|
HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
|
||||||
|
FillRect(paint_device_context, &erase_rect, brush);
|
||||||
|
DeleteObject(brush);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT ClientPlugin::OnLButtonDown(UINT message, WPARAM wparam, LPARAM lparam,
|
||||||
|
BOOL& handled)
|
||||||
|
{
|
||||||
|
MessageBox(L"You clicked on the client plugin!", L"Client Plugin", MB_OK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPlugin::RefreshDisplay() {
|
||||||
|
if (!IsWindow())
|
||||||
|
return;
|
||||||
|
|
||||||
|
InvalidateRect(NULL, TRUE);
|
||||||
|
UpdateWindow();
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Portions of this implementation are borrowed from webkit\default_plugin\
|
||||||
|
// plugin_impl.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atlbase.h>
|
||||||
|
#include <atlwin.h>
|
||||||
|
#include "cef_nplugin.h"
|
||||||
|
|
||||||
|
extern NPNetscapeFuncs* g_browser;
|
||||||
|
|
||||||
|
NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||||
|
NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs);
|
||||||
|
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.
|
||||||
|
class ClientPlugin : public CWindowImpl<ClientPlugin> {
|
||||||
|
public:
|
||||||
|
// mode is the plugin instantiation mode, i.e. whether it is a full
|
||||||
|
// page plugin (NP_FULL) or an embedded plugin (NP_EMBED)
|
||||||
|
explicit ClientPlugin(int16 mode);
|
||||||
|
virtual ~ClientPlugin();
|
||||||
|
|
||||||
|
BEGIN_MSG_MAP(ClientPlugin)
|
||||||
|
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackGround)
|
||||||
|
MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
||||||
|
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
||||||
|
END_MSG_MAP()
|
||||||
|
|
||||||
|
// Initializes the plugin with the instance information, mime type
|
||||||
|
// and the list of parameters passed down to the plugin from the webpage.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// module_handle
|
||||||
|
// The handle to the dll in which this object is instantiated.
|
||||||
|
// instance
|
||||||
|
// The plugins opaque instance handle.
|
||||||
|
// mime_type
|
||||||
|
// Identifies the third party plugin which would be eventually installed.
|
||||||
|
// argc
|
||||||
|
// Indicates the count of arguments passed in from the webpage.
|
||||||
|
// argv
|
||||||
|
// Pointer to the arguments.
|
||||||
|
// Returns true on success.
|
||||||
|
bool Initialize(HINSTANCE module_handle, NPP instance, NPMIMEType mime_type,
|
||||||
|
int16 argc, char* argn[], char* argv[]);
|
||||||
|
|
||||||
|
// Displays the default plugin UI.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// parent_window
|
||||||
|
// Handle to the parent window.
|
||||||
|
bool SetWindow(HWND parent_window);
|
||||||
|
|
||||||
|
// Destroys the install dialog and the plugin window.
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
HWND window() const { return m_hWnd; }
|
||||||
|
|
||||||
|
// Getter for the NPP instance member.
|
||||||
|
const NPP instance() const {
|
||||||
|
return instance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Window message handlers.
|
||||||
|
LRESULT OnPaint(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled);
|
||||||
|
LRESULT OnEraseBackGround(UINT message, WPARAM wparam, LPARAM lparam,
|
||||||
|
BOOL& handled);
|
||||||
|
LRESULT OnLButtonDown(UINT message, WPARAM wparam, LPARAM lparam,
|
||||||
|
BOOL& handled);
|
||||||
|
|
||||||
|
// Enables the plugin window if required and initiates an update of the
|
||||||
|
// the plugin window.
|
||||||
|
void RefreshDisplay();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The plugins opaque instance handle
|
||||||
|
NPP instance_;
|
||||||
|
// The plugin instantiation mode (NP_FULL or NP_EMBED)
|
||||||
|
int16 mode_;
|
||||||
|
};
|
|
@ -22,6 +22,7 @@
|
||||||
#define IDC_NAV_RELOAD 202
|
#define IDC_NAV_RELOAD 202
|
||||||
#define IDC_NAV_STOP 203
|
#define IDC_NAV_STOP 203
|
||||||
#define ID_TESTS_JAVASCRIPT 32771
|
#define ID_TESTS_JAVASCRIPT 32771
|
||||||
|
#define ID_TESTS_PLUGIN 32772
|
||||||
#define IDC_STATIC -1
|
#define IDC_STATIC -1
|
||||||
#define IDS_LOGO 1000
|
#define IDS_LOGO 1000
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NO_MFC 1
|
#define _APS_NO_MFC 1
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32772
|
#define _APS_NEXT_COMMAND_VALUE 32773
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
#define _APS_NEXT_SYMED_VALUE 110
|
#define _APS_NEXT_SYMED_VALUE 110
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue