Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 5 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
| 10 #include "base/lazy_instance.h" | |
| 10 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 11 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 12 #include "base/values.h" | 13 #include "base/values.h" |
| 13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 14 #include "chrome/browser/extensions/extension_activity_log.h" | 15 #include "chrome/browser/extensions/extension_activity_log.h" |
| 15 #include "chrome/browser/extensions/extension_function.h" | 16 #include "chrome/browser/extensions/extension_function.h" |
| 16 #include "chrome/browser/extensions/extension_function_registry.h" | 17 #include "chrome/browser/extensions/extension_function_registry.h" |
| 17 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
| 18 #include "chrome/browser/extensions/extension_web_ui.h" | 19 #include "chrome/browser/extensions/extension_web_ui.h" |
| 19 #include "chrome/browser/extensions/extensions_quota_service.h" | 20 #include "chrome/browser/extensions/extensions_quota_service.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 32 #include "ipc/ipc_message.h" | 33 #include "ipc/ipc_message.h" |
| 33 #include "ipc/ipc_message_macros.h" | 34 #include "ipc/ipc_message_macros.h" |
| 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 35 #include "third_party/skia/include/core/SkBitmap.h" | 36 #include "third_party/skia/include/core/SkBitmap.h" |
| 36 #include "webkit/glue/resource_type.h" | 37 #include "webkit/glue/resource_type.h" |
| 37 | 38 |
| 38 using extensions::ExtensionAPI; | 39 using extensions::ExtensionAPI; |
| 39 using content::RenderViewHost; | 40 using content::RenderViewHost; |
| 40 using WebKit::WebSecurityOrigin; | 41 using WebKit::WebSecurityOrigin; |
| 41 | 42 |
| 43 namespace { | |
| 44 | |
| 42 const char kAccessDenied[] = "access denied"; | 45 const char kAccessDenied[] = "access denied"; |
| 43 const char kQuotaExceeded[] = "quota exceeded"; | 46 const char kQuotaExceeded[] = "quota exceeded"; |
| 44 | 47 |
| 45 void LogSuccess(const Extension* extension, | 48 void LogSuccess(const Extension* extension, |
| 46 const ExtensionHostMsg_Request_Params& params) { | 49 const ExtensionHostMsg_Request_Params& params) { |
| 47 ExtensionActivityLog* extension_activity_log = | 50 ExtensionActivityLog* extension_activity_log = |
| 48 ExtensionActivityLog::GetInstance(); | 51 ExtensionActivityLog::GetInstance(); |
| 49 if (extension_activity_log->HasObservers(extension)) { | 52 if (extension_activity_log->HasObservers(extension)) { |
| 50 std::string call_signature = params.name + "("; | 53 std::string call_signature = params.name + "("; |
| 51 ListValue::const_iterator it = params.arguments.begin(); | 54 ListValue::const_iterator it = params.arguments.begin(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 73 ExtensionActivityLog* extension_activity_log = | 76 ExtensionActivityLog* extension_activity_log = |
| 74 ExtensionActivityLog::GetInstance(); | 77 ExtensionActivityLog::GetInstance(); |
| 75 if (extension_activity_log->HasObservers(extension)) { | 78 if (extension_activity_log->HasObservers(extension)) { |
| 76 extension_activity_log->Log( | 79 extension_activity_log->Log( |
| 77 extension, | 80 extension, |
| 78 ExtensionActivityLog::ACTIVITY_EXTENSION_API_BLOCK, | 81 ExtensionActivityLog::ACTIVITY_EXTENSION_API_BLOCK, |
| 79 func_name + ": " + reason); | 82 func_name + ": " + reason); |
| 80 } | 83 } |
| 81 } | 84 } |
| 82 | 85 |
| 86 // Separate copy of ExtensionAPI used for IO thread extension functions. We need | |
| 87 // this because ExtensionAPI has mutable data. It should be possible to remove | |
| 88 // this once all the extension APIs are updated to the feature system. | |
| 89 struct Static { | |
| 90 Static() | |
| 91 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { | |
| 92 } | |
| 93 scoped_ptr<extensions::ExtensionAPI> api; | |
| 94 }; | |
| 95 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; | |
| 96 | |
| 97 } | |
|
Matt Perry
2012/04/04 16:40:22
} // namespace
Aaron Boodman
2012/04/04 18:05:42
Done.
| |
| 98 | |
| 83 void ExtensionFunctionDispatcher::GetAllFunctionNames( | 99 void ExtensionFunctionDispatcher::GetAllFunctionNames( |
| 84 std::vector<std::string>* names) { | 100 std::vector<std::string>* names) { |
| 85 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); | 101 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); |
| 86 } | 102 } |
| 87 | 103 |
| 88 bool ExtensionFunctionDispatcher::OverrideFunction( | 104 bool ExtensionFunctionDispatcher::OverrideFunction( |
| 89 const std::string& name, ExtensionFunctionFactory factory) { | 105 const std::string& name, ExtensionFunctionFactory factory) { |
| 90 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, | 106 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, |
| 91 factory); | 107 factory); |
| 92 } | 108 } |
| 93 | 109 |
| 94 void ExtensionFunctionDispatcher::ResetFunctions() { | 110 void ExtensionFunctionDispatcher::ResetFunctions() { |
| 95 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); | 111 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); |
| 96 } | 112 } |
| 97 | 113 |
| 98 // static | 114 // static |
| 99 void ExtensionFunctionDispatcher::DispatchOnIOThread( | 115 void ExtensionFunctionDispatcher::DispatchOnIOThread( |
| 100 ExtensionInfoMap* extension_info_map, | 116 ExtensionInfoMap* extension_info_map, |
| 101 void* profile, | 117 void* profile, |
| 102 int render_process_id, | 118 int render_process_id, |
| 103 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, | 119 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, |
| 104 int routing_id, | 120 int routing_id, |
| 105 const ExtensionHostMsg_Request_Params& params) { | 121 const ExtensionHostMsg_Request_Params& params) { |
| 106 const Extension* extension = | 122 const Extension* extension = |
| 107 extension_info_map->extensions().GetByID(params.extension_id); | 123 extension_info_map->extensions().GetByID(params.extension_id); |
| 108 | 124 |
| 109 scoped_refptr<ExtensionFunction> function( | 125 scoped_refptr<ExtensionFunction> function( |
| 110 CreateExtensionFunction(params, extension, render_process_id, | 126 CreateExtensionFunction(params, extension, render_process_id, |
| 111 extension_info_map->process_map(), profile, | 127 extension_info_map->process_map(), |
| 128 g_global_io_data.Get().api.get(), | |
| 129 profile, | |
| 112 ipc_sender, routing_id)); | 130 ipc_sender, routing_id)); |
| 113 if (!function) { | 131 if (!function) { |
| 114 LogFailure(extension, params.name, kAccessDenied); | 132 LogFailure(extension, params.name, kAccessDenied); |
| 115 return; | 133 return; |
| 116 } | 134 } |
| 117 | 135 |
| 118 IOThreadExtensionFunction* function_io = | 136 IOThreadExtensionFunction* function_io = |
| 119 function->AsIOThreadExtensionFunction(); | 137 function->AsIOThreadExtensionFunction(); |
| 120 if (!function_io) { | 138 if (!function_io) { |
| 121 NOTREACHED(); | 139 NOTREACHED(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 params.extension_id); | 202 params.extension_id); |
| 185 if (!extension) | 203 if (!extension) |
| 186 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( | 204 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( |
| 187 WebSecurityOrigin::createFromString(params.source_origin), | 205 WebSecurityOrigin::createFromString(params.source_origin), |
| 188 params.source_url)); | 206 params.source_url)); |
| 189 | 207 |
| 190 scoped_refptr<ExtensionFunction> function( | 208 scoped_refptr<ExtensionFunction> function( |
| 191 CreateExtensionFunction(params, extension, | 209 CreateExtensionFunction(params, extension, |
| 192 render_view_host->GetProcess()->GetID(), | 210 render_view_host->GetProcess()->GetID(), |
| 193 *(service->process_map()), | 211 *(service->process_map()), |
| 212 extensions::ExtensionAPI::GetSharedInstance(), | |
| 194 profile(), render_view_host, | 213 profile(), render_view_host, |
| 195 render_view_host->GetRoutingID())); | 214 render_view_host->GetRoutingID())); |
| 196 if (!function) { | 215 if (!function) { |
| 197 LogFailure(extension, params.name, kAccessDenied); | 216 LogFailure(extension, params.name, kAccessDenied); |
| 198 return; | 217 return; |
| 199 } | 218 } |
| 200 | 219 |
| 201 UIThreadExtensionFunction* function_ui = | 220 UIThreadExtensionFunction* function_ui = |
| 202 function->AsUIThreadExtensionFunction(); | 221 function->AsUIThreadExtensionFunction(); |
| 203 if (!function_ui) { | 222 if (!function_ui) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( | 254 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( |
| 236 extension); | 255 extension); |
| 237 } | 256 } |
| 238 | 257 |
| 239 // static | 258 // static |
| 240 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( | 259 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( |
| 241 const ExtensionHostMsg_Request_Params& params, | 260 const ExtensionHostMsg_Request_Params& params, |
| 242 const Extension* extension, | 261 const Extension* extension, |
| 243 int requesting_process_id, | 262 int requesting_process_id, |
| 244 const extensions::ProcessMap& process_map, | 263 const extensions::ProcessMap& process_map, |
| 264 extensions::ExtensionAPI* api, | |
| 245 void* profile, | 265 void* profile, |
| 246 IPC::Message::Sender* ipc_sender, | 266 IPC::Message::Sender* ipc_sender, |
| 247 int routing_id) { | 267 int routing_id) { |
| 248 if (!extension) { | 268 if (!extension) { |
| 249 LOG(ERROR) << "Specified extension does not exist."; | 269 LOG(ERROR) << "Specified extension does not exist."; |
| 250 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 270 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 251 return NULL; | 271 return NULL; |
| 252 } | 272 } |
| 253 | 273 |
| 254 if (ExtensionAPI::GetInstance()->IsPrivileged(params.name) && | 274 if (api->IsPrivileged(params.name) && |
| 255 !process_map.Contains(extension->id(), requesting_process_id)) { | 275 !process_map.Contains(extension->id(), requesting_process_id)) { |
| 256 LOG(ERROR) << "Extension API called from incorrect process " | 276 LOG(ERROR) << "Extension API called from incorrect process " |
| 257 << requesting_process_id | 277 << requesting_process_id |
| 258 << " from URL " << params.source_url.spec(); | 278 << " from URL " << params.source_url.spec(); |
| 259 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 279 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 260 return NULL; | 280 return NULL; |
| 261 } | 281 } |
| 262 | 282 |
| 263 if (!extension->HasAPIPermission(params.name)) { | 283 if (!extension->HasAPIPermission(params.name)) { |
| 264 LOG(ERROR) << "Extension " << extension->id() << " does not have " | 284 LOG(ERROR) << "Extension " << extension->id() << " does not have " |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 279 return function; | 299 return function; |
| 280 } | 300 } |
| 281 | 301 |
| 282 // static | 302 // static |
| 283 void ExtensionFunctionDispatcher::SendAccessDenied( | 303 void ExtensionFunctionDispatcher::SendAccessDenied( |
| 284 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { | 304 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { |
| 285 ipc_sender->Send(new ExtensionMsg_Response( | 305 ipc_sender->Send(new ExtensionMsg_Response( |
| 286 routing_id, request_id, false, std::string(), | 306 routing_id, request_id, false, std::string(), |
| 287 "Access to extension API denied.")); | 307 "Access to extension API denied.")); |
| 288 } | 308 } |
| OLD | NEW |