Index: chrome/browser/extensions/extension_function_dispatcher.cc |
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc |
index 0eb742ae2127b6c97b65f82cecbe4a6629649c27..3e1a761af10bec90b4581fa096e798a060b98787 100644 |
--- a/chrome/browser/extensions/extension_function_dispatcher.cc |
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc |
@@ -46,6 +46,7 @@ |
#include "chrome/browser/extensions/extensions_quota_service.h" |
#include "chrome/browser/external_protocol/external_protocol_handler.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
#include "chrome/browser/ui/browser_list.h" |
#include "chrome/browser/ui/browser_window.h" |
#include "chrome/common/extensions/extension_messages.h" |
@@ -411,6 +412,36 @@ void ExtensionFunctionDispatcher::ResetFunctions() { |
FactoryRegistry::GetInstance()->ResetFunctions(); |
} |
+// static |
+void ExtensionFunctionDispatcher::DispatchOnIOThread( |
+ const ExtensionInfoMap* extension_info_map, |
+ ProfileId profile_id, |
+ int render_process_id, |
+ base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, |
+ int routing_id, |
+ const ExtensionHostMsg_Request_Params& params) { |
+ const Extension* extension = |
+ extension_info_map->extensions().GetByURL(params.source_url); |
+ |
+ scoped_refptr<ExtensionFunction> function( |
+ CreateExtensionFunction(params, extension, profile_id, render_process_id, |
+ ipc_sender, routing_id)); |
+ if (!function) |
+ return; |
+ |
+ IOThreadExtensionFunction* function_io = |
+ function->AsIOThreadExtensionFunction(); |
+ if (!function_io) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ function_io->set_ipc_sender(ipc_sender, routing_id); |
+ function_io->set_extension_info_map(extension_info_map); |
+ function->set_include_incognito( |
+ extension_info_map->IsIncognitoEnabled(extension->id())); |
+ function->Run(); |
+} |
+ |
ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile, |
Delegate* delegate) |
: profile_(profile), |
@@ -448,21 +479,6 @@ Browser* ExtensionFunctionDispatcher::GetCurrentBrowser( |
void ExtensionFunctionDispatcher::Dispatch( |
const ExtensionHostMsg_Request_Params& params, |
RenderViewHost* render_view_host) { |
- // TODO(aa): It would be cool to use ExtensionProcessManager to track which |
- // processes are extension processes rather than ChildProcessSecurityPolicy. |
- // EPM has richer information: it not only knows which processes contain |
- // at least one extension, but it knows which extensions are inside and what |
- // permissions the have. So we would be able to enforce permissions more |
- // granularly. |
- if (!ChildProcessSecurityPolicy::GetInstance()->HasExtensionBindings( |
- render_view_host->process()->id())) { |
- // TODO(aa): Allow content scripts access to low-threat extension APIs. |
- // See: crbug.com/80308. |
- LOG(ERROR) << "Extension API called from non-extension process."; |
- SendAccessDenied(render_view_host, params.request_id); |
- return; |
- } |
- |
ExtensionService* service = profile()->GetExtensionService(); |
if (!service) |
return; |
@@ -470,7 +486,8 @@ void ExtensionFunctionDispatcher::Dispatch( |
if (!service->ExtensionBindingsAllowed(params.source_url)) { |
LOG(ERROR) << "Extension bindings not allowed for URL: " |
<< params.source_url.spec(); |
- SendAccessDenied(render_view_host, params.request_id); |
+ SendAccessDenied(render_view_host, render_view_host->routing_id(), |
+ params.request_id); |
return; |
} |
@@ -479,22 +496,14 @@ void ExtensionFunctionDispatcher::Dispatch( |
const Extension* extension = service->GetExtensionByURL(params.source_url); |
if (!extension) |
extension = service->GetExtensionByWebExtent(params.source_url); |
- if (!extension) { |
- LOG(ERROR) << "Extension does not exist for URL: " |
- << params.source_url.spec(); |
- SendAccessDenied(render_view_host, params.request_id); |
- return; |
- } |
- if (!extension->HasApiPermission(params.name)) { |
- LOG(ERROR) << "Extension " << extension->id() << " does not have " |
- << "permission to function: " << params.name; |
- SendAccessDenied(render_view_host, params.request_id); |
+ scoped_refptr<ExtensionFunction> function(CreateExtensionFunction( |
+ params, extension, profile_->GetRuntimeId(), |
+ render_view_host->process()->id(), |
+ render_view_host, render_view_host->routing_id())); |
+ if (!function) |
return; |
- } |
- scoped_refptr<ExtensionFunction> function( |
- FactoryRegistry::GetInstance()->NewFunction(params.name)); |
UIThreadExtensionFunction* function_ui = |
function->AsUIThreadExtensionFunction(); |
if (!function_ui) { |
@@ -504,14 +513,6 @@ void ExtensionFunctionDispatcher::Dispatch( |
function_ui->SetRenderViewHost(render_view_host); |
function_ui->set_dispatcher(AsWeakPtr()); |
function_ui->set_profile(profile_); |
- |
- function->set_profile_id(profile_->GetRuntimeId()); |
- function->set_extension(extension); |
- function->SetArgs(¶ms.arguments); |
- function->set_source_url(params.source_url); |
- function->set_request_id(params.request_id); |
- function->set_has_callback(params.has_callback); |
- function->set_user_gesture(params.user_gesture); |
function->set_include_incognito(service->CanCrossIncognito(extension)); |
ExtensionsQuotaService* quota = service->quota_service(); |
@@ -528,9 +529,59 @@ void ExtensionFunctionDispatcher::Dispatch( |
} |
} |
+// static |
+ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( |
+ const ExtensionHostMsg_Request_Params& params, |
+ const Extension* extension, |
+ ProfileId profile_id, |
+ int render_process_id, |
+ IPC::Message::Sender* ipc_sender, |
+ int routing_id) { |
+ // TODO(aa): It would be cool to use ExtensionProcessManager to track which |
+ // processes are extension processes rather than ChildProcessSecurityPolicy. |
+ // EPM has richer information: it not only knows which processes contain |
+ // at least one extension, but it knows which extensions are inside and what |
+ // permissions the have. So we would be able to enforce permissions more |
+ // granularly. |
+ if (!ChildProcessSecurityPolicy::GetInstance()->HasExtensionBindings( |
+ render_process_id)) { |
+ // TODO(aa): Allow content scripts access to low-threat extension APIs. |
+ // See: crbug.com/80308. |
+ LOG(ERROR) << "Extension API called from non-extension process."; |
+ SendAccessDenied(ipc_sender, routing_id, params.request_id); |
+ return NULL; |
+ } |
+ |
+ if (!extension) { |
+ LOG(ERROR) << "Extension does not exist for URL: " |
+ << params.source_url.spec(); |
+ SendAccessDenied(ipc_sender, routing_id, params.request_id); |
+ return NULL; |
+ } |
+ |
+ if (!extension->HasApiPermission(params.name)) { |
+ LOG(ERROR) << "Extension " << extension->id() << " does not have " |
+ << "permission to function: " << params.name; |
+ SendAccessDenied(ipc_sender, routing_id, params.request_id); |
+ return NULL; |
+ } |
+ |
+ ExtensionFunction* function = |
+ FactoryRegistry::GetInstance()->NewFunction(params.name); |
+ function->SetArgs(¶ms.arguments); |
+ function->set_source_url(params.source_url); |
+ function->set_request_id(params.request_id); |
+ function->set_has_callback(params.has_callback); |
+ function->set_user_gesture(params.user_gesture); |
+ function->set_extension(extension); |
+ function->set_profile_id(profile_id); |
+ return function; |
+} |
+ |
+// static |
void ExtensionFunctionDispatcher::SendAccessDenied( |
- RenderViewHost* render_view_host, int request_id) { |
- render_view_host->Send(new ExtensionMsg_Response( |
- render_view_host->routing_id(), request_id, false, std::string(), |
+ IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { |
+ ipc_sender->Send(new ExtensionMsg_Response( |
+ routing_id, request_id, false, std::string(), |
"Access to extension API denied.")); |
} |