| 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 } // namespace |
| 98 |
| 99 |
| 83 void ExtensionFunctionDispatcher::GetAllFunctionNames( | 100 void ExtensionFunctionDispatcher::GetAllFunctionNames( |
| 84 std::vector<std::string>* names) { | 101 std::vector<std::string>* names) { |
| 85 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); | 102 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); |
| 86 } | 103 } |
| 87 | 104 |
| 88 bool ExtensionFunctionDispatcher::OverrideFunction( | 105 bool ExtensionFunctionDispatcher::OverrideFunction( |
| 89 const std::string& name, ExtensionFunctionFactory factory) { | 106 const std::string& name, ExtensionFunctionFactory factory) { |
| 90 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, | 107 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, |
| 91 factory); | 108 factory); |
| 92 } | 109 } |
| 93 | 110 |
| 94 void ExtensionFunctionDispatcher::ResetFunctions() { | 111 void ExtensionFunctionDispatcher::ResetFunctions() { |
| 95 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); | 112 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); |
| 96 } | 113 } |
| 97 | 114 |
| 98 // static | 115 // static |
| 99 void ExtensionFunctionDispatcher::DispatchOnIOThread( | 116 void ExtensionFunctionDispatcher::DispatchOnIOThread( |
| 100 ExtensionInfoMap* extension_info_map, | 117 ExtensionInfoMap* extension_info_map, |
| 101 void* profile, | 118 void* profile, |
| 102 int render_process_id, | 119 int render_process_id, |
| 103 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, | 120 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, |
| 104 int routing_id, | 121 int routing_id, |
| 105 const ExtensionHostMsg_Request_Params& params) { | 122 const ExtensionHostMsg_Request_Params& params) { |
| 106 const Extension* extension = | 123 const Extension* extension = |
| 107 extension_info_map->extensions().GetByID(params.extension_id); | 124 extension_info_map->extensions().GetByID(params.extension_id); |
| 108 | 125 |
| 109 scoped_refptr<ExtensionFunction> function( | 126 scoped_refptr<ExtensionFunction> function( |
| 110 CreateExtensionFunction(params, extension, render_process_id, | 127 CreateExtensionFunction(params, extension, render_process_id, |
| 111 extension_info_map->process_map(), profile, | 128 extension_info_map->process_map(), |
| 129 g_global_io_data.Get().api.get(), |
| 130 profile, |
| 112 ipc_sender, routing_id)); | 131 ipc_sender, routing_id)); |
| 113 if (!function) { | 132 if (!function) { |
| 114 LogFailure(extension, params.name, kAccessDenied); | 133 LogFailure(extension, params.name, kAccessDenied); |
| 115 return; | 134 return; |
| 116 } | 135 } |
| 117 | 136 |
| 118 IOThreadExtensionFunction* function_io = | 137 IOThreadExtensionFunction* function_io = |
| 119 function->AsIOThreadExtensionFunction(); | 138 function->AsIOThreadExtensionFunction(); |
| 120 if (!function_io) { | 139 if (!function_io) { |
| 121 NOTREACHED(); | 140 NOTREACHED(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 params.extension_id); | 203 params.extension_id); |
| 185 if (!extension) | 204 if (!extension) |
| 186 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( | 205 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( |
| 187 WebSecurityOrigin::createFromString(params.source_origin), | 206 WebSecurityOrigin::createFromString(params.source_origin), |
| 188 params.source_url)); | 207 params.source_url)); |
| 189 | 208 |
| 190 scoped_refptr<ExtensionFunction> function( | 209 scoped_refptr<ExtensionFunction> function( |
| 191 CreateExtensionFunction(params, extension, | 210 CreateExtensionFunction(params, extension, |
| 192 render_view_host->GetProcess()->GetID(), | 211 render_view_host->GetProcess()->GetID(), |
| 193 *(service->process_map()), | 212 *(service->process_map()), |
| 213 extensions::ExtensionAPI::GetSharedInstance(), |
| 194 profile(), render_view_host, | 214 profile(), render_view_host, |
| 195 render_view_host->GetRoutingID())); | 215 render_view_host->GetRoutingID())); |
| 196 if (!function) { | 216 if (!function) { |
| 197 LogFailure(extension, params.name, kAccessDenied); | 217 LogFailure(extension, params.name, kAccessDenied); |
| 198 return; | 218 return; |
| 199 } | 219 } |
| 200 | 220 |
| 201 UIThreadExtensionFunction* function_ui = | 221 UIThreadExtensionFunction* function_ui = |
| 202 function->AsUIThreadExtensionFunction(); | 222 function->AsUIThreadExtensionFunction(); |
| 203 if (!function_ui) { | 223 if (!function_ui) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( | 255 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( |
| 236 extension); | 256 extension); |
| 237 } | 257 } |
| 238 | 258 |
| 239 // static | 259 // static |
| 240 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( | 260 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( |
| 241 const ExtensionHostMsg_Request_Params& params, | 261 const ExtensionHostMsg_Request_Params& params, |
| 242 const Extension* extension, | 262 const Extension* extension, |
| 243 int requesting_process_id, | 263 int requesting_process_id, |
| 244 const extensions::ProcessMap& process_map, | 264 const extensions::ProcessMap& process_map, |
| 265 extensions::ExtensionAPI* api, |
| 245 void* profile, | 266 void* profile, |
| 246 IPC::Message::Sender* ipc_sender, | 267 IPC::Message::Sender* ipc_sender, |
| 247 int routing_id) { | 268 int routing_id) { |
| 248 if (!extension) { | 269 if (!extension) { |
| 249 LOG(ERROR) << "Specified extension does not exist."; | 270 LOG(ERROR) << "Specified extension does not exist."; |
| 250 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 271 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 251 return NULL; | 272 return NULL; |
| 252 } | 273 } |
| 253 | 274 |
| 254 if (ExtensionAPI::GetInstance()->IsPrivileged(params.name) && | 275 if (api->IsPrivileged(params.name) && |
| 255 !process_map.Contains(extension->id(), requesting_process_id)) { | 276 !process_map.Contains(extension->id(), requesting_process_id)) { |
| 256 LOG(ERROR) << "Extension API called from incorrect process " | 277 LOG(ERROR) << "Extension API called from incorrect process " |
| 257 << requesting_process_id | 278 << requesting_process_id |
| 258 << " from URL " << params.source_url.spec(); | 279 << " from URL " << params.source_url.spec(); |
| 259 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 280 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 260 return NULL; | 281 return NULL; |
| 261 } | 282 } |
| 262 | 283 |
| 263 if (!extension->HasAPIPermission(params.name)) { | 284 if (!extension->HasAPIPermission(params.name)) { |
| 264 LOG(ERROR) << "Extension " << extension->id() << " does not have " | 285 LOG(ERROR) << "Extension " << extension->id() << " does not have " |
| (...skipping 14 matching lines...) Expand all Loading... |
| 279 return function; | 300 return function; |
| 280 } | 301 } |
| 281 | 302 |
| 282 // static | 303 // static |
| 283 void ExtensionFunctionDispatcher::SendAccessDenied( | 304 void ExtensionFunctionDispatcher::SendAccessDenied( |
| 284 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { | 305 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { |
| 285 ipc_sender->Send(new ExtensionMsg_Response( | 306 ipc_sender->Send(new ExtensionMsg_Response( |
| 286 routing_id, request_id, false, std::string(), | 307 routing_id, request_id, false, std::string(), |
| 287 "Access to extension API denied.")); | 308 "Access to extension API denied.")); |
| 288 } | 309 } |
| OLD | NEW |