diff options
Diffstat (limited to 'webkit/glue/plugins/plugin_host.cc')
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 1111 |
1 files changed, 0 insertions, 1111 deletions
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc deleted file mode 100644 index 28aba02..0000000 --- a/webkit/glue/plugins/plugin_host.cc +++ /dev/null @@ -1,1111 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/plugin_host.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" -#if defined(OS_MACOSX) -#include "base/sys_info.h" -#endif -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" -#include "net/base/net_util.h" -#include "third_party/npapi/bindings/npapi_extensions.h" -#include "third_party/npapi/bindings/npruntime.h" -#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" -#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" -#include "webkit/glue/webkit_glue.h" -#include "webkit/glue/plugins/default_plugin_shared.h" -#include "webkit/glue/plugins/npapi_extension_thunk.h" -#include "webkit/glue/plugins/plugin_instance.h" -#include "webkit/glue/plugins/plugin_lib.h" -#include "webkit/glue/plugins/plugin_list.h" -#include "webkit/glue/plugins/plugin_stream_url.h" -#include "webkit/glue/plugins/webplugin_delegate.h" -#include "webkit/glue/plugins/webplugininfo.h" - -using WebKit::WebBindings; - -// Finds a PluginInstance from an NPP. -// The caller must take a reference if needed. -static NPAPI::PluginInstance* FindInstance(NPP id) { - if (id == NULL) { - return NULL; - } - return reinterpret_cast<NPAPI::PluginInstance*>(id->ndata); -} - -#if defined(OS_MACOSX) -// Returns true if the OS supports shared accelerated surfaces via IOSurface. -// This is true on Snow Leopard and higher. -static bool SupportsSharingAcceleratedSurfaces() { - int32 major, minor, bugfix; - base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); - return major > 10 || (major == 10 && minor > 5); -} -#endif - -namespace NPAPI { - -scoped_refptr<PluginHost> PluginHost::singleton_; - -PluginHost::PluginHost() { - InitializeHostFuncs(); -} - -PluginHost::~PluginHost() { -} - -PluginHost *PluginHost::Singleton() { - if (singleton_.get() == NULL) { - singleton_ = new PluginHost(); - } - - DCHECK(singleton_.get() != NULL); - return singleton_; -} - -void PluginHost::InitializeHostFuncs() { - memset(&host_funcs_, 0, sizeof(host_funcs_)); - host_funcs_.size = sizeof(host_funcs_); - host_funcs_.version = (NP_VERSION_MAJOR << 8) | (NP_VERSION_MINOR); - - // The "basic" functions - host_funcs_.geturl = &NPN_GetURL; - host_funcs_.posturl = &NPN_PostURL; - host_funcs_.requestread = &NPN_RequestRead; - host_funcs_.newstream = &NPN_NewStream; - host_funcs_.write = &NPN_Write; - host_funcs_.destroystream = &NPN_DestroyStream; - host_funcs_.status = &NPN_Status; - host_funcs_.uagent = &NPN_UserAgent; - host_funcs_.memalloc = &NPN_MemAlloc; - host_funcs_.memfree = &NPN_MemFree; - host_funcs_.memflush = &NPN_MemFlush; - host_funcs_.reloadplugins = &NPN_ReloadPlugins; - - // We don't implement java yet - host_funcs_.getJavaEnv = &NPN_GetJavaEnv; - host_funcs_.getJavaPeer = &NPN_GetJavaPeer; - - // Advanced functions we implement - host_funcs_.geturlnotify = &NPN_GetURLNotify; - host_funcs_.posturlnotify = &NPN_PostURLNotify; - host_funcs_.getvalue = &NPN_GetValue; - host_funcs_.setvalue = &NPN_SetValue; - host_funcs_.invalidaterect = &NPN_InvalidateRect; - host_funcs_.invalidateregion = &NPN_InvalidateRegion; - host_funcs_.forceredraw = &NPN_ForceRedraw; - - // These come from the Javascript Engine - host_funcs_.getstringidentifier = WebBindings::getStringIdentifier; - host_funcs_.getstringidentifiers = WebBindings::getStringIdentifiers; - host_funcs_.getintidentifier = WebBindings::getIntIdentifier; - host_funcs_.identifierisstring = WebBindings::identifierIsString; - host_funcs_.utf8fromidentifier = WebBindings::utf8FromIdentifier; - host_funcs_.intfromidentifier = WebBindings::intFromIdentifier; - host_funcs_.createobject = WebBindings::createObject; - host_funcs_.retainobject = WebBindings::retainObject; - host_funcs_.releaseobject = WebBindings::releaseObject; - host_funcs_.invoke = WebBindings::invoke; - host_funcs_.invokeDefault = WebBindings::invokeDefault; - host_funcs_.evaluate = WebBindings::evaluate; - host_funcs_.getproperty = WebBindings::getProperty; - host_funcs_.setproperty = WebBindings::setProperty; - host_funcs_.removeproperty = WebBindings::removeProperty; - host_funcs_.hasproperty = WebBindings::hasProperty; - host_funcs_.hasmethod = WebBindings::hasMethod; - host_funcs_.releasevariantvalue = WebBindings::releaseVariantValue; - host_funcs_.setexception = WebBindings::setException; - host_funcs_.pushpopupsenabledstate = NPN_PushPopupsEnabledState; - host_funcs_.poppopupsenabledstate = NPN_PopPopupsEnabledState; - host_funcs_.enumerate = WebBindings::enumerate; - host_funcs_.pluginthreadasynccall = NPN_PluginThreadAsyncCall; - host_funcs_.construct = WebBindings::construct; - host_funcs_.getvalueforurl = NPN_GetValueForURL; - host_funcs_.setvalueforurl = NPN_SetValueForURL; - host_funcs_.getauthenticationinfo = NPN_GetAuthenticationInfo; - host_funcs_.scheduletimer = NPN_ScheduleTimer; - host_funcs_.unscheduletimer = NPN_UnscheduleTimer; - host_funcs_.popupcontextmenu = NPN_PopUpContextMenu; - host_funcs_.convertpoint = NPN_ConvertPoint; - host_funcs_.handleevent = NPN_HandleEvent; - host_funcs_.unfocusinstance = NPN_UnfocusInstance; - host_funcs_.urlredirectresponse = NPN_URLRedirectResponse; -} - -void PluginHost::PatchNPNetscapeFuncs(NPNetscapeFuncs* overrides) { - // When running in the plugin process, we need to patch the NPN functions - // that the plugin calls to interact with NPObjects that we give. Otherwise - // the plugin will call the v8 NPN functions, which won't work since we have - // an NPObjectProxy and not a real v8 implementation. - if (overrides->invoke) - host_funcs_.invoke = overrides->invoke; - - if (overrides->invokeDefault) - host_funcs_.invokeDefault = overrides->invokeDefault; - - if (overrides->evaluate) - host_funcs_.evaluate = overrides->evaluate; - - if (overrides->getproperty) - host_funcs_.getproperty = overrides->getproperty; - - if (overrides->setproperty) - host_funcs_.setproperty = overrides->setproperty; - - if (overrides->removeproperty) - host_funcs_.removeproperty = overrides->removeproperty; - - if (overrides->hasproperty) - host_funcs_.hasproperty = overrides->hasproperty; - - if (overrides->hasmethod) - host_funcs_.hasmethod = overrides->hasmethod; - - if (overrides->setexception) - host_funcs_.setexception = overrides->setexception; - - if (overrides->enumerate) - host_funcs_.enumerate = overrides->enumerate; -} - -bool PluginHost::SetPostData(const char* buf, - uint32 length, - std::vector<std::string>* names, - std::vector<std::string>* values, - std::vector<char>* body) { - // Use a state table to do the parsing. Whitespace must be - // trimmed after the fact if desired. In our case, we actually - // don't care about the whitespace, because we're just going to - // pass this back into another POST. This function strips out the - // "Content-length" header and does not append it to the request. - - // - // This parser takes action only on state changes. - // - // Transition table: - // : \n NULL Other - // 0 GetHeader 1 2 4 0 - // 1 GetValue 1 0 3 1 - // 2 GetData 2 2 3 2 - // 3 DONE - // 4 ERR - // - enum { INPUT_COLON=0, INPUT_NEWLINE, INPUT_NULL, INPUT_OTHER }; - enum { GETNAME, GETVALUE, GETDATA, DONE, ERR }; - int statemachine[3][4] = { { GETVALUE, GETDATA, GETDATA, GETNAME }, - { GETVALUE, GETNAME, DONE, GETVALUE }, - { GETDATA, GETDATA, DONE, GETDATA } }; - std::string name, value; - const char* ptr = static_cast<const char*>(buf); - const char* start = ptr; - int state = GETNAME; // initial state - bool done = false; - bool err = false; - do { - int input; - - // Translate the current character into an input - // for the state table. - switch (*ptr) { - case ':' : - input = INPUT_COLON; - break; - case '\n': - input = INPUT_NEWLINE; - break; - case 0 : - input = INPUT_NULL; - break; - default : - input = INPUT_OTHER; - break; - } - - int newstate = statemachine[state][input]; - - // Take action based on the new state. - if (state != newstate) { - switch (newstate) { - case GETNAME: - // Got a value. - value = std::string(start, ptr - start); - TrimWhitespace(value, TRIM_ALL, &value); - // If the name field is empty, we'll skip this header - // but we won't error out. - if (!name.empty() && name != "content-length") { - names->push_back(name); - values->push_back(value); - } - start = ptr + 1; - break; - case GETVALUE: - // Got a header. - name = StringToLowerASCII(std::string(start, ptr - start)); - TrimWhitespace(name, TRIM_ALL, &name); - start = ptr + 1; - break; - case GETDATA: { - // Finished headers, now get body - if (*ptr) - start = ptr + 1; - size_t previous_size = body->size(); - size_t new_body_size = length - static_cast<int>(start - buf); - body->resize(previous_size + new_body_size); - if (!body->empty()) - memcpy(&body->front() + previous_size, start, new_body_size); - done = true; - break; - } - case ERR: - // error - err = true; - done = true; - break; - } - } - state = newstate; - ptr++; - } while (!done); - - return !err; -} - -} // namespace NPAPI - -extern "C" { - -// Allocates memory from the host's memory space. -void* NPN_MemAlloc(uint32_t size) { - scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); - if (host != NULL) { - // Note: We must use the same allocator/deallocator - // that is used by the javascript library, as some of the - // JS APIs will pass memory to the plugin which the plugin - // will attempt to free. - return malloc(size); - } - return NULL; -} - -// Deallocates memory from the host's memory space -void NPN_MemFree(void* ptr) { - scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); - if (host != NULL) { - if (ptr != NULL && ptr != reinterpret_cast<void*>(-1)) - free(ptr); - } -} - -// Requests that the host free a specified amount of memory. -uint32_t NPN_MemFlush(uint32_t size) { - // This is not relevant on Windows; MAC specific - return size; -} - -// This is for dynamic discovery of new plugins. -// Should force a re-scan of the plugins directory to load new ones. -void NPN_ReloadPlugins(NPBool reload_pages) { - WebKit::resetPluginCache(reload_pages ? true : false); -} - -// Requests a range of bytes for a seekable stream. -NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { - if (!stream || !range_list) - return NPERR_GENERIC_ERROR; - - scoped_refptr<NPAPI::PluginInstance> plugin( - reinterpret_cast<NPAPI::PluginInstance*>(stream->ndata)); - if (!plugin.get()) - return NPERR_GENERIC_ERROR; - - plugin->RequestRead(stream, range_list); - return NPERR_NO_ERROR; -} - -// Generic form of GetURL for common code between GetURL and GetURLNotify. -static NPError GetURLNotify(NPP id, - const char* url, - const char* target, - bool notify, - void* notify_data) { - if (!url) - return NPERR_INVALID_URL; - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (!plugin.get()) { - return NPERR_GENERIC_ERROR; - } - - plugin->RequestURL(url, "GET", target, NULL, 0, notify, notify_data); - return NPERR_NO_ERROR; -} - -// Requests creation of a new stream with the contents of the -// specified URL; gets notification of the result. -NPError NPN_GetURLNotify(NPP id, - const char* url, - const char* target, - void* notify_data) { - // This is identical to NPN_GetURL, but after finishing, the - // browser will call NPP_URLNotify to inform the plugin that - // it has completed. - - // According to the NPAPI documentation, if target == _self - // or a parent to _self, the browser should return NPERR_INVALID_PARAM, - // because it can't notify the plugin once deleted. This is - // absolutely false; firefox doesn't do this, and Flash relies on - // being able to use this. - - // Also according to the NPAPI documentation, we should return - // NPERR_INVALID_URL if the url requested is not valid. However, - // this would require that we synchronously start fetching the - // URL. That just isn't practical. As such, there really is - // no way to return this error. From looking at the Firefox - // implementation, it doesn't look like Firefox does this either. - - return GetURLNotify(id, url, target, true, notify_data); -} - -NPError NPN_GetURL(NPP id, const char* url, const char* target) { - // Notes: - // Request from the Plugin to fetch content either for the plugin - // or to be placed into a browser window. - // - // If target == null, the browser fetches content and streams to plugin. - // otherwise, the browser loads content into an existing browser frame. - // If the target is the window/frame containing the plugin, the plugin - // may be destroyed. - // If the target is _blank, a mailto: or news: url open content in a new - // browser window - // If the target is _self, no other instance of the plugin is created. The - // plugin continues to operate in its own window - - return GetURLNotify(id, url, target, false, 0); -} - -// Generic form of PostURL for common code between PostURL and PostURLNotify. -static NPError PostURLNotify(NPP id, - const char* url, - const char* target, - uint32_t len, - const char* buf, - NPBool file, - bool notify, - void* notify_data) { - if (!url) - return NPERR_INVALID_URL; - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (!plugin.get()) { - NOTREACHED(); - return NPERR_GENERIC_ERROR; - } - - std::string post_file_contents; - - if (file) { - // Post data to be uploaded from a file. This can be handled in two - // ways. - // 1. Read entire file and send the contents as if it was a post data - // specified in the argument - // 2. Send just the file details and read them in the browser at the - // time of sending the request. - // Approach 2 is more efficient but complicated. Approach 1 has a major - // drawback of sending potentially large data over two IPC hops. In a way - // 'large data over IPC' problem exists as it is in case of plugin giving - // the data directly instead of in a file. - // Currently we are going with the approach 1 to get the feature working. - // We can optimize this later with approach 2. - - // TODO(joshia): Design a scheme to send a file descriptor instead of - // entire file contents across. - - // Security alert: - // --------------- - // Here we are blindly uploading whatever file requested by a plugin. - // This is risky as someone could exploit a plugin to send private - // data in arbitrary locations. - // A malicious (non-sandboxed) plugin has unfeterred access to OS - // resources and can do this anyway without using browser's HTTP stack. - // FWIW, Firefox and Safari don't perform any security checks. - - if (!buf) - return NPERR_FILE_NOT_FOUND; - - std::string file_path_ascii(buf); - FilePath file_path; - static const char kFileUrlPrefix[] = "file:"; - if (StartsWithASCII(file_path_ascii, kFileUrlPrefix, false)) { - GURL file_url(file_path_ascii); - DCHECK(file_url.SchemeIsFile()); - net::FileURLToFilePath(file_url, &file_path); - } else { - file_path = FilePath::FromWStringHack( - base::SysNativeMBToWide(file_path_ascii)); - } - - base::PlatformFileInfo post_file_info = {0}; - if (!file_util::GetFileInfo(file_path, &post_file_info) || - post_file_info.is_directory) - return NPERR_FILE_NOT_FOUND; - - if (!file_util::ReadFileToString(file_path, &post_file_contents)) - return NPERR_FILE_NOT_FOUND; - - buf = post_file_contents.c_str(); - len = post_file_contents.size(); - } - - // The post data sent by a plugin contains both headers - // and post data. Example: - // Content-type: text/html - // Content-length: 200 - // - // <200 bytes of content here> - // - // Unfortunately, our stream needs these broken apart, - // so we need to parse the data and set headers and data - // separately. - plugin->RequestURL(url, "POST", target, buf, len, notify, notify_data); - return NPERR_NO_ERROR; -} - -NPError NPN_PostURLNotify(NPP id, - const char* url, - const char* target, - uint32_t len, - const char* buf, - NPBool file, - void* notify_data) { - return PostURLNotify(id, url, target, len, buf, file, true, notify_data); -} - -NPError NPN_PostURL(NPP id, - const char* url, - const char* target, - uint32_t len, - const char* buf, - NPBool file) { - // POSTs data to an URL, either from a temp file or a buffer. - // If file is true, buf contains a temp file (which host will delete after - // completing), and len contains the length of the filename. - // If file is false, buf contains the data to send, and len contains the - // length of the buffer - // - // If target is null, - // server response is returned to the plugin - // If target is _current, _self, or _top, - // server response is written to the plugin window and plugin is unloaded. - // If target is _new or _blank, - // server response is written to a new browser window - // If target is an existing frame, - // server response goes to that frame. - // - // For protocols other than FTP - // file uploads must be line-end converted from \r\n to \n - // - // Note: you cannot specify headers (even a blank line) in a memory buffer, - // use NPN_PostURLNotify - - return PostURLNotify(id, url, target, len, buf, file, false, 0); -} - -NPError NPN_NewStream(NPP id, - NPMIMEType type, - const char* target, - NPStream** stream) { - // Requests creation of a new data stream produced by the plugin, - // consumed by the browser. - // - // Browser should put this stream into a window target. - // - // TODO: implement me - DVLOG(1) << "NPN_NewStream is not implemented yet."; - return NPERR_GENERIC_ERROR; -} - -int32_t NPN_Write(NPP id, NPStream* stream, int32_t len, void* buffer) { - // Writes data to an existing Plugin-created stream. - - // TODO: implement me - DVLOG(1) << "NPN_Write is not implemented yet."; - return NPERR_GENERIC_ERROR; -} - -NPError NPN_DestroyStream(NPP id, NPStream* stream, NPReason reason) { - // Destroys a stream (could be created by plugin or browser). - // - // Reasons: - // NPRES_DONE - normal completion - // NPRES_USER_BREAK - user terminated - // NPRES_NETWORK_ERROR - network error (all errors fit here?) - // - // - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin.get() == NULL) { - NOTREACHED(); - return NPERR_GENERIC_ERROR; - } - - return plugin->NPP_DestroyStream(stream, reason); -} - -const char* NPN_UserAgent(NPP id) { -#if defined(OS_WIN) - // Flash passes in a null id during the NP_initialize call. We need to - // default to the Mozilla user agent if we don't have an NPP instance or - // else Flash won't request windowless mode. - bool use_mozilla_user_agent = true; - if (id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); - if (plugin.get() && !plugin->use_mozilla_user_agent()) - use_mozilla_user_agent = false; - } - - if (use_mozilla_user_agent) - return "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) " - "Gecko/20061103 Firefox/2.0a1"; -#elif defined(OS_MACOSX) - // Silverlight 4 doesn't handle events correctly unless we claim to be Safari. - scoped_refptr<NPAPI::PluginInstance> plugin; - if (id) - plugin = FindInstance(id); - if (plugin.get()) { - WebPluginInfo plugin_info = plugin->plugin_lib()->plugin_info(); - if (plugin_info.name == ASCIIToUTF16("Silverlight Plug-In") && - StartsWith(plugin_info.version, ASCIIToUTF16("4."), false)) { - return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) " - "AppleWebKit/534.1+ (KHTML, like Gecko) Version/5.0 Safari/533.16"; - } - } -#endif - - return webkit_glue::GetUserAgent(GURL()).c_str(); -} - -void NPN_Status(NPP id, const char* message) { - // Displays a message on the status line of the browser window. - - // TODO: implement me - DVLOG(1) << "NPN_Status is not implemented yet."; -} - -void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { - // Invalidates specified drawing area prior to repainting or refreshing a - // windowless plugin - - // Before a windowless plugin can refresh part of its drawing area, it must - // first invalidate it. This function causes the NPP_HandleEvent method to - // pass an update event or a paint message to the plug-in. After calling - // this method, the plug-in recieves a paint message asynchronously. - - // The browser redraws invalid areas of the document and any windowless - // plug-ins at regularly timed intervals. To force a paint message, the - // plug-in can call NPN_ForceRedraw after calling this method. - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin.get() && plugin->webplugin()) { - if (invalidRect) { -#if defined(OS_WIN) - if (!plugin->windowless()) { - RECT rect = {0}; - rect.left = invalidRect->left; - rect.right = invalidRect->right; - rect.top = invalidRect->top; - rect.bottom = invalidRect->bottom; - ::InvalidateRect(plugin->window_handle(), &rect, false); - return; - } -#endif - gfx::Rect rect(invalidRect->left, - invalidRect->top, - invalidRect->right - invalidRect->left, - invalidRect->bottom - invalidRect->top); - plugin->webplugin()->InvalidateRect(rect); - } else { - plugin->webplugin()->Invalidate(); - } - } -} - -void NPN_InvalidateRegion(NPP id, NPRegion invalidRegion) { - // Invalidates a specified drawing region prior to repainting - // or refreshing a window-less plugin. - // - // Similar to NPN_InvalidateRect. - - // TODO: this is overkill--add platform-specific region handling (at the - // very least, fetch the region's bounding box and pass it to InvalidateRect). - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - DCHECK(plugin.get() != NULL); - if (plugin.get() && plugin->webplugin()) - plugin->webplugin()->Invalidate(); -} - -void NPN_ForceRedraw(NPP id) { - // Forces repaint for a windowless plug-in. - // - // We deliberately do not implement this; we don't want plugins forcing - // synchronous paints. -} - -NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { - // Allows the plugin to query the browser for information - // - // Variables: - // NPNVxDisplay (unix only) - // NPNVxtAppContext (unix only) - // NPNVnetscapeWindow (win only) - Gets the native window on which the - // plug-in drawing occurs, returns HWND - // NPNVjavascriptEnabledBool: tells whether Javascript is enabled - // NPNVasdEnabledBool: tells whether SmartUpdate is enabled - // NPNVOfflineBool: tells whether offline-mode is enabled - - NPError rv = NPERR_GENERIC_ERROR; - - switch (static_cast<int>(variable)) { - case NPNVWindowNPObject: { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - NPObject *np_object = plugin->webplugin()->GetWindowScriptNPObject(); - // Return value is expected to be retained, as - // described here: - // <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess> - if (np_object) { - WebBindings::retainObject(np_object); - void **v = (void **)value; - *v = np_object; - rv = NPERR_NO_ERROR; - } else { - NOTREACHED(); - } - break; - } - case NPNVPluginElementNPObject: { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - NPObject *np_object = plugin->webplugin()->GetPluginElement(); - // Return value is expected to be retained, as - // described here: - // <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess> - if (np_object) { - WebBindings::retainObject(np_object); - void** v = static_cast<void**>(value); - *v = np_object; - rv = NPERR_NO_ERROR; - } else { - NOTREACHED(); - } - break; - } - #if !defined(OS_MACOSX) // OS X doesn't have windowed plugins. - case NPNVnetscapeWindow: { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); - if (!plugin.get()) { - NOTREACHED(); - return NPERR_GENERIC_ERROR; - } - gfx::PluginWindowHandle handle = plugin->window_handle(); - *((void**)value) = (void*)handle; - rv = NPERR_NO_ERROR; - break; - } - #endif - case NPNVjavascriptEnabledBool: { - // yes, JS is enabled. - *((void**)value) = (void*)1; - rv = NPERR_NO_ERROR; - break; - } - #if defined(TOOLKIT_USES_GTK) - case NPNVToolkit: - // Tell them we are GTK2. (The alternative is GTK 1.2.) - *reinterpret_cast<int*>(value) = NPNVGtk2; - rv = NPERR_NO_ERROR; - break; - - case NPNVSupportsXEmbedBool: - *reinterpret_cast<NPBool*>(value) = true; - rv = NPERR_NO_ERROR; - break; - #endif - case NPNVSupportsWindowless: { - NPBool* supports_windowless = reinterpret_cast<NPBool*>(value); - *supports_windowless = true; - rv = NPERR_NO_ERROR; - break; - } - case NPNVprivateModeBool: { - NPBool* private_mode = reinterpret_cast<NPBool*>(value); - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - *private_mode = plugin->webplugin()->IsOffTheRecord(); - rv = NPERR_NO_ERROR; - break; - } - case default_plugin::kMissingPluginStatusStart + - default_plugin::MISSING_PLUGIN_AVAILABLE: - // fall through - case default_plugin::kMissingPluginStatusStart + - default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD: { - // This is a hack for the default plugin to send notification to - // renderer. Even though we check if the plugin is the default plugin, - // we still need to worry about future standard change that may conflict - // with the variable definition, in order to avoid duplicate case clauses - // in this big switch statement. - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin->plugin_lib()->plugin_info().path.value() == - kDefaultPluginLibraryName) { - plugin->webplugin()->OnMissingPluginStatus( - variable - default_plugin::kMissingPluginStatusStart); - } - break; - } - #if defined(OS_MACOSX) - case NPNVpluginDrawingModel: { - // return the drawing model that was negotiated when we initialized. - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - *reinterpret_cast<int*>(value) = plugin->drawing_model(); - rv = NPERR_NO_ERROR; - break; - } -#ifndef NP_NO_QUICKDRAW - case NPNVsupportsQuickDrawBool: { - // We do not admit to supporting the QuickDraw drawing model. The logic - // here is that our QuickDraw plugin support is so rudimentary that we - // only want to use it as a fallback to keep plugins from crashing: if a - // plugin knows enough to ask, we want them to use CoreGraphics. - NPBool* supports_qd = reinterpret_cast<NPBool*>(value); - *supports_qd = false; - rv = NPERR_NO_ERROR; - break; - } -#endif - case NPNVsupportsCoreGraphicsBool: -#ifndef NP_NO_CARBON - case NPNVsupportsCarbonBool: -#endif - case NPNVsupportsCocoaBool: { - // we do support these drawing and event models. - NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = true; - rv = NPERR_NO_ERROR; - break; - } - case NPNVsupportsCoreAnimationBool: { - // We only support the Core Animation model on 10.6 and higher - // TODO(stuartmorgan): Once existing CA plugins have implemented the - // invalidating version, remove support for this one. - NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = SupportsSharingAcceleratedSurfaces() ? true : false; - rv = NPERR_NO_ERROR; - break; - } - case NPNVsupportsInvalidatingCoreAnimationBool: { - NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = true; - rv = NPERR_NO_ERROR; - break; - } - case NPNVsupportsOpenGLBool: { - // This drawing model was never widely supported, and we don't plan to - // support it. - NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = false; - rv = NPERR_NO_ERROR; - break; - } - #endif // OS_MACOSX - case NPNVPepperExtensions: - // Available for any plugin that attempts to get it. - // If the plugin is not started in a Pepper implementation, it - // will likely fail when it tries to use any of the functions - // attached to the extension vector. - rv = NPAPI::GetPepperExtensionsFunctions(value); - break; - default: - DVLOG(1) << "NPN_GetValue(" << variable << ") is not implemented yet."; - break; - } - return rv; -} - -NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { - // Allows the plugin to set various modes - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - switch(variable) { - case NPPVpluginWindowBool: { - // Sets windowless mode for display of the plugin - // Note: the documentation at - // http://developer.mozilla.org/en/docs/NPN_SetValue is wrong. When - // value is NULL, the mode is set to true. This is the same way Mozilla - // works. - plugin->set_windowless(value == 0); - return NPERR_NO_ERROR; - } - case NPPVpluginTransparentBool: { - // Sets transparent mode for display of the plugin - // - // Transparent plugins require the browser to paint the background - // before having the plugin paint. By default, windowless plugins - // are transparent. Making a windowless plugin opaque means that - // the plugin does not require the browser to paint the background. - bool mode = (value != 0); - plugin->set_transparent(mode); - return NPERR_NO_ERROR; - } - case NPPVjavascriptPushCallerBool: - // Specifies whether you are pushing or popping the JSContext off. - // the stack - // TODO: implement me - DVLOG(1) << "NPN_SetValue(NPPVJavascriptPushCallerBool) is not " - "implemented."; - return NPERR_GENERIC_ERROR; - case NPPVpluginKeepLibraryInMemory: - // Tells browser that plugin library should live longer than usual. - // TODO: implement me - DVLOG(1) << "NPN_SetValue(NPPVpluginKeepLibraryInMemory) is not " - "implemented."; - return NPERR_GENERIC_ERROR; - #if defined(OS_MACOSX) - case NPPVpluginDrawingModel: { - int model = reinterpret_cast<int>(value); - if (model == NPDrawingModelCoreGraphics || - model == NPDrawingModelInvalidatingCoreAnimation || - (model == NPDrawingModelCoreAnimation && - SupportsSharingAcceleratedSurfaces())) { - plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); - return NPERR_NO_ERROR; - } - return NPERR_GENERIC_ERROR; - } - case NPPVpluginEventModel: { - // we support Carbon and Cocoa event models - int model = reinterpret_cast<int>(value); - switch (model) { -#ifndef NP_NO_CARBON - case NPEventModelCarbon: -#endif - case NPEventModelCocoa: - plugin->set_event_model(static_cast<NPEventModel>(model)); - return NPERR_NO_ERROR; - break; - } - return NPERR_GENERIC_ERROR; - } - #endif - default: - // TODO: implement me - DVLOG(1) << "NPN_SetValue(" << variable << ") is not implemented."; - break; - } - - NOTREACHED(); - return NPERR_GENERIC_ERROR; -} - -void* NPN_GetJavaEnv() { - // TODO: implement me - DVLOG(1) << "NPN_GetJavaEnv is not implemented."; - return NULL; -} - -void* NPN_GetJavaPeer(NPP) { - // TODO: implement me - DVLOG(1) << "NPN_GetJavaPeer is not implemented."; - return NULL; -} - -void NPN_PushPopupsEnabledState(NPP id, NPBool enabled) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin) - plugin->PushPopupsEnabledState(enabled ? true : false); -} - -void NPN_PopPopupsEnabledState(NPP id) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin) - plugin->PopPopupsEnabledState(); -} - -void NPN_PluginThreadAsyncCall(NPP id, - void (*func)(void*), - void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin) - plugin->PluginThreadAsyncCall(func, user_data); -} - -NPError NPN_GetValueForURL(NPP id, - NPNURLVariable variable, - const char* url, - char** value, - uint32_t* len) { - if (!id) - return NPERR_INVALID_PARAM; - - if (!url || !*url || !len) - return NPERR_INVALID_URL; - - *len = 0; - std::string result; - - switch (variable) { - case NPNURLVProxy: { - result = "DIRECT"; - if (!webkit_glue::FindProxyForUrl(GURL((std::string(url))), &result)) - return NPERR_GENERIC_ERROR; - - break; - } - case NPNURLVCookie: { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (!plugin) - return NPERR_GENERIC_ERROR; - - webkit_glue::WebPlugin* webplugin = plugin->webplugin(); - if (!webplugin) - return NPERR_GENERIC_ERROR; - - // Bypass third-party cookie blocking by using the url as the - // first_party_for_cookies. - GURL cookies_url((std::string(url))); - result = webplugin->GetCookies(cookies_url, cookies_url); - break; - } - default: - return NPERR_GENERIC_ERROR; - } - - // Allocate this using the NPAPI allocator. The plugin will call - // NPN_Free to free this. - *value = static_cast<char*>(NPN_MemAlloc(result.length() + 1)); - base::strlcpy(*value, result.c_str(), result.length() + 1); - *len = result.length(); - - return NPERR_NO_ERROR; -} - -NPError NPN_SetValueForURL(NPP id, - NPNURLVariable variable, - const char* url, - const char* value, - uint32_t len) { - if (!id) - return NPERR_INVALID_PARAM; - - if (!url || !*url) - return NPERR_INVALID_URL; - - switch (variable) { - case NPNURLVCookie: { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (!plugin) - return NPERR_GENERIC_ERROR; - - webkit_glue::WebPlugin* webplugin = plugin->webplugin(); - if (!webplugin) - return NPERR_GENERIC_ERROR; - - std::string cookie(value, len); - GURL cookies_url((std::string(url))); - webplugin->SetCookie(cookies_url, cookies_url, cookie); - return NPERR_NO_ERROR; - } - case NPNURLVProxy: - // We don't support setting proxy values, fall through... - break; - default: - // Fall through and return an error... - break; - } - - return NPERR_GENERIC_ERROR; -} - -NPError NPN_GetAuthenticationInfo(NPP id, - const char* protocol, - const char* host, - int32_t port, - const char* scheme, - const char* realm, - char** username, - uint32_t* ulen, - char** password, - uint32_t* plen) { - if (!id || !protocol || !host || !scheme || !realm || !username || - !ulen || !password || !plen) - return NPERR_INVALID_PARAM; - - // TODO: implement me (bug 23928) - return NPERR_GENERIC_ERROR; -} - -uint32_t NPN_ScheduleTimer(NPP id, - uint32_t interval, - NPBool repeat, - void (*func)(NPP id, uint32_t timer_id)) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (!plugin) - return 0; - - return plugin->ScheduleTimer(interval, repeat, func); -} - -void NPN_UnscheduleTimer(NPP id, uint32_t timer_id) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin) - plugin->UnscheduleTimer(timer_id); -} - -NPError NPN_PopUpContextMenu(NPP id, NPMenu* menu) { - if (!menu) - return NPERR_INVALID_PARAM; - - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin.get()) { - return plugin->PopUpContextMenu(menu); - } - NOTREACHED(); - return NPERR_GENERIC_ERROR; -} - -NPBool NPN_ConvertPoint(NPP id, double sourceX, double sourceY, - NPCoordinateSpace sourceSpace, - double *destX, double *destY, - NPCoordinateSpace destSpace) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); - if (plugin.get()) { - return plugin->ConvertPoint(sourceX, sourceY, sourceSpace, - destX, destY, destSpace); - } - NOTREACHED(); - return false; -} - -NPBool NPN_HandleEvent(NPP id, void *event, NPBool handled) { - // TODO: Implement advanced key handling: http://crbug.com/46578 - NOTIMPLEMENTED(); - return false; -} - -NPBool NPN_UnfocusInstance(NPP id, NPFocusDirection direction) { - // TODO: Implement advanced key handling: http://crbug.com/46578 - NOTIMPLEMENTED(); - return false; -} - -void NPN_URLRedirectResponse(NPP instance, void* notify_data, NPBool allow) { - scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(instance)); - if (plugin.get()) { - plugin->URLRedirectResponse(!!allow, notify_data); - } -} - -} // extern "C" |