| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/extension_function_dispatcher.h" | 5 #include "extensions/browser/extension_function_dispatcher.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_string_value_serializer.h" | 10 #include "base/json/json_string_value_serializer.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 using content::BrowserThread; | 44 using content::BrowserThread; |
| 45 using content::RenderViewHost; | 45 using content::RenderViewHost; |
| 46 | 46 |
| 47 namespace extensions { | 47 namespace extensions { |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 // Notifies the ApiActivityMonitor that an extension API function has been | 50 // Notifies the ApiActivityMonitor that an extension API function has been |
| 51 // called. May be called from any thread. | 51 // called. May be called from any thread. |
| 52 void NotifyApiFunctionCalled(const std::string& extension_id, | 52 void NotifyApiFunctionCalled(const std::string& extension_id, |
| 53 const std::string& api_name, | 53 const std::string& api_name, |
| 54 scoped_ptr<base::ListValue> args, | 54 std::unique_ptr<base::ListValue> args, |
| 55 content::BrowserContext* browser_context) { | 55 content::BrowserContext* browser_context) { |
| 56 // The ApiActivityMonitor can only be accessed from the main (UI) thread. If | 56 // The ApiActivityMonitor can only be accessed from the main (UI) thread. If |
| 57 // we're running on the wrong thread, re-dispatch from the main thread. | 57 // we're running on the wrong thread, re-dispatch from the main thread. |
| 58 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 58 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 59 BrowserThread::PostTask(BrowserThread::UI, | 59 BrowserThread::PostTask(BrowserThread::UI, |
| 60 FROM_HERE, | 60 FROM_HERE, |
| 61 base::Bind(&NotifyApiFunctionCalled, | 61 base::Bind(&NotifyApiFunctionCalled, |
| 62 extension_id, | 62 extension_id, |
| 63 api_name, | 63 api_name, |
| 64 base::Passed(&args), | 64 base::Passed(&args), |
| 65 browser_context)); | 65 browser_context)); |
| 66 return; | 66 return; |
| 67 } | 67 } |
| 68 // The BrowserContext may become invalid after the task above is posted. | 68 // The BrowserContext may become invalid after the task above is posted. |
| 69 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) | 69 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) |
| 70 return; | 70 return; |
| 71 | 71 |
| 72 ApiActivityMonitor* monitor = | 72 ApiActivityMonitor* monitor = |
| 73 ExtensionsBrowserClient::Get()->GetApiActivityMonitor(browser_context); | 73 ExtensionsBrowserClient::Get()->GetApiActivityMonitor(browser_context); |
| 74 if (monitor) | 74 if (monitor) |
| 75 monitor->OnApiFunctionCalled(extension_id, api_name, std::move(args)); | 75 monitor->OnApiFunctionCalled(extension_id, api_name, std::move(args)); |
| 76 } | 76 } |
| 77 | 77 |
| 78 // Separate copy of ExtensionAPI used for IO thread extension functions. We need | 78 // Separate copy of ExtensionAPI used for IO thread extension functions. We need |
| 79 // this because ExtensionAPI has mutable data. It should be possible to remove | 79 // this because ExtensionAPI has mutable data. It should be possible to remove |
| 80 // this once all the extension APIs are updated to the feature system. | 80 // this once all the extension APIs are updated to the feature system. |
| 81 struct Static { | 81 struct Static { |
| 82 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {} | 82 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {} |
| 83 scoped_ptr<ExtensionAPI> api; | 83 std::unique_ptr<ExtensionAPI> api; |
| 84 }; | 84 }; |
| 85 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; | 85 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; |
| 86 | 86 |
| 87 // Kills the specified process because it sends us a malformed message. | 87 // Kills the specified process because it sends us a malformed message. |
| 88 // Track the specific function's |histogram_value|, as this may indicate a bug | 88 // Track the specific function's |histogram_value|, as this may indicate a bug |
| 89 // in that API's implementation on the renderer. | 89 // in that API's implementation on the renderer. |
| 90 void KillBadMessageSender(const base::Process& process, | 90 void KillBadMessageSender(const base::Process& process, |
| 91 functions::HistogramValue histogram_value) { | 91 functions::HistogramValue histogram_value) { |
| 92 NOTREACHED(); | 92 NOTREACHED(); |
| 93 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); | 93 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 function->Run()->Execute(); | 277 function->Run()->Execute(); |
| 278 return; | 278 return; |
| 279 } | 279 } |
| 280 | 280 |
| 281 QuotaService* quota = extension_info_map->GetQuotaService(); | 281 QuotaService* quota = extension_info_map->GetQuotaService(); |
| 282 std::string violation_error = quota->Assess(extension->id(), | 282 std::string violation_error = quota->Assess(extension->id(), |
| 283 function.get(), | 283 function.get(), |
| 284 ¶ms.arguments, | 284 ¶ms.arguments, |
| 285 base::TimeTicks::Now()); | 285 base::TimeTicks::Now()); |
| 286 if (violation_error.empty()) { | 286 if (violation_error.empty()) { |
| 287 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); | 287 std::unique_ptr<base::ListValue> args(params.arguments.DeepCopy()); |
| 288 NotifyApiFunctionCalled(extension->id(), params.name, std::move(args), | 288 NotifyApiFunctionCalled(extension->id(), params.name, std::move(args), |
| 289 static_cast<content::BrowserContext*>(profile_id)); | 289 static_cast<content::BrowserContext*>(profile_id)); |
| 290 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", | 290 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", |
| 291 function->histogram_value()); | 291 function->histogram_value()); |
| 292 tracked_objects::ScopedProfile scoped_profile( | 292 tracked_objects::ScopedProfile scoped_profile( |
| 293 FROM_HERE_WITH_EXPLICIT_FUNCTION(function->name()), | 293 FROM_HERE_WITH_EXPLICIT_FUNCTION(function->name()), |
| 294 tracked_objects::ScopedProfile::ENABLED); | 294 tracked_objects::ScopedProfile::ENABLED); |
| 295 function->Run()->Execute(); | 295 function->Run()->Execute(); |
| 296 } else { | 296 } else { |
| 297 function->OnQuotaExceeded(violation_error); | 297 function->OnQuotaExceeded(violation_error); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 ProcessManager* process_manager = ProcessManager::Get(browser_context_); | 384 ProcessManager* process_manager = ProcessManager::Get(browser_context_); |
| 385 | 385 |
| 386 ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); | 386 ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); |
| 387 QuotaService* quota = extension_system->quota_service(); | 387 QuotaService* quota = extension_system->quota_service(); |
| 388 std::string violation_error = quota->Assess(extension->id(), | 388 std::string violation_error = quota->Assess(extension->id(), |
| 389 function.get(), | 389 function.get(), |
| 390 ¶ms.arguments, | 390 ¶ms.arguments, |
| 391 base::TimeTicks::Now()); | 391 base::TimeTicks::Now()); |
| 392 | 392 |
| 393 if (violation_error.empty()) { | 393 if (violation_error.empty()) { |
| 394 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); | 394 std::unique_ptr<base::ListValue> args(params.arguments.DeepCopy()); |
| 395 | 395 |
| 396 // See crbug.com/39178. | 396 // See crbug.com/39178. |
| 397 ExtensionsBrowserClient::Get()->PermitExternalProtocolHandler(); | 397 ExtensionsBrowserClient::Get()->PermitExternalProtocolHandler(); |
| 398 NotifyApiFunctionCalled(extension->id(), params.name, std::move(args), | 398 NotifyApiFunctionCalled(extension->id(), params.name, std::move(args), |
| 399 browser_context_); | 399 browser_context_); |
| 400 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", | 400 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", |
| 401 function->histogram_value()); | 401 function->histogram_value()); |
| 402 tracked_objects::ScopedProfile scoped_profile( | 402 tracked_objects::ScopedProfile scoped_profile( |
| 403 FROM_HERE_WITH_EXPLICIT_FUNCTION(function->name()), | 403 FROM_HERE_WITH_EXPLICIT_FUNCTION(function->name()), |
| 404 tracked_objects::ScopedProfile::ENABLED); | 404 tracked_objects::ScopedProfile::ENABLED); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 // static | 494 // static |
| 495 void ExtensionFunctionDispatcher::SendAccessDenied( | 495 void ExtensionFunctionDispatcher::SendAccessDenied( |
| 496 const ExtensionFunction::ResponseCallback& callback, | 496 const ExtensionFunction::ResponseCallback& callback, |
| 497 functions::HistogramValue histogram_value) { | 497 functions::HistogramValue histogram_value) { |
| 498 base::ListValue empty_list; | 498 base::ListValue empty_list; |
| 499 callback.Run(ExtensionFunction::FAILED, empty_list, | 499 callback.Run(ExtensionFunction::FAILED, empty_list, |
| 500 "Access to extension API denied.", histogram_value); | 500 "Access to extension API denied.", histogram_value); |
| 501 } | 501 } |
| 502 | 502 |
| 503 } // namespace extensions | 503 } // namespace extensions |
| OLD | NEW |