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 |