summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-15 18:36:46 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-15 18:36:46 +0000
commit173de1be12780200c62bae5c01965d51ac0eaa31 (patch)
tree5ab851b72e8012f49a4d80b281744a6b64d40753 /chrome
parent1f2763de9d897fc2b0e6da4c2323b7d8ab70c687 (diff)
downloadchromium_src-173de1be12780200c62bae5c01965d51ac0eaa31.zip
chromium_src-173de1be12780200c62bae5c01965d51ac0eaa31.tar.gz
chromium_src-173de1be12780200c62bae5c01965d51ac0eaa31.tar.bz2
Step 1 at making Gears run in the renderer process (enabled by switch
"--gears-in-renderer"). Requires some changes to gears to work. Most things work if you disable the sandbox. One major hole is that update tasks don't report status to the appropriate renderer. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@954 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chrome_plugin_host.cc8
-rw-r--r--chrome/browser/render_process_host.cc3
-rw-r--r--chrome/browser/resource_message_filter.cc20
-rw-r--r--chrome/browser/resource_message_filter.h4
-rw-r--r--chrome/common/chrome_plugin_api.h1
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--chrome/common/render_messages_internal.h10
-rw-r--r--chrome/plugin/webplugin_proxy.h3
-rw-r--r--chrome/renderer/SConscript1
-rw-r--r--chrome/renderer/chrome_plugin_host.cc573
-rw-r--r--chrome/renderer/chrome_plugin_host.h38
-rw-r--r--chrome/renderer/render_thread.cc5
-rw-r--r--chrome/renderer/render_thread.h3
-rw-r--r--chrome/renderer/render_view.cc21
-rw-r--r--chrome/renderer/render_view.h8
-rw-r--r--chrome/renderer/renderer.vcproj8
17 files changed, 704 insertions, 7 deletions
diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc
index 65600b8..ed6c6f5 100644
--- a/chrome/browser/chrome_plugin_host.cc
+++ b/chrome/browser/chrome_plugin_host.cc
@@ -31,6 +31,7 @@
#include <set>
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/histogram.h"
#include "base/message_loop.h"
@@ -52,6 +53,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_plugin_util.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/net/url_request_intercept_job.h"
#include "chrome/common/plugin_messages.h"
@@ -658,6 +660,12 @@ CPProcessType STDCALL CPB_GetProcessType(CPID id) {
}
CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
+ CommandLine cmd;
+ if (cmd.HasSwitch(switches::kGearsInRenderer)) {
+ // TODO(mpcomplete): figure out what to do here.
+ return CPERR_FAILURE;
+ }
+
CHECK(ChromePluginLib::IsPluginThread());
ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
CHECK(plugin);
diff --git a/chrome/browser/render_process_host.cc b/chrome/browser/render_process_host.cc
index 558a161..aff2ba0 100644
--- a/chrome/browser/render_process_host.cc
+++ b/chrome/browser/render_process_host.cc
@@ -289,7 +289,8 @@ bool RenderProcessHost::Init() {
switches::kEnableDCHECK,
switches::kSilentDumpOnDCHECK,
switches::kDisablePopupBlocking,
- switches::kUseLowFragHeapCrt
+ switches::kUseLowFragHeapCrt,
+ switches::kGearsInRenderer,
};
for (int i = 0; i < arraysize(switch_names); ++i) {
diff --git a/chrome/browser/resource_message_filter.cc b/chrome/browser/resource_message_filter.cc
index d5234a8..99b188c 100644
--- a/chrome/browser/resource_message_filter.cc
+++ b/chrome/browser/resource_message_filter.cc
@@ -41,6 +41,7 @@
#include "chrome/browser/render_process_host.h"
#include "chrome/browser/render_widget_helper.h"
#include "chrome/browser/spellchecker.h"
+#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/clipboard_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -167,6 +168,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookies, OnGetCookies)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_GetDataDir, OnGetDataDir)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_PluginMessage, OnPluginMessage)
IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorInfoForWindow,
OnGetMonitorInfoForWindow)
@@ -362,6 +365,23 @@ void ResourceMessageFilter::OnGetCookies(const GURL& url,
*cookies = request_context_->cookie_store()->GetCookies(url);
}
+void ResourceMessageFilter::OnGetDataDir(std::wstring* data_dir) {
+ *data_dir = plugin_service_->GetChromePluginDataDir();
+}
+
+void ResourceMessageFilter::OnPluginMessage(const std::wstring& dll_path,
+ const std::vector<uint8>& data) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO));
+
+ ChromePluginLib *chrome_plugin = ChromePluginLib::Find(dll_path);
+ if (chrome_plugin) {
+ void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0]));
+ uint32 data_len = static_cast<uint32>(data.size());
+ chrome_plugin->functions().on_message(data_ptr, data_len);
+ }
+}
+
void ResourceMessageFilter::OnGetPlugins(bool refresh,
std::vector<WebPluginInfo>* plugins) {
plugin_service_->GetPlugins(refresh, plugins);
diff --git a/chrome/browser/resource_message_filter.h b/chrome/browser/resource_message_filter.h
index a5525e7..31dff65 100644
--- a/chrome/browser/resource_message_filter.h
+++ b/chrome/browser/resource_message_filter.h
@@ -103,6 +103,10 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
const std::string& cookie);
void OnGetCookies(const GURL& url, const GURL& policy_url,
std::string* cookies);
+ void OnGetDataDir(std::wstring* data_dir);
+ void OnPluginMessage(const std::wstring& dll_path,
+ const std::vector<uint8>& message);
+
// Cache fonts for the renderer. See ResourceMessageFilter::OnLoadFont
// implementation for more details
void OnLoadFont(LOGFONT font);
diff --git a/chrome/common/chrome_plugin_api.h b/chrome/common/chrome_plugin_api.h
index 1dd08727..af21699 100644
--- a/chrome/common/chrome_plugin_api.h
+++ b/chrome/common/chrome_plugin_api.h
@@ -67,6 +67,7 @@ typedef unsigned char CPBool;
typedef enum {
CP_PROCESS_BROWSER = 0,
CP_PROCESS_PLUGIN,
+ CP_PROCESS_RENDERER,
} CPProcessType;
// Return codes. Error values are negative.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 47f3080..c36d710 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -330,6 +330,9 @@ const wchar_t kUseLowFragHeapCrt[] = L"use-lf-heap";
const wchar_t kGearsPluginPathOverride[] = L"gears-plugin-path";
#endif
+// Switch to load Gears in the renderer process.
+const wchar_t kGearsInRenderer[] = L"gears-in-renderer";
+
// Enable new HTTP stack.
const wchar_t kUseNewHttp[] = L"new-http";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index fbffc88..11ce1bc 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -137,6 +137,8 @@ extern const wchar_t kUseLowFragHeapCrt[];
extern const wchar_t kGearsPluginPathOverride[];
#endif
+extern const wchar_t kGearsInRenderer[];
+
extern const wchar_t kUseNewHttp[];
extern const wchar_t kJavaScriptDebuggerPath[];
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 334b902..841f661 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -650,6 +650,16 @@ IPC_BEGIN_MESSAGES(ViewHost, 2)
std::wstring /* filename */,
std::string /* actual mime type for url */)
+ // Retrieve the data directory associated with the renderer's profile.
+ IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetDataDir,
+ std::wstring /* data_dir_retval */)
+
+ // Allows a chrome plugin loaded in a renderer process to send arbitrary
+ // data to an instance of the same plugin loaded in the browser process.
+ IPC_MESSAGE_CONTROL2(ViewHostMsg_PluginMessage,
+ std::wstring /* dll_path of plugin */,
+ std::vector<uint8> /* opaque data */)
+
// Requests spellcheck for a word.
IPC_SYNC_MESSAGE_ROUTED1_2(ViewHostMsg_SpellCheck,
std::wstring /* word to check */,
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 6c862e1..de0a771 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -60,6 +60,9 @@ class WebPluginProxy : public WebPlugin {
void InvalidateRect(const gfx::Rect& rect);
NPObject* GetWindowScriptNPObject();
NPObject* GetPluginElement();
+ WebFrame* GetWebFrame() {
+ return NULL; // doesn't make sense in the plugin process.
+ }
void SetCookie(const GURL& url,
const GURL& policy_url,
const std::string& cookie);
diff --git a/chrome/renderer/SConscript b/chrome/renderer/SConscript
index f801236..a10793e 100644
--- a/chrome/renderer/SConscript
+++ b/chrome/renderer/SConscript
@@ -61,6 +61,7 @@ env.Append(
input_files = [
'about_handler.cc',
'automation/dom_automation_controller.cc',
+ 'chrome_plugin_host.cc',
'debug_message_handler.cc',
'dom_ui_bindings.cc',
'external_js_object.cc',
diff --git a/chrome/renderer/chrome_plugin_host.cc b/chrome/renderer/chrome_plugin_host.cc
new file mode 100644
index 0000000..cf80816
--- /dev/null
+++ b/chrome/renderer/chrome_plugin_host.cc
@@ -0,0 +1,573 @@
+// Copyright 2008, Google Inc.
+// 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 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.
+
+#include "chrome/plugin/chrome_plugin_host.h"
+
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_plugin_lib.h"
+#include "chrome/common/chrome_plugin_util.h"
+#include "chrome/common/resource_dispatcher.h"
+#include "chrome/renderer/render_view.h"
+#include "net/base/data_url.h"
+#include "net/base/upload_data.h"
+#include "webkit/glue/plugins/plugin_instance.h"
+#include "webkit/glue/resource_loader_bridge.h"
+#include "webkit/glue/resource_type.h"
+#include "webkit/glue/webkit_glue.h"
+#include "webkit/glue/webframe.h"
+
+namespace {
+
+using webkit_glue::ResourceLoaderBridge;
+
+// This class manages a network request made by the plugin, handling the
+// data as it comes in from the ResourceLoaderBridge and is requested by the
+// plugin.
+// NOTE: All methods must be called on the Plugin thread.
+class PluginRequestHandlerProxy
+ : public PluginHelper, public ResourceLoaderBridge::Peer {
+ public:
+ static PluginRequestHandlerProxy* FromCPRequest(CPRequest* request) {
+ return ScopableCPRequest::GetData<PluginRequestHandlerProxy*>(request);
+ }
+
+ PluginRequestHandlerProxy(ChromePluginLib* plugin,
+ ScopableCPRequest* cprequest,
+ WebFrame* webframe)
+ : PluginHelper(plugin), cprequest_(cprequest), response_data_offset_(0),
+ completed_(false), sync_(false), read_buffer_(NULL),
+ webframe_(webframe) {
+ load_flags_ = PluginResponseUtils::CPLoadFlagsToNetFlags(0);
+ cprequest_->data = this; // see FromCPRequest().
+ }
+
+ ~PluginRequestHandlerProxy() {
+ if (bridge_.get() && !completed_) {
+ bridge_->Cancel();
+ }
+ }
+
+ // ResourceLoaderBridge::Peer
+ virtual void OnUploadProgress(uint64 position, uint64 size) {
+ CPRR_UploadProgressFunc upload_progress =
+ plugin_->functions().response_funcs->upload_progress;
+ if (upload_progress)
+ upload_progress(cprequest_.get(), position, size);
+ }
+
+ virtual void OnReceivedRedirect(const GURL& new_url) {
+ plugin_->functions().response_funcs->received_redirect(
+ cprequest_.get(), new_url.spec().c_str());
+ }
+
+ virtual void OnReceivedResponse(
+ const ResourceLoaderBridge::ResponseInfo& info) {
+ response_headers_ = info.headers;
+ plugin_->functions().response_funcs->start_completed(
+ cprequest_.get(), CPERR_SUCCESS);
+ }
+
+ virtual void OnReceivedData(const char* data, int len) {
+ response_data_.append(data, len);
+ if (read_buffer_) {
+ // If we had an asynchronous operation pending, read into that buffer
+ // and inform the plugin.
+ int rv = Read(read_buffer_, read_buffer_size_);
+ DCHECK(rv != CPERR_IO_PENDING);
+ read_buffer_ = NULL;
+ plugin_->functions().response_funcs->read_completed(
+ cprequest_.get(), rv);
+ }
+ }
+
+ virtual void OnCompletedRequest(const URLRequestStatus& status) {
+ completed_ = true;
+
+ if (!status.is_success()) {
+ // TODO(mpcomplete): better error codes
+ // Inform the plugin, calling the right function depending on whether
+ // we got the start_completed event or not.
+ if (response_headers_) {
+ plugin_->functions().response_funcs->start_completed(
+ cprequest_.get(), CPERR_FAILURE);
+ } else {
+ plugin_->functions().response_funcs->read_completed(
+ cprequest_.get(), CPERR_FAILURE);
+ }
+ } else if (read_buffer_) {
+ // The plugin was waiting for more data. Inform him we're done.
+ read_buffer_ = NULL;
+ plugin_->functions().response_funcs->read_completed(
+ cprequest_.get(), CPERR_SUCCESS);
+ }
+ }
+
+ virtual std::string GetURLForDebugging() {
+ return cprequest_->url;
+ }
+
+ void set_extra_headers(const std::string& headers) {
+ extra_headers_ = headers;
+ }
+ void set_load_flags(uint32 flags) {
+ load_flags_ = flags;
+ }
+ void set_sync(bool sync) {
+ sync_ = sync;
+ }
+ void AppendDataToUpload(const char* bytes, int bytes_len) {
+ upload_content_.push_back(net::UploadData::Element());
+ upload_content_.back().SetToBytes(bytes, bytes_len);
+ }
+
+ void AppendFileToUpload(const std::wstring &filepath) {
+ AppendFileRangeToUpload(filepath, 0, kuint64max);
+ }
+
+ void AppendFileRangeToUpload(const std::wstring &filepath,
+ uint64 offset, uint64 length) {
+ upload_content_.push_back(net::UploadData::Element());
+ upload_content_.back().SetToFilePathRange(filepath, offset, length);
+ }
+
+ CPError Start() {
+ bridge_.reset(
+ webkit_glue::ResourceLoaderBridge::Create(
+ webframe_,
+ cprequest_->method,
+ GURL(cprequest_->url),
+ GURL(cprequest_->url), // TODO(jackson): policy url?
+ GURL(), // TODO(mpcomplete): referrer?
+ extra_headers_,
+ load_flags_,
+ GetCurrentProcessId(),
+ ResourceType::OBJECT,
+ false)); // TODO (jcampan): mixed-content?
+ if (!bridge_.get())
+ return CPERR_FAILURE;
+
+ for (size_t i = 0; i < upload_content_.size(); ++i) {
+ switch (upload_content_[i].type()) {
+ case net::UploadData::TYPE_BYTES: {
+ const std::vector<char>& bytes = upload_content_[i].bytes();
+ bridge_->AppendDataToUpload(&bytes[0],
+ static_cast<int>(bytes.size()));
+ break;
+ }
+ case net::UploadData::TYPE_FILE: {
+ bridge_->AppendFileRangeToUpload(
+ upload_content_[i].file_path(),
+ upload_content_[i].file_range_offset(),
+ upload_content_[i].file_range_length());
+ break;
+ }
+ default: {
+ NOTREACHED() << "Unknown UploadData::Element type";
+ }
+ }
+ }
+
+ if (sync_) {
+ ResourceLoaderBridge::SyncLoadResponse response;
+ bridge_->SyncLoad(&response);
+ response_headers_ = response.headers;
+ response_data_ = response.data;
+ completed_ = true;
+ return response.status.is_success() ? CPERR_SUCCESS : CPERR_FAILURE;
+ } else {
+ if (!bridge_->Start(this)) {
+ bridge_.reset();
+ return CPERR_FAILURE;
+ }
+ return CPERR_IO_PENDING;
+ }
+ }
+
+ int GetResponseInfo(CPResponseInfoType type, void* buf, uint32 buf_size) {
+ return PluginResponseUtils::GetResponseInfo(
+ response_headers_, type, buf, buf_size);
+ }
+
+ int Read(void* buf, uint32 buf_size) {
+ uint32 avail =
+ static_cast<uint32>(response_data_.size()) - response_data_offset_;
+ uint32 count = buf_size;
+ if (count > avail)
+ count = avail;
+
+ int rv = CPERR_FAILURE;
+ if (count) {
+ // Data is ready now.
+ memcpy(buf, &response_data_[0] + response_data_offset_, count);
+ response_data_offset_ += count;
+ } else if (!completed_) {
+ read_buffer_ = buf;
+ read_buffer_size_ = buf_size;
+ DCHECK(!sync_);
+ return CPERR_IO_PENDING;
+ }
+
+ if (response_data_.size() == response_data_offset_) {
+ // Simple optimization for large requests. Generally the consumer will
+ // read the data faster than it comes in, so we can clear our buffer
+ // any time it has all been read.
+ response_data_.clear();
+ response_data_offset_ = 0;
+ }
+
+ read_buffer_ = NULL;
+ return count;
+ }
+
+ private:
+ scoped_ptr<ScopableCPRequest> cprequest_;
+ WebFrame* webframe_;
+ scoped_ptr<ResourceLoaderBridge> bridge_;
+ std::vector<net::UploadData::Element> upload_content_;
+ std::string extra_headers_;
+ uint32 load_flags_;
+ bool sync_;
+
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
+ std::string response_data_;
+ int response_data_offset_;
+ bool completed_;
+ void* read_buffer_;
+ uint32 read_buffer_size_;
+};
+
+//
+// Generic functions
+//
+
+// TODO(mpcomplete): call up to browser to ask for a valid browsing context.
+WebPlugin* WebPluginFromContext(CPBrowsingContext context) {
+ return reinterpret_cast<WebPlugin*>(static_cast<LONG_PTR>(context));
+}
+
+CPBrowsingContext ContextFromWebPlugin(WebPlugin* webplugin) {
+ return static_cast<CPBrowsingContext>(reinterpret_cast<LONG_PTR>(webplugin));
+}
+
+void STDCALL CPB_SetKeepProcessAlive(CPID id, CPBool keep_alive) {
+ // Doesn't apply in the renderer process.
+}
+
+CPError STDCALL CPB_GetCookies(CPID id, CPBrowsingContext context,
+ const char* url, char** cookies) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ std::string cookies_str = webkit_glue::GetCookies(GURL(url), 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) {
+ CHECK(ChromePluginLib::IsPluginThread());
+
+ WebPlugin* webplugin = WebPluginFromContext(context);
+ if (!webplugin)
+ return CPERR_INVALID_PARAMETER;
+
+ std::string retval_str;
+ webplugin->ShowModalHTMLDialog(
+ GURL(url), width, height, json_arguments, &retval_str);
+ *json_retval = CPB_StringDup(CPB_Alloc, retval_str);
+ return CPERR_SUCCESS;
+}
+
+CPError STDCALL CPB_ShowHtmlDialog(
+ CPID id, CPBrowsingContext context, const char* url, int width, int height,
+ const char* json_arguments, void* plugin_context) {
+ // TODO(mpcomplete): support non-modal dialogs.
+ return CPERR_FAILURE;
+}
+
+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(NPP npp) {
+ if (!npp)
+ return CPERR_INVALID_PARAMETER;
+
+ NPAPI::PluginInstance* instance =
+ static_cast<NPAPI::PluginInstance *>(npp->ndata);
+ return ContextFromWebPlugin(instance->webplugin());
+}
+
+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*);
+
+ std::wstring wretval;
+ if (!RenderThread::current()->Send(new ViewHostMsg_GetDataDir(&wretval)))
+ return CPERR_FAILURE;
+ file_util::AppendToPath(&wretval, chrome::kChromePluginDataDirname);
+ *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, WideToUTF8(wretval));
+ return CPERR_SUCCESS;
+ }
+ case CPBROWSINGCONTEXT_UI_LOCALE_PTR: {
+ if (buf_size < sizeof(char*))
+ return sizeof(char*);
+
+ std::wstring wretval = webkit_glue::GetWebKitLocale();
+ *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, WideToUTF8(wretval));
+ return CPERR_SUCCESS;
+ }
+ }
+
+ return CPERR_FAILURE;
+}
+
+CPError STDCALL CPB_AddUICommand(CPID id, int command) {
+ // Not implemented in the renderer process
+ return CPERR_FAILURE;
+}
+
+CPError STDCALL CPB_HandleCommand(
+ CPID id, CPBrowsingContext context, int command, void *data) {
+ // Not implemented in the renderer process
+ return CPERR_FAILURE;
+}
+
+//
+// Functions related to network interception
+//
+
+void STDCALL CPB_EnableRequestIntercept(
+ CPID id, const char** schemes, uint32 num_schemes) {
+ // We ignore requests by the plugin to intercept from this process. That's
+ // handled in the browser process.
+}
+
+void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
+ NOTREACHED() << "Network interception should not happen in renderer process.";
+}
+
+void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
+ NOTREACHED() << "Network interception should not happen in renderer process.";
+}
+
+void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
+ NOTREACHED() << "Network interception should not happen in renderer process.";
+}
+
+void STDCALL CPRR_UploadProgress(CPRequest* request, uint64 pos, uint64 size) {
+ NOTREACHED() << "Network interception should not happen in renderer process.";
+}
+
+//
+// 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);
+
+ WebPlugin* webplugin = WebPluginFromContext(context);
+ WebFrame* webframe = webplugin->GetWebFrame();
+ ScopableCPRequest* cprequest = new ScopableCPRequest(url, method, context);
+ PluginRequestHandlerProxy* handler =
+ new PluginRequestHandlerProxy(plugin, cprequest, webframe);
+
+ *request = cprequest;
+ return CPERR_SUCCESS;
+}
+
+CPError STDCALL CPR_StartRequest(CPRequest* request) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+ return handler->Start();
+}
+
+void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ delete handler;
+}
+
+void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
+ const char* headers) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+ handler->set_extra_headers(headers);
+}
+
+void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+
+ if (flags & CPREQUESTLOAD_SYNCHRONOUS) {
+ handler->set_sync(true);
+ }
+
+ uint32 net_flags = PluginResponseUtils::CPLoadFlagsToNetFlags(flags);
+ handler->set_load_flags(net_flags);
+}
+
+void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
+ int bytes_len) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+ handler->AppendDataToUpload(bytes, bytes_len);
+}
+
+CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
+ uint64 offset, uint64 length) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+
+ if (!length) length = kuint64max;
+ std::wstring wfilepath(UTF8ToWide(filepath));
+ handler->AppendFileRangeToUpload(wfilepath, offset, length);
+ return CPERR_SUCCESS;
+}
+
+int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
+ void* buf, uint32 buf_size) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+ return handler->GetResponseInfo(type, buf, buf_size);
+}
+
+int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ PluginRequestHandlerProxy* handler =
+ PluginRequestHandlerProxy::FromCPRequest(request);
+ CHECK(handler);
+ return handler->Read(buf, buf_size);
+}
+
+CPBool STDCALL CPB_IsPluginProcessRunning(CPID id) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ return true;
+}
+
+CPProcessType STDCALL CPB_GetProcessType(CPID id) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ return CP_PROCESS_RENDERER;
+}
+
+CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
+ CHECK(ChromePluginLib::IsPluginThread());
+ ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
+ CHECK(plugin);
+
+ const uint8* data_ptr = static_cast<const uint8*>(data);
+ std::vector<uint8> v(data_ptr, data_ptr + data_len);
+ if (!RenderThread::current()->Send(new ViewHostMsg_PluginMessage(
+ plugin->filename(), v))) {
+ return CPERR_FAILURE;
+ }
+ return CPERR_SUCCESS;
+}
+
+} // namespace
+
+CPBrowserFuncs* GetCPBrowserFuncsForRenderer() {
+ 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 = CPB_ShowHtmlDialog;
+ browser_funcs.show_html_dialog_modal = CPB_ShowHtmlDialogModal;
+ 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;
+
+ 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;
+}
diff --git a/chrome/renderer/chrome_plugin_host.h b/chrome/renderer/chrome_plugin_host.h
new file mode 100644
index 0000000..4587ded
--- /dev/null
+++ b/chrome/renderer/chrome_plugin_host.h
@@ -0,0 +1,38 @@
+// Copyright 2008, Google Inc.
+// 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 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 CHROME_RENDERER_CHROME_PLUGIN_HOST_H__
+#define CHROME_RENDERER_CHROME_PLUGIN_HOST_H__
+
+#include "chrome/common/chrome_plugin_api.h"
+
+// Returns the table of browser functions for use from the renderer process.
+CPBrowserFuncs* GetCPBrowserFuncsForRenderer();
+
+#endif // CHROME_RENDERER_CHROME_PLUGIN_HOST_H__
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 5282cad..b37cf454 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -34,6 +34,7 @@
#include "base/shared_memory.h"
#include "chrome/common/ipc_logging.h"
+#include "chrome/common/notification_service.h"
#include "chrome/plugin/plugin_channel.h"
#include "chrome/renderer/net/render_dns_master.h"
#include "chrome/renderer/render_process.h"
@@ -108,6 +109,8 @@ void RenderThread::Init() {
DCHECK(tls_index_) << "static initializer failed";
DCHECK(!current()) << "should only have one RenderThread per thread";
+ notification_service_.reset(new NotificationService);
+
cache_stats_factory_.reset(
new ScopedRunnableMethodFactory<RenderThread>(this));
@@ -145,6 +148,8 @@ void RenderThread::CleanUp() {
IPC::Logging::current()->SetIPCSender(NULL);
#endif
+ notification_service_.reset();
+
delete visited_link_slave_;
visited_link_slave_ = NULL;
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index ca022671..9463a20 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -43,6 +43,7 @@ class Task;
class VisitedLinkSlave;
struct WebPreferences;
class RenderDnsMaster;
+class NotificationService;
// The RenderThread class represents a background thread where RenderView
// instances live. The RenderThread supports an API that is used by its
@@ -137,6 +138,8 @@ class RenderThread : public IPC::Channel::Listener,
scoped_ptr<ScopedRunnableMethodFactory<RenderThread> > cache_stats_factory_;
+ scoped_ptr<NotificationService> notification_service_;
+
int in_send_;
DISALLOW_EVIL_CONSTRUCTORS(RenderThread);
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 2d93886..0d57727 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -52,7 +52,9 @@
#include "chrome/common/resource_bundle.h"
#include "chrome/common/text_zoom.h"
#include "chrome/common/thumbnail_score.h"
+#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/renderer/about_handler.h"
+#include "chrome/renderer/chrome_plugin_host.h"
#include "chrome/renderer/debug_message_handler.h"
#include "chrome/renderer/localized_error.h"
#include "chrome/renderer/renderer_resources.h"
@@ -1659,13 +1661,28 @@ WebWidget* RenderView::CreatePopupWidget(WebView* webview) {
return widget->webwidget();
}
+static bool ShouldLoadPluginInProcess(const std::string& mime_type,
+ bool* is_gears) {
+ if (RenderProcess::ShouldLoadPluginsInProcess())
+ return true;
+
+ if (mime_type == "application/x-googlegears") {
+ *is_gears = true;
+ CommandLine cmd;
+ return cmd.HasSwitch(switches::kGearsInRenderer);
+ }
+
+ return false;
+}
+
WebPluginDelegate* RenderView::CreatePluginDelegate(
WebView* webview,
const GURL& url,
const std::string& mime_type,
const std::string& clsid,
std::string* actual_mime_type) {
- if (RenderProcess::ShouldLoadPluginsInProcess()) {
+ bool is_gears = false;
+ if (ShouldLoadPluginInProcess(mime_type, &is_gears)) {
std::wstring path;
RenderThread::current()->Send(
new ViewHostMsg_GetPluginPath(url, mime_type, clsid, &path,
@@ -1679,6 +1696,8 @@ WebPluginDelegate* RenderView::CreatePluginDelegate(
else
mime_type_to_use = mime_type;
+ if (is_gears)
+ ChromePluginLib::Create(path, GetCPBrowserFuncsForRenderer());
return WebPluginDelegateImpl::Create(path, mime_type_to_use, host_window_);
}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index c04be51..cf3c0d1 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -116,6 +116,9 @@ class RenderView : public RenderWidget, public WebViewDelegate,
virtual void OnMessageReceived(const IPC::Message& msg);
// WebViewDelegate
+ virtual void ShowModalHTMLDialog(const GURL& url, int width, int height,
+ const std::string& json_arguments,
+ std::string* json_retval);
virtual void RunJavaScriptAlert(WebView* webview,
const std::wstring& message);
virtual bool RunJavaScriptConfirm(WebView* webview,
@@ -276,11 +279,6 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// Called when a plugin is crashed.
void PluginCrashed(const std::wstring& plugin_path);
- // Shows a modal HTML dialog.
- void ShowModalHTMLDialog(const GURL& url, int width, int height,
- const std::string& json_arguments,
- std::string* json_retval);
-
// Called from JavaScript window.external.AddSearchProvider() to add a
// keyword for a provider described in the given OpenSearch document.
void AddSearchProvider(const std::string& url);
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index 7f867bd..753f517 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -162,6 +162,14 @@
>
</File>
<File
+ RelativePath=".\chrome_plugin_host.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\chrome_plugin_host.h"
+ >
+ </File>
+ <File
RelativePath=".\debug_message_handler.cc"
>
</File>