| Index: chrome/browser/chrome_plugin_host.cc
|
| diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc
|
| deleted file mode 100644
|
| index 4c069ab774d8cfad84e6493d31dbe713ff683c69..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chrome_plugin_host.cc
|
| +++ /dev/null
|
| @@ -1,842 +0,0 @@
|
| -// Copyright (c) 2011 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 "chrome/browser/chrome_plugin_host.h"
|
| -
|
| -#include <set>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/command_line.h"
|
| -#include "base/file_path.h"
|
| -#include "base/file_util.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/path_service.h"
|
| -#include "base/perftimer.h"
|
| -#include "base/singleton.h"
|
| -#include "base/string_util.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "chrome/browser/browser_list.h"
|
| -#include "chrome/browser/chrome_plugin_browsing_context.h"
|
| -#include "chrome/browser/gears_integration.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/ui/webui/html_dialog_ui.h"
|
| -#include "chrome/common/chrome_constants.h"
|
| -#include "chrome/common/chrome_counters.h"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/chrome_plugin_lib.h"
|
| -#include "chrome/common/chrome_plugin_util.h"
|
| -#include "chrome/common/gears_api.h"
|
| -#include "chrome/common/net/url_request_context_getter.h"
|
| -#include "chrome/common/net/url_request_intercept_job.h"
|
| -#include "chrome/common/plugin_messages.h"
|
| -#include "chrome/common/render_messages.h"
|
| -#include "content/browser/browser_thread.h"
|
| -#include "content/browser/plugin_process_host.h"
|
| -#include "content/browser/plugin_service.h"
|
| -#include "content/browser/renderer_host/render_process_host.h"
|
| -#include "content/common/notification_service.h"
|
| -#include "net/base/cookie_monster.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/http/http_request_headers.h"
|
| -#include "net/url_request/url_request.h"
|
| -#include "net/url_request/url_request_context.h"
|
| -#include "net/url_request/url_request_error_job.h"
|
| -#include "third_party/skia/include/core/SkBitmap.h"
|
| -
|
| -
|
| -using base::TimeDelta;
|
| -
|
| -// This class manages the interception of network requests. It queries the
|
| -// plugin on every request, and creates an intercept job if the plugin can
|
| -// intercept the request.
|
| -// NOTE: All methods must be called on the IO thread.
|
| -class PluginRequestInterceptor
|
| - : public PluginHelper, public net::URLRequest::Interceptor {
|
| - public:
|
| - static net::URLRequestJob* UninterceptedProtocolHandler(
|
| - net::URLRequest* request, const std::string& scheme) {
|
| - // This will get called if a plugin failed to intercept a request for a
|
| - // protocol it has registered. In that case, we return NULL and the request
|
| - // will result in an error.
|
| - return new net::URLRequestErrorJob(request, net::ERR_FILE_NOT_FOUND);
|
| - }
|
| -
|
| - explicit PluginRequestInterceptor(ChromePluginLib* plugin)
|
| - : PluginHelper(plugin) {
|
| - net::URLRequest::RegisterRequestInterceptor(this);
|
| - }
|
| -
|
| - virtual ~PluginRequestInterceptor() {
|
| - net::URLRequest::UnregisterRequestInterceptor(this);
|
| -
|
| - // Unregister our protocols.
|
| - for (HandledProtocolList::iterator it = registered_protocols_.begin();
|
| - it != registered_protocols_.end(); ++it) {
|
| - net::URLRequest::ProtocolFactory* factory =
|
| - net::URLRequest::RegisterProtocolFactory(*it, NULL);
|
| - DCHECK(factory == UninterceptedProtocolHandler);
|
| - }
|
| - }
|
| -
|
| - void RegisterProtocol(const std::string& scheme) {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - std::string lower_scheme = StringToLowerASCII(scheme);
|
| - handled_protocols_.insert(lower_scheme);
|
| -
|
| - // Only add a protocol factory if the net::URLRequest doesn't already handle
|
| - // it. If we fail to intercept, the request will be treated as an error.
|
| - if (!net::URLRequest::IsHandledProtocol(lower_scheme)) {
|
| - registered_protocols_.insert(lower_scheme);
|
| - net::URLRequest::RegisterProtocolFactory(lower_scheme,
|
| - &UninterceptedProtocolHandler);
|
| - }
|
| - }
|
| -
|
| - // net::URLRequest::Interceptor
|
| - virtual net::URLRequestJob* MaybeIntercept(net::URLRequest* request) {
|
| - // TODO(darin): This DCHECK fails in the unit tests because our interceptor
|
| - // is being persisted across unit tests. As a result, each time we get
|
| - // poked on a different thread, but never from more than one thread at a
|
| - // time. We need a way to have the URLRequestJobManager get reset between
|
| - // unit tests.
|
| - // DCHECK(CalledOnValidThread());
|
| -
|
| - if (!IsHandledProtocol(request->url().scheme()))
|
| - return NULL;
|
| -
|
| - CPBrowsingContext context =
|
| - CPBrowsingContextManager::GetInstance()->Lookup(request->context());
|
| - scoped_ptr<ScopableCPRequest> cprequest(
|
| - new ScopableCPRequest(request->url().spec().c_str(),
|
| - request->method().c_str(),
|
| - context));
|
| -
|
| - PerfTimer timer;
|
| - if (!plugin_->functions().should_intercept_request(cprequest.get())) {
|
| - LogInterceptMissTime(timer.Elapsed());
|
| - return NULL;
|
| - }
|
| - LogInterceptHitTime(timer.Elapsed());
|
| - return new URLRequestInterceptJob(request, plugin_, cprequest.release());
|
| - }
|
| -
|
| - private:
|
| - bool IsHandledProtocol(const std::string& scheme) {
|
| - return handled_protocols_.find(scheme) != handled_protocols_.end();
|
| - }
|
| -
|
| - void LogInterceptHitTime(const TimeDelta& time) {
|
| - UMA_HISTOGRAM_TIMES("Gears.InterceptHit", time);
|
| - }
|
| -
|
| - void LogInterceptMissTime(const TimeDelta& time) {
|
| - UMA_HISTOGRAM_TIMES("Gears.InterceptMiss", time);
|
| - }
|
| -
|
| - typedef std::set<std::string> HandledProtocolList;
|
| - HandledProtocolList handled_protocols_;
|
| - HandledProtocolList registered_protocols_;
|
| -};
|
| -
|
| -// This class manages a network request made by the plugin, also acting as
|
| -// the net::URLRequest delegate.
|
| -// NOTE: All methods must be called on the IO thread.
|
| -class PluginRequestHandler : public PluginHelper,
|
| - public net::URLRequest::Delegate {
|
| - public:
|
| - static PluginRequestHandler* FromCPRequest(CPRequest* request) {
|
| - return ScopableCPRequest::GetData<PluginRequestHandler*>(request);
|
| - }
|
| -
|
| - PluginRequestHandler(ChromePluginLib* plugin, ScopableCPRequest* cprequest)
|
| - : PluginHelper(plugin), cprequest_(cprequest), user_buffer_(NULL) {
|
| - cprequest_->data = this; // see FromCPRequest().
|
| -
|
| - net::URLRequestContext* context = CPBrowsingContextManager::GetInstance()->
|
| - ToURLRequestContext(cprequest_->context);
|
| - // TODO(mpcomplete): remove fallback case when Gears support is prevalent.
|
| - if (!context)
|
| - context = Profile::GetDefaultRequestContext()->GetURLRequestContext();
|
| -
|
| - GURL gurl(cprequest_->url);
|
| - request_.reset(new net::URLRequest(gurl, this));
|
| - request_->set_context(context);
|
| - request_->set_method(cprequest_->method);
|
| - request_->set_load_flags(PluginResponseUtils::CPLoadFlagsToNetFlags(0));
|
| - }
|
| -
|
| - net::URLRequest* request() { return request_.get(); }
|
| -
|
| - // Wraper of net::URLRequest::Read()
|
| - bool Read(char* dest, int dest_size, int *bytes_read) {
|
| - CHECK(!my_buffer_.get());
|
| - // We'll use our own buffer until the read actually completes.
|
| - user_buffer_ = dest;
|
| - my_buffer_ = new net::IOBuffer(dest_size);
|
| -
|
| - if (request_->Read(my_buffer_, dest_size, bytes_read)) {
|
| - memcpy(dest, my_buffer_->data(), *bytes_read);
|
| - my_buffer_ = NULL;
|
| - return true;
|
| - }
|
| -
|
| - if (!request_->status().is_io_pending())
|
| - my_buffer_ = NULL;
|
| -
|
| - return false;
|
| - }
|
| -
|
| - // net::URLRequest::Delegate
|
| - virtual void OnReceivedRedirect(net::URLRequest* request, const GURL& new_url,
|
| - bool* defer_redirect) {
|
| - plugin_->functions().response_funcs->received_redirect(
|
| - cprequest_.get(), new_url.spec().c_str());
|
| - }
|
| -
|
| - virtual void OnResponseStarted(net::URLRequest* request) {
|
| - // TODO(mpcomplete): better error codes
|
| - CPError result =
|
| - request_->status().is_success() ? CPERR_SUCCESS : CPERR_FAILURE;
|
| - plugin_->functions().response_funcs->start_completed(
|
| - cprequest_.get(), result);
|
| - }
|
| -
|
| - virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
| - CHECK(my_buffer_.get());
|
| - CHECK(user_buffer_);
|
| - if (bytes_read > 0) {
|
| - memcpy(user_buffer_, my_buffer_->data(), bytes_read);
|
| - } else if (bytes_read < 0) {
|
| - // TODO(mpcomplete): better error codes
|
| - bytes_read = CPERR_FAILURE;
|
| - }
|
| - my_buffer_ = NULL;
|
| - plugin_->functions().response_funcs->read_completed(
|
| - cprequest_.get(), bytes_read);
|
| - }
|
| -
|
| - private:
|
| - scoped_ptr<ScopableCPRequest> cprequest_;
|
| - scoped_ptr<net::URLRequest> request_;
|
| - scoped_refptr<net::IOBuffer> my_buffer_;
|
| - char* user_buffer_;
|
| -};
|
| -
|
| -// This class manages plugins that want to handle UI commands. Right now, we
|
| -// only allow 1 plugin to do this, so there's only ever 1 instance of this
|
| -// class at once.
|
| -// NOTE: All methods must be called on the IO thread.
|
| -class PluginCommandHandler : public PluginHelper {
|
| - public:
|
| - static void HandleCommand(int command,
|
| - CPCommandInterface* data,
|
| - int32 context_as_int32) {
|
| - CPBrowsingContext context =
|
| - static_cast<CPBrowsingContext>(context_as_int32);
|
| - // Ensure plugins are loaded before we try to talk to it. This will be a
|
| - // noop if plugins are loaded already.
|
| - ChromePluginLib::LoadChromePlugins(GetCPBrowserFuncsForBrowser());
|
| -
|
| - DCHECK(ChromePluginLib::IsPluginThread());
|
| - CPError rv = CPERR_INVALID_VERSION;
|
| - if (instance_ && instance_->plugin_->functions().handle_command) {
|
| - rv = instance_->plugin_->functions().handle_command(
|
| - context, command, data ? data->GetData() : NULL);
|
| - }
|
| - if (data)
|
| - data->OnCommandInvoked(rv);
|
| - }
|
| -
|
| - static void RegisterPlugin(ChromePluginLib* plugin) {
|
| - DCHECK(ChromePluginLib::IsPluginThread());
|
| - // TODO(mpcomplete): We only expect to have Gears register a command handler
|
| - // at the moment. We should either add support for other plugins to do
|
| - // this, or verify that the plugin is Gears.
|
| - DCHECK(!instance_) <<
|
| - "We only support a single plugin handling UI commands.";
|
| - if (instance_)
|
| - return;
|
| - // Deleted in response to a notification in PluginHelper.
|
| - new PluginCommandHandler(plugin);
|
| - }
|
| -
|
| - private:
|
| - explicit PluginCommandHandler(ChromePluginLib* plugin)
|
| - : PluginHelper(plugin) {
|
| - DCHECK(instance_ == NULL);
|
| - instance_ = this;
|
| - }
|
| -
|
| - virtual ~PluginCommandHandler() {
|
| - instance_ = NULL;
|
| - }
|
| -
|
| - static PluginCommandHandler* instance_;
|
| -};
|
| -
|
| -PluginCommandHandler* PluginCommandHandler::instance_ = NULL;
|
| -
|
| -// This class acts as a helper to display the HTML dialog. It is created
|
| -// on demand on the plugin thread, and proxies calls to and from the UI thread
|
| -// to display the UI.
|
| -class ModelessHtmlDialogDelegate : public HtmlDialogUIDelegate {
|
| - public:
|
| - ModelessHtmlDialogDelegate(const GURL& url,
|
| - int width, int height,
|
| - const std::string& json_arguments,
|
| - void* plugin_context,
|
| - ChromePluginLib* plugin,
|
| - MessageLoop* main_message_loop,
|
| - gfx::NativeWindow parent_wnd)
|
| - : main_message_loop_(main_message_loop),
|
| - io_message_loop_(MessageLoop::current()),
|
| - plugin_(plugin),
|
| - plugin_context_(plugin_context),
|
| - parent_wnd_(parent_wnd) {
|
| - DCHECK(ChromePluginLib::IsPluginThread());
|
| - params_.url = url;
|
| - params_.height = height;
|
| - params_.width = width;
|
| - params_.json_input = json_arguments;
|
| -
|
| - main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
|
| - this, &ModelessHtmlDialogDelegate::Show));
|
| - }
|
| - virtual ~ModelessHtmlDialogDelegate() {
|
| - DCHECK(ChromePluginLib::IsPluginThread());
|
| - }
|
| -
|
| - // The following public methods are called from the UI thread.
|
| -
|
| - // HtmlDialogUIDelegate implementation:
|
| - virtual bool IsDialogModal() const { return false; }
|
| - virtual std::wstring GetDialogTitle() const { return L"Gears"; }
|
| - virtual GURL GetDialogContentURL() const { return params_.url; }
|
| - virtual void GetWebUIMessageHandlers(
|
| - std::vector<WebUIMessageHandler*>* handlers) const {}
|
| - virtual void GetDialogSize(gfx::Size* size) const {
|
| - size->set_width(params_.width);
|
| - size->set_height(params_.height);
|
| - }
|
| - virtual std::string GetDialogArgs() const { return params_.json_input; }
|
| - virtual void OnDialogClosed(const std::string& json_retval) {
|
| - io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
|
| - this, &ModelessHtmlDialogDelegate::ReportResults, json_retval));
|
| - }
|
| - virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { }
|
| - virtual bool ShouldShowDialogTitle() const { return true; }
|
| -
|
| - private:
|
| - // Actually shows the dialog on the UI thread.
|
| - void Show() {
|
| - DCHECK(MessageLoop::current() == main_message_loop_);
|
| - Browser* browser = BrowserList::GetLastActive();
|
| - browser->BrowserShowHtmlDialog(this, parent_wnd_);
|
| - }
|
| -
|
| - // Gives the JSON result string back to the plugin.
|
| - void ReportResults(const std::string& json_retval) {
|
| - DCHECK(MessageLoop::current() == io_message_loop_);
|
| - // The plugin may have unloaded before it was time to report the results.
|
| - if (plugin_->is_loaded())
|
| - plugin_->functions().html_dialog_closed(plugin_context_,
|
| - json_retval.c_str());
|
| - delete this;
|
| - }
|
| -
|
| - // The parameters needed to display a modal HTML dialog.
|
| - HtmlDialogUI::HtmlDialogParams params_;
|
| -
|
| - // Message loops for sending messages between UI and IO threads.
|
| - MessageLoop* main_message_loop_;
|
| - MessageLoop* io_message_loop_;
|
| -
|
| - // The plugin object that requested the dialog. This can only be accessed on
|
| - // the IO thread.
|
| - scoped_refptr<ChromePluginLib> plugin_;
|
| -
|
| - // The plugin's context argument to CPB_ShowHtmlDialog.
|
| - void* plugin_context_;
|
| -
|
| - // The window this dialog box should be parented to, or NULL for the last
|
| - // active browser window.
|
| - gfx::NativeWindow parent_wnd_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ModelessHtmlDialogDelegate);
|
| -};
|
| -
|
| -// Allows InvokeLater without adding refcounting. The object is only deleted
|
| -// when its last InvokeLater is run anyway.
|
| -DISABLE_RUNNABLE_METHOD_REFCOUNT(ModelessHtmlDialogDelegate);
|
| -
|
| -namespace {
|
| -
|
| -//
|
| -// Generic functions
|
| -//
|
| -
|
| -void STDCALL CPB_SetKeepProcessAlive(CPID id, CPBool keep_alive) {
|
| - // This is a no-op in the main browser process
|
| -}
|
| -
|
| -CPError STDCALL CPB_GetCookies(CPID id, CPBrowsingContext bcontext,
|
| - const char* url, char** cookies) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - net::URLRequestContext* context = CPBrowsingContextManager::GetInstance()->
|
| - ToURLRequestContext(bcontext);
|
| - // TODO(mpcomplete): remove fallback case when Gears support is prevalent.
|
| - if (!context) {
|
| - context = Profile::GetDefaultRequestContext()->GetURLRequestContext();
|
| - if (!context)
|
| - return CPERR_FAILURE;
|
| - }
|
| - std::string cookies_str = context->cookie_store()->GetCookies(GURL(url));
|
| - *cookies = CPB_StringDup(CPB_Alloc, cookies_str);
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -CPError STDCALL CPB_ShowHtmlDialogModal(
|
| - CPID id, CPBrowsingContext context, const char* url, int width, int height,
|
| - const char* json_arguments, char** json_retval) {
|
| - // Should not be called in browser process.
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_ShowHtmlDialog(
|
| - CPID id, CPBrowsingContext context, const char* url, int width, int height,
|
| - const char* json_arguments, void* plugin_context) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| -#if defined(OS_WIN)
|
| - HWND parent_hwnd = reinterpret_cast<HWND>(static_cast<uintptr_t>(context));
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return CPERR_FAILURE;
|
| - MessageLoop* main_message_loop = service->main_message_loop();
|
| - ModelessHtmlDialogDelegate* delegate =
|
| - new ModelessHtmlDialogDelegate(GURL(url), width, height, json_arguments,
|
| - plugin_context, plugin, main_message_loop,
|
| - parent_hwnd);
|
| -#else
|
| - // TODO(port): port ModelessHtmlDialogDelegate
|
| - NOTIMPLEMENTED();
|
| -#endif
|
| -
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -CPError STDCALL CPB_GetCommandLineArguments(
|
| - CPID id, CPBrowsingContext context, const char* url, char** arguments) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - std::string arguments_str;
|
| - CPError rv = CPB_GetCommandLineArgumentsCommon(url, &arguments_str);
|
| - if (rv == CPERR_SUCCESS)
|
| - *arguments = CPB_StringDup(CPB_Alloc, arguments_str);
|
| - return rv;
|
| -}
|
| -
|
| -CPBrowsingContext STDCALL CPB_GetBrowsingContextFromNPP(struct _NPP* npp) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - NOTREACHED() << "NPP does not exist in the browser process.";
|
| - return 0;
|
| -}
|
| -
|
| -int STDCALL CPB_GetBrowsingContextInfo(
|
| - CPID id, CPBrowsingContext context, CPBrowsingContextInfoType type,
|
| - void* buf, uint32 buf_size) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - switch (type) {
|
| - case CPBROWSINGCONTEXT_DATA_DIR_PTR: {
|
| - if (buf_size < sizeof(char*))
|
| - return sizeof(char*);
|
| -
|
| - // TODO(mpcomplete): http://b/1143021 - When we support multiple profiles,
|
| - // fetch the data dir from the context.
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return CPERR_FAILURE;
|
| - FilePath path = service->GetChromePluginDataDir();
|
| - // This is wrong -- we can't in general stuff a path through a std::string.
|
| - // But this code is Gears-specific, so Windows-only anyway for now.
|
| - std::string retval;
|
| -#if defined(OS_WIN)
|
| - retval = WideToUTF8(path.Append(chrome::kChromePluginDataDirname).value());
|
| -#else
|
| - NOTREACHED();
|
| -#endif
|
| - *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, retval);
|
| - return CPERR_SUCCESS;
|
| - }
|
| - case CPBROWSINGCONTEXT_UI_LOCALE_PTR: {
|
| - if (buf_size < sizeof(char*))
|
| - return sizeof(char*);
|
| -
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return CPERR_FAILURE;
|
| - const std::string& retval = service->GetUILocale();
|
| - *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, retval);
|
| - return CPERR_SUCCESS;
|
| - }
|
| - }
|
| -
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_AddUICommand(CPID id, int command) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| - PluginCommandHandler::RegisterPlugin(plugin);
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -static void NotifyGearsShortcutsChanged() {
|
| - DCHECK(MessageLoop::current() ==
|
| - PluginService::GetInstance()->main_message_loop());
|
| -
|
| - // TODO(michaeln): source should be the original profile, fix this
|
| - // when gears provides the correct browser context, and when we
|
| - // can relate that to an actual profile.
|
| - NotificationService::current()->Notify(
|
| - NotificationType::WEB_APP_INSTALL_CHANGED,
|
| - Source<Profile>(NULL),
|
| - NotificationService::NoDetails());
|
| -}
|
| -
|
| -CPError STDCALL CPB_HandleCommand(
|
| - CPID id, CPBrowsingContext context, int command, void *data) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| - if (command == GEARSBROWSERCOMMAND_CREATE_SHORTCUT_DONE) {
|
| - GearsCreateShortcutResult* result =
|
| - static_cast<GearsCreateShortcutResult*>(data);
|
| - CHECK(result);
|
| -
|
| - GearsCreateShortcutData* shortcut_data =
|
| - static_cast<GearsCreateShortcutData*>(result->shortcut);
|
| - shortcut_data->command_interface->OnCommandResponse(result->result);
|
| - } else if (command == GEARSBROWSERCOMMAND_NOTIFY_SHORTCUTS_CHANGED) {
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return CPERR_FAILURE;
|
| - service->main_message_loop()->PostTask(FROM_HERE,
|
| - NewRunnableFunction(NotifyGearsShortcutsChanged));
|
| - return CPERR_SUCCESS;
|
| - }
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_GetDragData(
|
| - CPID id, CPBrowsingContext context, struct NPObject* event, bool add_data,
|
| - int32* identity, int32* event_id, char** drag_type, char** drag_data) {
|
| - *identity = *event_id = 0;
|
| - NOTREACHED() << "Should not be called in the browser process.";
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_SetDropEffect(
|
| - CPID id, CPBrowsingContext context, struct NPObject* event, int effect) {
|
| - NOTREACHED() << "Should not be called in the browser process.";
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_AllowFileDrop(
|
| - CPID id, CPBrowsingContext context, const char* file_drag_data) {
|
| - NOTREACHED() << "Should not be called in the browser process.";
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -//
|
| -// Functions related to network interception
|
| -//
|
| -
|
| -void STDCALL CPB_EnableRequestIntercept(CPID id, const char** schemes,
|
| - uint32 num_schemes) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| - if (schemes && num_schemes > 0) {
|
| - PluginRequestInterceptor* interceptor =
|
| - new PluginRequestInterceptor(plugin);
|
| - for (uint32 i = 0; i < num_schemes; ++i)
|
| - interceptor->RegisterProtocol(schemes[i]);
|
| - } else {
|
| - PluginRequestInterceptor::DestroyAllHelpersForPlugin(plugin);
|
| - }
|
| -}
|
| -
|
| -void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
|
| -}
|
| -
|
| -void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - URLRequestInterceptJob* job = URLRequestInterceptJob::FromCPRequest(request);
|
| - CHECK(job);
|
| - job->OnStartCompleted(result);
|
| -}
|
| -
|
| -void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - URLRequestInterceptJob* job = URLRequestInterceptJob::FromCPRequest(request);
|
| - CHECK(job);
|
| - job->OnReadCompleted(bytes_read);
|
| -}
|
| -
|
| -void STDCALL CPRR_UploadProgress(CPRequest* request, uint64 pos, uint64 size) {
|
| - // Does not apply, plugins do not yet intercept uploads
|
| -}
|
| -
|
| -//
|
| -// Functions related to serving network requests to the plugin
|
| -//
|
| -
|
| -CPError STDCALL CPB_CreateRequest(CPID id, CPBrowsingContext context,
|
| - const char* method, const char* url,
|
| - CPRequest** request) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| - ScopableCPRequest* cprequest = new ScopableCPRequest(url, method, context);
|
| - PluginRequestHandler* handler = new PluginRequestHandler(plugin, cprequest);
|
| - CHECK(handler);
|
| -
|
| - *request = cprequest;
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -CPError STDCALL CPR_StartRequest(CPRequest* request) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| - handler->request()->Start();
|
| - return CPERR_IO_PENDING;
|
| -}
|
| -
|
| -void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - delete handler;
|
| -}
|
| -
|
| -void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
|
| - const char* headers) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| - net::HttpRequestHeaders http_headers;
|
| - http_headers.AddHeadersFromString(headers);
|
| - handler->request()->SetExtraRequestHeaders(http_headers);
|
| -}
|
| -
|
| -void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| - uint32 net_flags = PluginResponseUtils::CPLoadFlagsToNetFlags(flags);
|
| - handler->request()->set_load_flags(net_flags);
|
| -}
|
| -
|
| -void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
|
| - int bytes_len) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| - handler->request()->AppendBytesToUpload(bytes, bytes_len);
|
| -}
|
| -
|
| -CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
|
| - uint64 offset, uint64 length) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| -
|
| - if (!length) length = kuint64max;
|
| - FilePath path(FilePath::FromWStringHack(UTF8ToWide(filepath)));
|
| - handler->request()->AppendFileRangeToUpload(path, offset, length,
|
| - base::Time());
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
|
| - void* buf, uint32 buf_size) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| - return PluginResponseUtils::GetResponseInfo(
|
| - handler->request()->response_headers(), type, buf, buf_size);
|
| -}
|
| -
|
| -int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - PluginRequestHandler* handler = PluginRequestHandler::FromCPRequest(request);
|
| - CHECK(handler);
|
| -
|
| - int bytes_read;
|
| - if (handler->Read(static_cast<char*>(buf), buf_size, &bytes_read))
|
| - return bytes_read; // 0 == CPERR_SUCESS
|
| -
|
| - if (handler->request()->status().is_io_pending())
|
| - return CPERR_IO_PENDING;
|
| -
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPBool STDCALL CPB_IsPluginProcessRunning(CPID id) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return false;
|
| - PluginProcessHost *host = service->FindNpapiPluginProcess(plugin->filename());
|
| - return host ? true : false;
|
| -}
|
| -
|
| -CPProcessType STDCALL CPB_GetProcessType(CPID id) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - return CP_PROCESS_BROWSER;
|
| -}
|
| -
|
| -CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
|
| - CHECK(ChromePluginLib::IsPluginThread());
|
| - ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
|
| - CHECK(plugin);
|
| -
|
| - PluginService* service = PluginService::GetInstance();
|
| - if (!service)
|
| - return CPERR_FAILURE;
|
| - PluginProcessHost *host =
|
| - service->FindOrStartNpapiPluginProcess(plugin->filename());
|
| - if (!host)
|
| - return CPERR_FAILURE;
|
| -
|
| - const unsigned char* data_ptr = static_cast<const unsigned char*>(data);
|
| - std::vector<uint8> v(data_ptr, data_ptr + data_len);
|
| -#if defined(OS_WIN)
|
| - if (!host->Send(new PluginProcessMsg_PluginMessage(v)))
|
| - return CPERR_FAILURE;
|
| -#else
|
| - // TODO(port): Implement PluginProcessMsg.
|
| - NOTIMPLEMENTED();
|
| -#endif
|
| -
|
| - return CPERR_SUCCESS;
|
| -}
|
| -
|
| -CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
|
| - void **retval, uint32 *retval_len) {
|
| - NOTREACHED() << "Sync messages should not be sent from the browser process.";
|
| -
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
|
| - void (*func)(void *),
|
| - void *user_data) {
|
| - bool posted = BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - NewRunnableFunction(func, user_data));
|
| - return posted ? CPERR_SUCCESS : CPERR_FAILURE;
|
| -}
|
| -
|
| -CPError STDCALL CPB_OpenFileDialog(CPID id,
|
| - CPBrowsingContext context,
|
| - bool multiple_files,
|
| - const char *title,
|
| - const char *filter,
|
| - void *user_data) {
|
| - NOTREACHED() <<
|
| - "Open file dialog should only be called from the renderer process.";
|
| -
|
| - return CPERR_FAILURE;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -CPBrowserFuncs* GetCPBrowserFuncsForBrowser() {
|
| - static CPBrowserFuncs browser_funcs;
|
| - static CPRequestFuncs request_funcs;
|
| - static CPResponseFuncs response_funcs;
|
| - static bool initialized = false;
|
| - if (!initialized) {
|
| - initialized = true;
|
| -
|
| - browser_funcs.size = sizeof(browser_funcs);
|
| - browser_funcs.version = CP_VERSION;
|
| - browser_funcs.enable_request_intercept = CPB_EnableRequestIntercept;
|
| - browser_funcs.create_request = CPB_CreateRequest;
|
| - browser_funcs.get_cookies = CPB_GetCookies;
|
| - browser_funcs.alloc = CPB_Alloc;
|
| - browser_funcs.free = CPB_Free;
|
| - browser_funcs.set_keep_process_alive = CPB_SetKeepProcessAlive;
|
| - browser_funcs.show_html_dialog_modal = CPB_ShowHtmlDialogModal;
|
| - browser_funcs.show_html_dialog = CPB_ShowHtmlDialog;
|
| - browser_funcs.is_plugin_process_running = CPB_IsPluginProcessRunning;
|
| - browser_funcs.get_process_type = CPB_GetProcessType;
|
| - browser_funcs.send_message = CPB_SendMessage;
|
| - browser_funcs.get_browsing_context_from_npp = CPB_GetBrowsingContextFromNPP;
|
| - browser_funcs.get_browsing_context_info = CPB_GetBrowsingContextInfo;
|
| - browser_funcs.get_command_line_arguments = CPB_GetCommandLineArguments;
|
| - browser_funcs.add_ui_command = CPB_AddUICommand;
|
| - browser_funcs.handle_command = CPB_HandleCommand;
|
| -
|
| - browser_funcs.request_funcs = &request_funcs;
|
| - browser_funcs.response_funcs = &response_funcs;
|
| - browser_funcs.send_sync_message = CPB_SendSyncMessage;
|
| - browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
|
| - browser_funcs.open_file_dialog = CPB_OpenFileDialog;
|
| - browser_funcs.get_drag_data = CPB_GetDragData;
|
| - browser_funcs.set_drop_effect = CPB_SetDropEffect;
|
| - browser_funcs.allow_file_drop = CPB_AllowFileDrop;
|
| -
|
| - request_funcs.size = sizeof(request_funcs);
|
| - request_funcs.start_request = CPR_StartRequest;
|
| - request_funcs.end_request = CPR_EndRequest;
|
| - request_funcs.set_extra_request_headers = CPR_SetExtraRequestHeaders;
|
| - request_funcs.set_request_load_flags = CPR_SetRequestLoadFlags;
|
| - request_funcs.append_data_to_upload = CPR_AppendDataToUpload;
|
| - request_funcs.get_response_info = CPR_GetResponseInfo;
|
| - request_funcs.read = CPR_Read;
|
| - request_funcs.append_file_to_upload = CPR_AppendFileToUpload;
|
| -
|
| - response_funcs.size = sizeof(response_funcs);
|
| - response_funcs.received_redirect = CPRR_ReceivedRedirect;
|
| - response_funcs.start_completed = CPRR_StartCompleted;
|
| - response_funcs.read_completed = CPRR_ReadCompleted;
|
| - response_funcs.upload_progress = CPRR_UploadProgress;
|
| - }
|
| -
|
| - return &browser_funcs;
|
| -}
|
| -
|
| -void CPCommandInterface::OnCommandInvoked(CPError retval) {
|
| - delete this;
|
| -}
|
| -
|
| -void CPCommandInterface::OnCommandResponse(CPError retval) {}
|
| -
|
| -void CPHandleCommand(int command, CPCommandInterface* data,
|
| - CPBrowsingContext context) {
|
| - // Sadly if we try and pass context through, we seem to break cl's little
|
| - // brain trying to compile the Tuple3 ctor. This cast works.
|
| - int32 context_as_int32 = static_cast<int32>(context);
|
| - // Plugins can only be accessed on the IO thread.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - NewRunnableFunction(PluginCommandHandler::HandleCommand,
|
| - command, data, context_as_int32));
|
| -}
|
|
|