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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/process/process.h" | 12 #include "base/process/process.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
15 #include "chrome/browser/extensions/activity_log/activity_action_constants.h" | |
16 #include "chrome/browser/extensions/activity_log/activity_log.h" | |
17 #include "chrome/browser/extensions/api/activity_log_private/activity_log_privat
e_api.h" | |
18 #include "chrome/browser/extensions/extension_function_registry.h" | 15 #include "chrome/browser/extensions/extension_function_registry.h" |
19 #include "chrome/browser/extensions/extension_util.h" | 16 #include "chrome/browser/extensions/extension_util.h" |
20 #include "chrome/browser/extensions/extension_web_ui.h" | 17 #include "chrome/browser/extensions/extension_web_ui.h" |
21 #include "chrome/browser/external_protocol/external_protocol_handler.h" | 18 #include "chrome/browser/external_protocol/external_protocol_handler.h" |
22 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" | 19 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
23 #include "chrome/common/extensions/extension_messages.h" | 20 #include "chrome/common/extensions/extension_messages.h" |
24 #include "chrome/common/url_constants.h" | 21 #include "chrome/common/url_constants.h" |
25 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
26 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
27 #include "content/public/browser/render_process_host.h" | 24 #include "content/public/browser/render_process_host.h" |
28 #include "content/public/browser/render_view_host.h" | 25 #include "content/public/browser/render_view_host.h" |
29 #include "content/public/browser/user_metrics.h" | 26 #include "content/public/browser/user_metrics.h" |
30 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
31 #include "content/public/browser/web_contents_observer.h" | 28 #include "content/public/browser/web_contents_observer.h" |
32 #include "content/public/common/result_codes.h" | 29 #include "content/public/common/result_codes.h" |
| 30 #include "extensions/browser/api_activity_monitor.h" |
33 #include "extensions/browser/extension_registry.h" | 31 #include "extensions/browser/extension_registry.h" |
34 #include "extensions/browser/extension_system.h" | 32 #include "extensions/browser/extension_system.h" |
| 33 #include "extensions/browser/extensions_browser_client.h" |
35 #include "extensions/browser/process_manager.h" | 34 #include "extensions/browser/process_manager.h" |
36 #include "extensions/browser/process_map.h" | 35 #include "extensions/browser/process_map.h" |
37 #include "extensions/browser/quota_service.h" | 36 #include "extensions/browser/quota_service.h" |
38 #include "extensions/common/extension_api.h" | 37 #include "extensions/common/extension_api.h" |
39 #include "extensions/common/extension_set.h" | 38 #include "extensions/common/extension_set.h" |
40 #include "ipc/ipc_message.h" | 39 #include "ipc/ipc_message.h" |
41 #include "ipc/ipc_message_macros.h" | 40 #include "ipc/ipc_message_macros.h" |
42 #include "webkit/common/resource_type.h" | 41 #include "webkit/common/resource_type.h" |
43 | 42 |
44 using extensions::Extension; | 43 using extensions::Extension; |
45 using extensions::ExtensionAPI; | 44 using extensions::ExtensionAPI; |
46 using extensions::ExtensionSystem; | 45 using extensions::ExtensionSystem; |
47 using extensions::Feature; | 46 using extensions::Feature; |
| 47 using content::BrowserThread; |
48 using content::RenderViewHost; | 48 using content::RenderViewHost; |
49 | 49 |
50 namespace { | 50 namespace { |
51 | 51 |
52 void LogSuccess(const std::string& extension_id, | 52 // Notifies the ApiActivityMonitor that an extension API function has been |
53 const std::string& api_name, | 53 // called. May be called from any thread. |
54 scoped_ptr<base::ListValue> args, | 54 void NotifyApiFunctionCalled(const std::string& extension_id, |
55 content::BrowserContext* browser_context) { | 55 const std::string& api_name, |
56 // The ActivityLog can only be accessed from the main (UI) thread. If we're | 56 scoped_ptr<base::ListValue> args, |
57 // running on the wrong thread, re-dispatch from the main thread. | 57 content::BrowserContext* browser_context) { |
| 58 // The ApiActivityLogger can only be accessed from the main (UI) thread. If |
| 59 // we're running on the wrong thread, re-dispatch from the main thread. |
58 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 60 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
59 BrowserThread::PostTask(BrowserThread::UI, | 61 BrowserThread::PostTask(BrowserThread::UI, |
60 FROM_HERE, | 62 FROM_HERE, |
61 base::Bind(&LogSuccess, | 63 base::Bind(&NotifyApiFunctionCalled, |
62 extension_id, | 64 extension_id, |
63 api_name, | 65 api_name, |
64 base::Passed(&args), | 66 base::Passed(&args), |
65 browser_context)); | 67 browser_context)); |
66 } else { | 68 return; |
67 extensions::ActivityLog* activity_log = | |
68 extensions::ActivityLog::GetInstance(browser_context); | |
69 scoped_refptr<extensions::Action> action = | |
70 new extensions::Action(extension_id, | |
71 base::Time::Now(), | |
72 extensions::Action::ACTION_API_CALL, | |
73 api_name); | |
74 action->set_args(args.Pass()); | |
75 activity_log->LogAction(action); | |
76 } | 69 } |
| 70 extensions::ApiActivityMonitor* monitor = |
| 71 extensions::ExtensionsBrowserClient::Get()->GetApiActivityMonitor( |
| 72 browser_context); |
| 73 if (monitor) |
| 74 monitor->OnApiFunctionCalled(extension_id, api_name, args.Pass()); |
77 } | 75 } |
78 | 76 |
79 // Separate copy of ExtensionAPI used for IO thread extension functions. We need | 77 // Separate copy of ExtensionAPI used for IO thread extension functions. We need |
80 // this because ExtensionAPI has mutable data. It should be possible to remove | 78 // this because ExtensionAPI has mutable data. It should be possible to remove |
81 // this once all the extension APIs are updated to the feature system. | 79 // this once all the extension APIs are updated to the feature system. |
82 struct Static { | 80 struct Static { |
83 Static() | 81 Static() |
84 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { | 82 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { |
85 } | 83 } |
86 scoped_ptr<extensions::ExtensionAPI> api; | 84 scoped_ptr<extensions::ExtensionAPI> api; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 if (!CheckPermissions(function.get(), extension, params, callback)) | 269 if (!CheckPermissions(function.get(), extension, params, callback)) |
272 return; | 270 return; |
273 | 271 |
274 extensions::QuotaService* quota = extension_info_map->GetQuotaService(); | 272 extensions::QuotaService* quota = extension_info_map->GetQuotaService(); |
275 std::string violation_error = quota->Assess(extension->id(), | 273 std::string violation_error = quota->Assess(extension->id(), |
276 function.get(), | 274 function.get(), |
277 ¶ms.arguments, | 275 ¶ms.arguments, |
278 base::TimeTicks::Now()); | 276 base::TimeTicks::Now()); |
279 if (violation_error.empty()) { | 277 if (violation_error.empty()) { |
280 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); | 278 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); |
281 LogSuccess(extension->id(), | 279 NotifyApiFunctionCalled( |
282 params.name, | 280 extension->id(), |
283 args.Pass(), | 281 params.name, |
284 static_cast<content::BrowserContext*>(browser_context)); | 282 args.Pass(), |
| 283 static_cast<content::BrowserContext*>(browser_context)); |
285 function->Run(); | 284 function->Run(); |
286 } else { | 285 } else { |
287 function->OnQuotaExceeded(violation_error); | 286 function->OnQuotaExceeded(violation_error); |
288 } | 287 } |
289 } | 288 } |
290 | 289 |
291 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( | 290 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( |
292 content::BrowserContext* browser_context, | 291 content::BrowserContext* browser_context, |
293 Delegate* delegate) | 292 Delegate* delegate) |
294 : browser_context_(browser_context), | 293 : browser_context_(browser_context), |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 extensions::QuotaService* quota = extension_system->quota_service(); | 381 extensions::QuotaService* quota = extension_system->quota_service(); |
383 std::string violation_error = quota->Assess(extension->id(), | 382 std::string violation_error = quota->Assess(extension->id(), |
384 function.get(), | 383 function.get(), |
385 ¶ms.arguments, | 384 ¶ms.arguments, |
386 base::TimeTicks::Now()); | 385 base::TimeTicks::Now()); |
387 if (violation_error.empty()) { | 386 if (violation_error.empty()) { |
388 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); | 387 scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); |
389 | 388 |
390 // See crbug.com/39178. | 389 // See crbug.com/39178. |
391 ExternalProtocolHandler::PermitLaunchUrl(); | 390 ExternalProtocolHandler::PermitLaunchUrl(); |
392 LogSuccess(extension->id(), params.name, args.Pass(), browser_context_); | 391 NotifyApiFunctionCalled( |
| 392 extension->id(), params.name, args.Pass(), browser_context_); |
393 function->Run(); | 393 function->Run(); |
394 } else { | 394 } else { |
395 function->OnQuotaExceeded(violation_error); | 395 function->OnQuotaExceeded(violation_error); |
396 } | 396 } |
397 | 397 |
398 // Note: do not access |this| after this point. We may have been deleted | 398 // Note: do not access |this| after this point. We may have been deleted |
399 // if function->Run() ended up closing the tab that owns us. | 399 // if function->Run() ended up closing the tab that owns us. |
400 | 400 |
401 // Check if extension was uninstalled by management.uninstall. | 401 // Check if extension was uninstalled by management.uninstall. |
402 if (!registry->enabled_extensions().GetByID(params.extension_id)) | 402 if (!registry->enabled_extensions().GetByID(params.extension_id)) |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 return function; | 513 return function; |
514 } | 514 } |
515 | 515 |
516 // static | 516 // static |
517 void ExtensionFunctionDispatcher::SendAccessDenied( | 517 void ExtensionFunctionDispatcher::SendAccessDenied( |
518 const ExtensionFunction::ResponseCallback& callback) { | 518 const ExtensionFunction::ResponseCallback& callback) { |
519 base::ListValue empty_list; | 519 base::ListValue empty_list; |
520 callback.Run(ExtensionFunction::FAILED, empty_list, | 520 callback.Run(ExtensionFunction::FAILED, empty_list, |
521 "Access to extension API denied."); | 521 "Access to extension API denied."); |
522 } | 522 } |
OLD | NEW |