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

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

Issue 12262025: Alter the ActivityLog db table schemas. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/activity_log.h" 5 #include "chrome/browser/extensions/activity_log.h"
6 6
7 #include <set> 7 #include <set>
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/json/json_string_value_serializer.h" 9 #include "base/json/json_string_value_serializer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/threading/thread_checker.h" 12 #include "base/threading/thread_checker.h"
13 #include "chrome/browser/extensions/api_actions.h" 13 #include "chrome/browser/extensions/api_actions.h"
14 #include "chrome/browser/extensions/blocked_actions.h" 14 #include "chrome/browser/extensions/blocked_actions.h"
15 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/extensions/extension_system.h" 16 #include "chrome/browser/extensions/extension_system.h"
17 #include "chrome/common/chrome_constants.h" 17 #include "chrome/common/chrome_constants.h"
18 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension.h"
20 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
21 #include "googleurl/src/gurl.h" 21 #include "googleurl/src/gurl.h"
22 #include "sql/error_delegate_util.h" 22 #include "sql/error_delegate_util.h"
23 #include "third_party/re2/re2/re2.h" 23 #include "third_party/re2/re2/re2.h"
24 24
25 namespace { 25 namespace {
26 26
27 // Concatenate an API call with its arguments. 27 // Concatenate arguments.
28 std::string MakeCallSignature(const std::string& name, const ListValue* args) { 28 std::string MakeArgList(const ListValue* args) {
29 std::string call_signature = name + "("; 29 std::string call_signature = "";
30 ListValue::const_iterator it = args->begin(); 30 ListValue::const_iterator it = args->begin();
31 for (; it != args->end(); ++it) { 31 for (; it != args->end(); ++it) {
32 std::string arg; 32 std::string arg;
33 JSONStringValueSerializer serializer(&arg); 33 JSONStringValueSerializer serializer(&arg);
34 if (serializer.SerializeAndOmitBinaryValues(**it)) { 34 if (serializer.SerializeAndOmitBinaryValues(**it)) {
35 if (it != args->begin()) 35 if (it != args->begin())
36 call_signature += ", "; 36 call_signature += ", ";
37 call_signature += arg; 37 call_signature += arg;
38 } 38 }
39 } 39 }
40 return call_signature;
41 }
42
43 // Concatenate an API call with its arguments.
44 std::string MakeCallSignature(const std::string& name, const ListValue* args) {
45 std::string call_signature = name + "(";
46 call_signature += MakeArgList(args);
40 call_signature += ")"; 47 call_signature += ")";
41 return call_signature; 48 return call_signature;
42 } 49 }
43 50
44 // Computes whether the activity log is enabled in this browser (controlled by 51 // Computes whether the activity log is enabled in this browser (controlled by
45 // command-line flags) and caches the value (which is assumed never to change). 52 // command-line flags) and caches the value (which is assumed never to change).
46 class LogIsEnabled { 53 class LogIsEnabled {
47 public: 54 public:
48 LogIsEnabled() { 55 LogIsEnabled() {
49 ComputeIsEnabled(); 56 ComputeIsEnabled();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 167 }
161 168
162 // static 169 // static
163 ActivityLog* ActivityLog::GetInstance(Profile* profile) { 170 ActivityLog* ActivityLog::GetInstance(Profile* profile) {
164 return ActivityLogFactory::GetForProfile(profile); 171 return ActivityLogFactory::GetForProfile(profile);
165 } 172 }
166 173
167 void ActivityLog::AddObserver(const Extension* extension, 174 void ActivityLog::AddObserver(const Extension* extension,
168 ActivityLog::Observer* observer) { 175 ActivityLog::Observer* observer) {
169 if (!IsLogEnabled()) return; 176 if (!IsLogEnabled()) return;
170 if (observers_.count(extension) == 0) { 177 if (observers_.count(extension) == 0)
171 observers_[extension] = new ObserverListThreadSafe<Observer>; 178 observers_[extension] = new ObserverListThreadSafe<Observer>;
172 }
173 observers_[extension]->AddObserver(observer); 179 observers_[extension]->AddObserver(observer);
174 } 180 }
175 181
176 void ActivityLog::RemoveObserver(const Extension* extension, 182 void ActivityLog::RemoveObserver(const Extension* extension,
177 ActivityLog::Observer* observer) { 183 ActivityLog::Observer* observer) {
178 if (observers_.count(extension) == 1) { 184 if (observers_.count(extension) == 1)
179 observers_[extension]->RemoveObserver(observer); 185 observers_[extension]->RemoveObserver(observer);
180 }
181 } 186 }
182 187
183 void ActivityLog::LogAPIAction(const Extension* extension, 188 void ActivityLog::LogAPIActionInternal(const Extension* extension,
184 const std::string& name, 189 const std::string& api_call,
185 const ListValue* args, 190 const ListValue* args,
186 const std::string& extra) { 191 const std::string& extra,
187 if (!IsLogEnabled()) return; 192 const APIAction::Type type) {
188 std::string verb, manager; 193 std::string verb, manager;
189 bool matches = RE2::FullMatch(name, "(.*?)\\.(.*)", &manager, &verb); 194 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb);
190 if (matches) { 195 if (matches) {
191 std::string call_signature = MakeCallSignature(name, args);
192 scoped_refptr<APIAction> action = new APIAction( 196 scoped_refptr<APIAction> action = new APIAction(
193 extension->id(), 197 extension->id(),
194 base::Time::Now(), 198 base::Time::Now(),
195 APIAction::CALL, 199 type,
196 APIAction::StringAsVerb(verb), 200 APIAction::StringAsVerb(verb),
197 APIAction::StringAsTarget(manager), 201 APIAction::StringAsTarget(manager),
198 call_signature, 202 api_call,
203 MakeArgList(args),
199 extra); 204 extra);
200 ScheduleAndForget(&ActivityDatabase::RecordAction, action); 205 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
201 206
202 // Display the action. 207 // Display the action.
203 ObserverMap::const_iterator iter = observers_.find(extension); 208 ObserverMap::const_iterator iter = observers_.find(extension);
204 if (iter != observers_.end()) { 209 if (iter != observers_.end()) {
205 iter->second->Notify(&Observer::OnExtensionActivity, 210 if (type == APIAction::CALL) {
206 extension, 211 iter->second->Notify(&Observer::OnExtensionActivity,
207 ActivityLog::ACTIVITY_EXTENSION_API_CALL, 212 extension,
208 call_signature); 213 ActivityLog::ACTIVITY_EXTENSION_API_CALL,
209 } 214 MakeCallSignature(api_call, args));
210 if (log_activity_to_stdout_) { 215 } else if (type == APIAction::EVENT_CALLBACK) {
211 LOG(INFO) << action->PrettyPrintForDebug(); 216 iter->second->Notify(&Observer::OnExtensionActivity,
212 } 217 extension,
213 } else { 218 ActivityLog::ACTIVITY_EVENT_DISPATCH,
214 LOG(ERROR) << "Unknown API call! " << name; 219 MakeCallSignature(api_call, args));
215 } 220 }
216 }
217
218 void ActivityLog::LogEventAction(const Extension* extension,
219 const std::string& name,
220 const ListValue* args,
221 const std::string& extra) {
222 std::string verb, manager;
223 bool matches = RE2::FullMatch(name, "(.*?)\\.(.*)", &manager, &verb);
224 if (matches) {
225 std::string call_signature = MakeCallSignature(name, args);
226 scoped_refptr<APIAction> action = new APIAction(
227 extension->id(),
228 base::Time::Now(),
229 APIAction::EVENT_CALLBACK,
230 APIAction::StringAsVerb(verb),
231 APIAction::StringAsTarget(manager),
232 call_signature,
233 extra);
234 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
235
236 // Display the action.
237 ObserverMap::const_iterator iter = observers_.find(extension);
238 if (iter != observers_.end()) {
239 iter->second->Notify(&Observer::OnExtensionActivity,
240 extension,
241 ActivityLog::ACTIVITY_EVENT_DISPATCH,
242 call_signature);
243 } 221 }
244 if (log_activity_to_stdout_) 222 if (log_activity_to_stdout_)
245 LOG(INFO) << action->PrettyPrintForDebug(); 223 LOG(INFO) << action->PrettyPrintForDebug();
246 } else { 224 } else {
247 LOG(ERROR) << "Unknown event type! " << name; 225 LOG(ERROR) << "Unknown API call! " << api_call;
248 } 226 }
249 } 227 }
250 228
229 // A wrapper around LogAPIActionInternal, but we know it's an API call.
230 void ActivityLog::LogAPIAction(const Extension* extension,
231 const std::string& api_call,
232 const ListValue* args,
233 const std::string& extra) {
234 if (!IsLogEnabled()) return;
235 LogAPIActionInternal(extension, api_call, args, extra, APIAction::CALL);
236 }
237
238 // A wrapper around LogAPIActionInternal, but we know it's actually an event
239 // being fired and triggering extension code. Having the two separate methods
240 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to
241 // handle them. Right now they're being handled almost the same.
242 void ActivityLog::LogEventAction(const Extension* extension,
243 const std::string& api_call,
244 const ListValue* args,
245 const std::string& extra) {
246 if (!IsLogEnabled()) return;
247 LogAPIActionInternal(extension,
248 api_call,
249 args,
250 extra,
251 APIAction::EVENT_CALLBACK);
252 }
253
251 void ActivityLog::LogBlockedAction(const Extension* extension, 254 void ActivityLog::LogBlockedAction(const Extension* extension,
252 const std::string& blocked_name, 255 const std::string& blocked_call,
253 const ListValue* args, 256 const ListValue* args,
254 const char* reason, 257 const char* reason,
255 const std::string& extra) { 258 const std::string& extra) {
256 if (!IsLogEnabled()) return; 259 if (!IsLogEnabled()) return;
257 std::string blocked_call = MakeCallSignature(blocked_name, args);
258 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), 260 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(),
259 base::Time::Now(), 261 base::Time::Now(),
260 blocked_call, 262 blocked_call,
263 MakeArgList(args),
261 std::string(reason), 264 std::string(reason),
262 extra); 265 extra);
263 ScheduleAndForget(&ActivityDatabase::RecordAction, action); 266 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
264 // Display the action. 267 // Display the action.
265 ObserverMap::const_iterator iter = observers_.find(extension); 268 ObserverMap::const_iterator iter = observers_.find(extension);
266 if (iter != observers_.end()) { 269 if (iter != observers_.end()) {
270 std::string blocked_str = MakeCallSignature(blocked_call, args);
267 iter->second->Notify(&Observer::OnExtensionActivity, 271 iter->second->Notify(&Observer::OnExtensionActivity,
268 extension, 272 extension,
269 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, 273 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK,
270 blocked_call); 274 blocked_str);
271 } 275 }
272 if (log_activity_to_stdout_) 276 if (log_activity_to_stdout_)
273 LOG(INFO) << action->PrettyPrintForDebug(); 277 LOG(INFO) << action->PrettyPrintForDebug();
274 } 278 }
275 279
276 void ActivityLog::LogUrlAction(const Extension* extension, 280 void ActivityLog::LogDOMActionInternal(const Extension* extension,
277 const UrlAction::UrlActionType verb, 281 const GURL& url,
278 const GURL& url, 282 const string16& url_title,
279 const string16& url_title, 283 const std::string& api_call,
280 const std::string& technical_message, 284 const ListValue* args,
281 const std::string& extra) { 285 const std::string& extra,
282 if (!IsLogEnabled()) return; 286 DOMAction::DOMActionType verb) {
283 scoped_refptr<UrlAction> action = new UrlAction( 287 scoped_refptr<DOMAction> action = new DOMAction(
284 extension->id(), 288 extension->id(),
285 base::Time::Now(), 289 base::Time::Now(),
286 verb, 290 verb,
287 url, 291 url,
288 url_title, 292 url_title,
289 technical_message, 293 api_call,
290 extra); 294 MakeArgList(args),
295 extra);
291 ScheduleAndForget(&ActivityDatabase::RecordAction, action); 296 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
292 297
293 // Display the action. 298 // Display the action.
294 ObserverMap::const_iterator iter = observers_.find(extension); 299 ObserverMap::const_iterator iter = observers_.find(extension);
295 if (iter != observers_.end()) { 300 if (iter != observers_.end()) {
296 iter->second->Notify(&Observer::OnExtensionActivity, 301 // TODO(felt): This is a kludge, planning to update this when new
297 extension, 302 // UI is in place.
298 ActivityLog::ACTIVITY_CONTENT_SCRIPT, 303 if (verb == DOMAction::INSERTED) {
299 action->PrettyPrintForDebug()); 304 iter->second->Notify(&Observer::OnExtensionActivity,
305 extension,
306 ActivityLog::ACTIVITY_CONTENT_SCRIPT,
307 action->PrettyPrintForDebug());
308 } else {
309 iter->second->Notify(&Observer::OnExtensionActivity,
310 extension,
311 ActivityLog::ACTIVITY_CONTENT_SCRIPT,
312 MakeCallSignature(api_call, args));
313 }
300 } 314 }
301 if (log_activity_to_stdout_) 315 if (log_activity_to_stdout_)
302 LOG(INFO) << action->PrettyPrintForDebug(); 316 LOG(INFO) << action->PrettyPrintForDebug();
303 } 317 }
304 318
319 void ActivityLog::LogDOMAction(const Extension* extension,
320 const GURL& url,
321 const string16& url_title,
322 const std::string& api_call,
323 const ListValue* args,
324 const std::string& extra) {
325 if (!IsLogEnabled()) return;
326 LogDOMActionInternal(extension,
327 url,
328 url_title,
329 api_call,
330 args,
331 extra,
332 DOMAction::MODIFIED);
333 }
334
305 void ActivityLog::OnScriptsExecuted( 335 void ActivityLog::OnScriptsExecuted(
306 const content::WebContents* web_contents, 336 const content::WebContents* web_contents,
307 const ExecutingScriptsMap& extension_ids, 337 const ExecutingScriptsMap& extension_ids,
308 int32 on_page_id, 338 int32 on_page_id,
309 const GURL& on_url) { 339 const GURL& on_url) {
310 if (!IsLogEnabled()) return; 340 if (!IsLogEnabled()) return;
311 Profile* profile = 341 Profile* profile =
312 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 342 Profile::FromBrowserContext(web_contents->GetBrowserContext());
313 const ExtensionService* extension_service = 343 const ExtensionService* extension_service =
314 ExtensionSystem::Get(profile)->extension_service(); 344 ExtensionSystem::Get(profile)->extension_service();
315 const ExtensionSet* extensions = extension_service->extensions(); 345 const ExtensionSet* extensions = extension_service->extensions();
316 346
317 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); 347 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin();
318 it != extension_ids.end(); ++it) { 348 it != extension_ids.end(); ++it) {
319 const Extension* extension = extensions->GetByID(it->first); 349 const Extension* extension = extensions->GetByID(it->first);
320 if (!extension) 350 if (!extension)
321 continue; 351 continue;
322 352
323 // If OnScriptsExecuted is fired because of tabs.executeScript, the list 353 // If OnScriptsExecuted is fired because of tabs.executeScript, the list
324 // of content scripts will be empty. We don't want to log it because 354 // of content scripts will be empty. We don't want to log it because
325 // the call to tabs.executeScript will have already been logged anyway. 355 // the call to tabs.executeScript will have already been logged anyway.
326 if (!it->second.empty()) { 356 if (!it->second.empty()) {
327 std::string ext_scripts_str = ""; 357 std::string ext_scripts_str = "";
328 for (std::set<std::string>::const_iterator it2 = it->second.begin(); 358 for (std::set<std::string>::const_iterator it2 = it->second.begin();
329 it2 != it->second.end(); ++it2) { 359 it2 != it->second.end(); ++it2) {
330 ext_scripts_str += *it2; 360 ext_scripts_str += *it2;
331 ext_scripts_str += " "; 361 ext_scripts_str += " ";
332 } 362 }
333 LogUrlAction(extension, 363 scoped_ptr<ListValue> script_names(new ListValue());
334 UrlAction::INSERTED, 364 script_names->Set(0, new StringValue(ext_scripts_str));
335 on_url, 365 LogDOMActionInternal(extension,
336 web_contents->GetTitle(), 366 on_url,
337 ext_scripts_str, 367 web_contents->GetTitle(),
338 ""); 368 "", // no api call here
369 script_names.get(),
370 "", // no extras either
371 DOMAction::INSERTED);
339 } 372 }
340 } 373 }
341 } 374 }
342 375
343 void ActivityLog::KillActivityLogDatabase() { 376 void ActivityLog::KillActivityLogDatabase() {
344 if (db_.get()) { 377 if (db_.get()) {
345 ScheduleAndForget(&ActivityDatabase::KillDatabase); 378 ScheduleAndForget(&ActivityDatabase::KillDatabase);
346 } 379 }
347 } 380 }
348 381
349 // static 382 // static
350 const char* ActivityLog::ActivityToString(Activity activity) { 383 const char* ActivityLog::ActivityToString(Activity activity) {
351 switch (activity) { 384 switch (activity) {
352 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: 385 case ActivityLog::ACTIVITY_EXTENSION_API_CALL:
353 return "api_call"; 386 return "api_call";
354 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: 387 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK:
355 return "api_block"; 388 return "api_block";
356 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: 389 case ActivityLog::ACTIVITY_CONTENT_SCRIPT:
357 return "content_script"; 390 return "content_script";
358 case ActivityLog::ACTIVITY_EVENT_DISPATCH: 391 case ActivityLog::ACTIVITY_EVENT_DISPATCH:
359 return "event_dispatch"; 392 return "event_dispatch";
360 default: 393 default:
361 NOTREACHED(); 394 NOTREACHED();
362 return ""; 395 return "";
363 } 396 }
364 } 397 }
365 398
366 } // namespace extensions 399 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/activity_log.h ('k') | chrome/browser/extensions/activity_log_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698