Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: chrome/browser/extensions/extension_function_dispatcher.cc

Issue 11421192: Save extension activity log to a file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: something about lkgr Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/extensions/blocked_actions.cc ('k') | chrome/browser/extensions/tab_helper.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/bind.h"
9 #include "base/json/json_string_value_serializer.h" 10 #include "base/json/json_string_value_serializer.h"
10 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
12 #include "base/process_util.h" 13 #include "base/process_util.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "build/build_config.h" 15 #include "build/build_config.h"
15 #include "chrome/browser/extensions/activity_log.h" 16 #include "chrome/browser/extensions/activity_log.h"
16 #include "chrome/browser/extensions/extension_function.h" 17 #include "chrome/browser/extensions/extension_function.h"
17 #include "chrome/browser/extensions/extension_function_registry.h" 18 #include "chrome/browser/extensions/extension_function_registry.h"
18 #include "chrome/browser/extensions/extension_service.h" 19 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_system.h" 20 #include "chrome/browser/extensions/extension_system.h"
20 #include "chrome/browser/extensions/extension_web_ui.h" 21 #include "chrome/browser/extensions/extension_web_ui.h"
21 #include "chrome/browser/extensions/extensions_quota_service.h" 22 #include "chrome/browser/extensions/extensions_quota_service.h"
22 #include "chrome/browser/extensions/process_map.h" 23 #include "chrome/browser/extensions/process_map.h"
23 #include "chrome/browser/external_protocol/external_protocol_handler.h" 24 #include "chrome/browser/external_protocol/external_protocol_handler.h"
24 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 26 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
26 #include "chrome/common/extensions/api/extension_api.h" 27 #include "chrome/common/extensions/api/extension_api.h"
27 #include "chrome/common/extensions/extension_messages.h" 28 #include "chrome/common/extensions/extension_messages.h"
28 #include "chrome/common/extensions/extension_set.h" 29 #include "chrome/common/extensions/extension_set.h"
29 #include "chrome/common/url_constants.h" 30 #include "chrome/common/url_constants.h"
31 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/render_process_host.h" 32 #include "content/public/browser/render_process_host.h"
31 #include "content/public/browser/render_view_host.h" 33 #include "content/public/browser/render_view_host.h"
32 #include "ipc/ipc_message.h" 34 #include "ipc/ipc_message.h"
33 #include "ipc/ipc_message_macros.h" 35 #include "ipc/ipc_message_macros.h"
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
35 #include "webkit/glue/resource_type.h" 37 #include "webkit/glue/resource_type.h"
36 38
37 using extensions::Extension; 39 using extensions::Extension;
38 using extensions::ExtensionAPI; 40 using extensions::ExtensionAPI;
39 using content::RenderViewHost; 41 using content::RenderViewHost;
40 using WebKit::WebSecurityOrigin; 42 using WebKit::WebSecurityOrigin;
41 43
42 namespace { 44 namespace {
43 45
44 const char kAccessDenied[] = "access denied"; 46 const char kAccessDenied[] = "access denied";
45 const char kQuotaExceeded[] = "quota exceeded"; 47 const char kQuotaExceeded[] = "quota exceeded";
46 48
47 void LogSuccess(const Extension* extension, 49 void LogSuccess(const Extension* extension,
48 const ExtensionHostMsg_Request_Params& params) { 50 const std::string& api_name,
49 extensions::ActivityLog* activity_log = 51 scoped_ptr<ListValue> args,
50 extensions::ActivityLog::GetInstance(); 52 Profile* profile) {
51 if (activity_log->HasObservers(extension)) { 53 // The ActivityLog can only be accessed from the main (UI) thread. If we're
52 std::string call_signature = params.name + "("; 54 // running on the wrong thread, re-dispatch from the main thread.
53 ListValue::const_iterator it = params.arguments.begin(); 55 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
54 for (; it != params.arguments.end(); ++it) { 56 BrowserThread::PostTask(BrowserThread::UI,
55 std::string arg; 57 FROM_HERE,
56 JSONStringValueSerializer serializer(&arg); 58 base::Bind(&LogSuccess,
57 if (serializer.SerializeAndOmitBinaryValues(**it)) { 59 extension,
58 if (it != params.arguments.begin()) 60 api_name,
59 call_signature += ", "; 61 Passed(args.Pass()),
60 call_signature += arg; 62 profile));
61 } 63 } else {
62 } 64 extensions::ActivityLog* activity_log =
63 call_signature += ")"; 65 extensions::ActivityLog::GetInstance(profile);
64 66 if (activity_log->HasObservers(extension))
65 activity_log->Log(extension, 67 activity_log->LogAPIAction(extension, api_name, args.get(), "");
66 extensions::ActivityLog::ACTIVITY_EXTENSION_API_CALL,
67 call_signature);
68 } 68 }
69 } 69 }
70 70
71 void LogFailure(const Extension* extension, 71 void LogFailure(const Extension* extension,
72 const std::string& func_name, 72 const std::string& api_name,
73 const char* reason) { 73 scoped_ptr<ListValue> args,
74 extensions::ActivityLog* activity_log = 74 const char* reason,
75 extensions::ActivityLog::GetInstance(); 75 Profile* profile) {
76 if (activity_log->HasObservers(extension)) { 76 // The ActivityLog can only be accessed from the main (UI) thread. If we're
77 activity_log->Log(extension, 77 // running on the wrong thread, re-dispatch from the main thread.
78 extensions::ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, 78 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
79 func_name + ": " + reason); 79 BrowserThread::PostTask(BrowserThread::UI,
80 FROM_HERE,
81 base::Bind(&LogFailure,
82 extension,
83 api_name,
84 Passed(args.Pass()),
85 reason,
86 profile));
87 } else {
88 extensions::ActivityLog* activity_log =
89 extensions::ActivityLog::GetInstance(profile);
90 if (activity_log->HasObservers(extension))
91 activity_log->LogBlockedAction(extension,
92 api_name,
93 args.get(),
94 reason,
95 "");
80 } 96 }
81 } 97 }
82 98
99
83 // Separate copy of ExtensionAPI used for IO thread extension functions. We need 100 // Separate copy of ExtensionAPI used for IO thread extension functions. We need
84 // this because ExtensionAPI has mutable data. It should be possible to remove 101 // this because ExtensionAPI has mutable data. It should be possible to remove
85 // this once all the extension APIs are updated to the feature system. 102 // this once all the extension APIs are updated to the feature system.
86 struct Static { 103 struct Static {
87 Static() 104 Static()
88 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { 105 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) {
89 } 106 }
90 scoped_ptr<extensions::ExtensionAPI> api; 107 scoped_ptr<extensions::ExtensionAPI> api;
91 }; 108 };
92 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; 109 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER;
(...skipping 29 matching lines...) Expand all
122 // static 139 // static
123 void ExtensionFunctionDispatcher::DispatchOnIOThread( 140 void ExtensionFunctionDispatcher::DispatchOnIOThread(
124 ExtensionInfoMap* extension_info_map, 141 ExtensionInfoMap* extension_info_map,
125 void* profile, 142 void* profile,
126 int render_process_id, 143 int render_process_id,
127 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, 144 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender,
128 int routing_id, 145 int routing_id,
129 const ExtensionHostMsg_Request_Params& params) { 146 const ExtensionHostMsg_Request_Params& params) {
130 const Extension* extension = 147 const Extension* extension =
131 extension_info_map->extensions().GetByID(params.extension_id); 148 extension_info_map->extensions().GetByID(params.extension_id);
132 149 Profile* profile_cast = static_cast<Profile*>(profile);
133 scoped_refptr<ExtensionFunction> function( 150 scoped_refptr<ExtensionFunction> function(
134 CreateExtensionFunction(params, extension, render_process_id, 151 CreateExtensionFunction(params, extension, render_process_id,
135 extension_info_map->process_map(), 152 extension_info_map->process_map(),
136 g_global_io_data.Get().api.get(), 153 g_global_io_data.Get().api.get(),
137 profile, 154 profile,
138 ipc_sender, NULL, routing_id)); 155 ipc_sender, NULL, routing_id));
156 scoped_ptr<ListValue> args(params.arguments.DeepCopy());
157
139 if (!function) { 158 if (!function) {
140 LogFailure(extension, params.name, kAccessDenied); 159 LogFailure(extension,
160 params.name,
161 args.Pass(),
162 kAccessDenied,
163 profile_cast);
141 return; 164 return;
142 } 165 }
143 166
144 IOThreadExtensionFunction* function_io = 167 IOThreadExtensionFunction* function_io =
145 function->AsIOThreadExtensionFunction(); 168 function->AsIOThreadExtensionFunction();
146 if (!function_io) { 169 if (!function_io) {
147 NOTREACHED(); 170 NOTREACHED();
148 return; 171 return;
149 } 172 }
150 function_io->set_ipc_sender(ipc_sender, routing_id); 173 function_io->set_ipc_sender(ipc_sender, routing_id);
151 function_io->set_extension_info_map(extension_info_map); 174 function_io->set_extension_info_map(extension_info_map);
152 function->set_include_incognito( 175 function->set_include_incognito(
153 extension_info_map->IsIncognitoEnabled(extension->id())); 176 extension_info_map->IsIncognitoEnabled(extension->id()));
154 177
155 if (!CheckPermissions(function, extension, params, ipc_sender, routing_id)) { 178 if (!CheckPermissions(function, extension, params, ipc_sender, routing_id)) {
156 LogFailure(extension, params.name, kAccessDenied); 179 LogFailure(extension,
180 params.name,
181 args.Pass(),
182 kAccessDenied,
183 profile_cast);
157 return; 184 return;
158 } 185 }
159 186
160 ExtensionsQuotaService* quota = extension_info_map->GetQuotaService(); 187 ExtensionsQuotaService* quota = extension_info_map->GetQuotaService();
161 std::string violation_error = quota->Assess(extension->id(), 188 std::string violation_error = quota->Assess(extension->id(),
162 function, 189 function,
163 &params.arguments, 190 &params.arguments,
164 base::TimeTicks::Now()); 191 base::TimeTicks::Now());
165 if (violation_error.empty()) { 192 if (violation_error.empty()) {
193 LogSuccess(extension,
194 params.name,
195 args.Pass(),
196 profile_cast);
166 function->Run(); 197 function->Run();
167 LogSuccess(extension, params);
168 } else { 198 } else {
199 LogFailure(extension,
200 params.name,
201 args.Pass(),
202 kQuotaExceeded,
203 profile_cast);
169 function->OnQuotaExceeded(violation_error); 204 function->OnQuotaExceeded(violation_error);
170 LogFailure(extension, params.name, kQuotaExceeded);
171 } 205 }
172 } 206 }
173 207
174 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile, 208 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile,
175 Delegate* delegate) 209 Delegate* delegate)
176 : profile_(profile), 210 : profile_(profile),
177 delegate_(delegate) { 211 delegate_(delegate) {
178 } 212 }
179 213
180 ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { 214 ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
(...skipping 16 matching lines...) Expand all
197 WebSecurityOrigin::createFromString(params.source_origin), 231 WebSecurityOrigin::createFromString(params.source_origin),
198 params.source_url)); 232 params.source_url));
199 233
200 scoped_refptr<ExtensionFunction> function( 234 scoped_refptr<ExtensionFunction> function(
201 CreateExtensionFunction(params, extension, 235 CreateExtensionFunction(params, extension,
202 render_view_host->GetProcess()->GetID(), 236 render_view_host->GetProcess()->GetID(),
203 *(service->process_map()), 237 *(service->process_map()),
204 extensions::ExtensionAPI::GetSharedInstance(), 238 extensions::ExtensionAPI::GetSharedInstance(),
205 profile(), render_view_host, render_view_host, 239 profile(), render_view_host, render_view_host,
206 render_view_host->GetRoutingID())); 240 render_view_host->GetRoutingID()));
241 scoped_ptr<ListValue> args(params.arguments.DeepCopy());
242
207 if (!function) { 243 if (!function) {
208 LogFailure(extension, params.name, kAccessDenied); 244 LogFailure(extension,
245 params.name,
246 args.Pass(),
247 kAccessDenied,
248 profile());
209 return; 249 return;
210 } 250 }
211 251
212 UIThreadExtensionFunction* function_ui = 252 UIThreadExtensionFunction* function_ui =
213 function->AsUIThreadExtensionFunction(); 253 function->AsUIThreadExtensionFunction();
214 if (!function_ui) { 254 if (!function_ui) {
215 NOTREACHED(); 255 NOTREACHED();
216 return; 256 return;
217 } 257 }
218 function_ui->set_dispatcher(AsWeakPtr()); 258 function_ui->set_dispatcher(AsWeakPtr());
219 function_ui->set_profile(profile_); 259 function_ui->set_profile(profile_);
220 function->set_include_incognito(service->CanCrossIncognito(extension)); 260 function->set_include_incognito(service->CanCrossIncognito(extension));
221 261
222 if (!CheckPermissions(function, extension, params, render_view_host, 262 if (!CheckPermissions(function, extension, params, render_view_host,
223 render_view_host->GetRoutingID())) { 263 render_view_host->GetRoutingID())) {
224 LogFailure(extension, params.name, kAccessDenied); 264 LogFailure(extension,
265 params.name,
266 args.Pass(),
267 kAccessDenied,
268 profile());
225 return; 269 return;
226 } 270 }
227 271
228 ExtensionsQuotaService* quota = service->quota_service(); 272 ExtensionsQuotaService* quota = service->quota_service();
229 std::string violation_error = quota->Assess(extension->id(), 273 std::string violation_error = quota->Assess(extension->id(),
230 function, 274 function,
231 &params.arguments, 275 &params.arguments,
232 base::TimeTicks::Now()); 276 base::TimeTicks::Now());
233 if (violation_error.empty()) { 277 if (violation_error.empty()) {
234 // See crbug.com/39178. 278 // See crbug.com/39178.
235 ExternalProtocolHandler::PermitLaunchUrl(); 279 ExternalProtocolHandler::PermitLaunchUrl();
236 280 LogSuccess(extension, params.name, args.Pass(), profile());
237 function->Run(); 281 function->Run();
238 LogSuccess(extension, params);
239 } else { 282 } else {
283 LogFailure(extension,
284 params.name,
285 args.Pass(),
286 kQuotaExceeded,
287 profile());
240 function->OnQuotaExceeded(violation_error); 288 function->OnQuotaExceeded(violation_error);
241 LogFailure(extension, params.name, kQuotaExceeded);
242 } 289 }
243 290
244 // Note: do not access |this| after this point. We may have been deleted 291 // Note: do not access |this| after this point. We may have been deleted
245 // if function->Run() ended up closing the tab that owns us. 292 // if function->Run() ended up closing the tab that owns us.
246 293
247 // Check if extension was uninstalled by management.uninstall. 294 // Check if extension was uninstalled by management.uninstall.
248 if (!service->extensions()->GetByID(params.extension_id)) 295 if (!service->extensions()->GetByID(params.extension_id))
249 return; 296 return;
250 297
251 // We only adjust the keepalive count for UIThreadExtensionFunction for 298 // We only adjust the keepalive count for UIThreadExtensionFunction for
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 370 }
324 371
325 // static 372 // static
326 void ExtensionFunctionDispatcher::SendAccessDenied( 373 void ExtensionFunctionDispatcher::SendAccessDenied(
327 IPC::Sender* ipc_sender, int routing_id, int request_id) { 374 IPC::Sender* ipc_sender, int routing_id, int request_id) {
328 ListValue empty_list; 375 ListValue empty_list;
329 ipc_sender->Send(new ExtensionMsg_Response( 376 ipc_sender->Send(new ExtensionMsg_Response(
330 routing_id, request_id, false, empty_list, 377 routing_id, request_id, false, empty_list,
331 "Access to extension API denied.")); 378 "Access to extension API denied."));
332 } 379 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/blocked_actions.cc ('k') | chrome/browser/extensions/tab_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698