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

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

Issue 2077723002: [Extensions] Short-circuit activity logging if not enabled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add Test Created 4 years, 6 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
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/activity_log.h" 5 #include "chrome/browser/extensions/activity_log/activity_log.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/json/json_string_value_serializer.h" 13 #include "base/json/json_string_value_serializer.h"
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "base/synchronization/lock.h"
19 #include "base/threading/thread_checker.h" 20 #include "base/threading/thread_checker.h"
21 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/extensions/activity_log/activity_action_constants.h" 22 #include "chrome/browser/extensions/activity_log/activity_action_constants.h"
21 #include "chrome/browser/extensions/activity_log/counting_policy.h" 23 #include "chrome/browser/extensions/activity_log/counting_policy.h"
22 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" 24 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
23 #include "chrome/browser/extensions/api/activity_log_private/activity_log_privat e_api.h" 25 #include "chrome/browser/extensions/api/activity_log_private/activity_log_privat e_api.h"
24 #include "chrome/browser/extensions/extension_tab_util.h" 26 #include "chrome/browser/extensions/extension_tab_util.h"
25 #include "chrome/browser/prerender/prerender_manager.h" 27 #include "chrome/browser/prerender/prerender_manager.h"
26 #include "chrome/browser/prerender/prerender_manager_factory.h" 28 #include "chrome/browser/prerender/prerender_manager_factory.h"
27 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ui/browser.h" 30 #include "chrome/browser/ui/browser.h"
29 #include "chrome/common/chrome_constants.h" 31 #include "chrome/common/chrome_constants.h"
30 #include "chrome/common/chrome_switches.h" 32 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
32 #include "components/syncable_prefs/pref_service_syncable.h" 34 #include "components/syncable_prefs/pref_service_syncable.h"
33 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/notification_source.h"
34 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents.h"
39 #include "extensions/browser/api_activity_monitor.h"
35 #include "extensions/browser/extension_registry.h" 40 #include "extensions/browser/extension_registry.h"
36 #include "extensions/browser/extension_registry_factory.h" 41 #include "extensions/browser/extension_registry_factory.h"
37 #include "extensions/browser/extension_system.h" 42 #include "extensions/browser/extension_system.h"
38 #include "extensions/browser/extension_system_provider.h" 43 #include "extensions/browser/extension_system_provider.h"
39 #include "extensions/browser/extensions_browser_client.h" 44 #include "extensions/browser/extensions_browser_client.h"
40 #include "extensions/common/extension.h" 45 #include "extensions/common/extension.h"
41 #include "extensions/common/one_shot_event.h" 46 #include "extensions/common/one_shot_event.h"
42 #include "third_party/re2/src/re2/re2.h" 47 #include "third_party/re2/src/re2/re2.h"
43 #include "url/gurl.h" 48 #include "url/gurl.h"
44 49
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 default: 331 default:
327 NOTREACHED(); 332 NOTREACHED();
328 } 333 }
329 334
330 if (arg_url.is_valid()) { 335 if (arg_url.is_valid()) {
331 action->set_arg_incognito(arg_incognito); 336 action->set_arg_incognito(arg_incognito);
332 action->set_arg_url(arg_url); 337 action->set_arg_url(arg_url);
333 } 338 }
334 } 339 }
335 340
341 // A global, thread-safe record of activity log state.
342 class ActivityLogState {
343 public:
344 ActivityLogState() {}
345 ~ActivityLogState() {}
346
347 void AddActiveContext(content::BrowserContext* context) {
348 DCHECK_CURRENTLY_ON(BrowserThread::UI);
349 base::AutoLock lock(lock_);
350 contexts_.insert(context);
351 }
352
353 void RemoveActiveContext(content::BrowserContext* context) {
354 DCHECK_CURRENTLY_ON(BrowserThread::UI);
355 base::AutoLock lock(lock_);
356 contexts_.erase(context);
357 }
358
359 bool IsActiveContext(content::BrowserContext* context) {
360 base::AutoLock lock(lock_);
361 return contexts_.count(context) > 0;
362 }
363
364 void AddWhitelistedId(const std::string& id) {
365 DCHECK_CURRENTLY_ON(BrowserThread::UI);
366 base::AutoLock lock(lock_);
367 whitelisted_ids_.insert(id);
368 }
369
370 // We don't remove the id entry from g_activity_log_state because it may be
371 // loaded in multiple profiles, and being whitelisted for the ActivityLog
372 // is a global permission.
373
374 bool IsWhitelistedId(const std::string& id) {
375 base::AutoLock lock(lock_);
376 return whitelisted_ids_.count(id) > 0;
377 }
378
379 private:
380 std::set<const content::BrowserContext*> contexts_;
381 std::set<std::string> whitelisted_ids_;
382 base::Lock lock_;
383
384 DISALLOW_COPY_AND_ASSIGN(ActivityLogState);
385 };
386
387 base::LazyInstance<ActivityLogState> g_activity_log_state =
388 LAZY_INSTANCE_INITIALIZER;
389
390 // Calls into the ActivityLog to log an api event or function call.
391 // Must be called on the UI thread.
392 void LogApiActivityOnUI(content::BrowserContext* browser_context,
393 const std::string& extension_id,
394 const std::string& activity_name,
395 std::unique_ptr<base::ListValue> args,
396 Action::ActionType type) {
397 DCHECK_CURRENTLY_ON(BrowserThread::UI);
398 ActivityLog* activity_log = ActivityLog::GetInstance(browser_context);
399 if (!activity_log || !activity_log->ShouldLog(extension_id))
400 return;
401 scoped_refptr<Action> action =
402 new Action(extension_id, base::Time::Now(), type, activity_name);
403 action->set_args(std::move(args));
404 activity_log->LogAction(action);
405 }
406
407 // Generic thread-safe handler for API calls and events.
408 void LogApiActivity(content::BrowserContext* browser_context,
409 const std::string& extension_id,
410 const std::string& activity_name,
411 const base::ListValue& args,
412 Action::ActionType type) {
413 ActivityLogState& state = g_activity_log_state.Get();
414 if (!state.IsActiveContext(browser_context) ||
415 state.IsWhitelistedId(extension_id))
416 return;
417 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
418 BrowserThread::PostTask(
419 BrowserThread::UI, FROM_HERE,
420 base::Bind(&LogApiActivityOnUI, browser_context, extension_id,
421 activity_name, base::Passed(args.CreateDeepCopy()), type));
422 return;
423 }
424 LogApiActivityOnUI(browser_context, extension_id, activity_name,
425 args.CreateDeepCopy(), type);
426 }
427
428 // Handler for API events. Thread-safe.
429 void LogApiEvent(content::BrowserContext* browser_context,
430 const std::string& extension_id,
431 const std::string& event_name,
432 const base::ListValue& args) {
433 LogApiActivity(browser_context, extension_id, event_name, args,
434 Action::ACTION_API_EVENT);
435 }
436
437 // Handler for API function calls. Thread-safe.
438 void LogApiFunction(content::BrowserContext* browser_context,
439 const std::string& extension_id,
440 const std::string& event_name,
441 const base::ListValue& args) {
442 LogApiActivity(browser_context, extension_id, event_name, args,
443 Action::ACTION_API_CALL);
444 }
445
446 // Calls into the ActivityLog to log a webRequest usage.
447 // Must be called on the UI thread.
448 void LogWebRequestActivityOnUI(content::BrowserContext* browser_context,
449 const std::string& extension_id,
450 const GURL& url,
451 bool is_incognito,
452 const std::string& api_call,
453 std::unique_ptr<base::DictionaryValue> details) {
454 DCHECK_CURRENTLY_ON(BrowserThread::UI);
455 ActivityLog* activity_log = ActivityLog::GetInstance(browser_context);
456 if (!activity_log || !activity_log->ShouldLog(extension_id))
457 return;
458 scoped_refptr<Action> action = new Action(
459 extension_id, base::Time::Now(), Action::ACTION_WEB_REQUEST, api_call);
460 action->set_page_url(url);
461 action->set_page_incognito(is_incognito);
462 action->mutable_other()->Set(activity_log_constants::kActionWebRequest,
463 std::move(details));
464 activity_log->LogAction(action);
465 }
466
467 // Handler for webRequest use. Thread-safe.
468 void LogWebRequestActivity(content::BrowserContext* browser_context,
469 const std::string& extension_id,
470 const GURL& url,
471 bool is_incognito,
472 const std::string& api_call,
473 std::unique_ptr<base::DictionaryValue> details) {
474 ActivityLogState& state = g_activity_log_state.Get();
475 if (!state.IsActiveContext(browser_context) ||
476 state.IsWhitelistedId(extension_id))
477 return;
478 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
479 BrowserThread::PostTask(
480 BrowserThread::UI, FROM_HERE,
481 base::Bind(&LogWebRequestActivityOnUI, browser_context, extension_id,
482 url, is_incognito, api_call, base::Passed(&details)));
483 return;
484 }
485 LogWebRequestActivityOnUI(browser_context, extension_id, url, is_incognito,
486 api_call, std::move(details));
487 }
488
489 void SetActivityHandlers() {
490 // Set up event handlers. We don't have to worry about unsetting these,
491 // because we check whether or not the activity log is active for the context
492 // in the monitor methods.
493 activity_monitor::Monitor current_function_monitor =
494 activity_monitor::GetApiFunctionMonitor();
495 DCHECK(!current_function_monitor ||
496 current_function_monitor == &LogApiFunction);
497 if (!current_function_monitor)
498 activity_monitor::SetApiFunctionMonitor(&LogApiFunction);
499
500 activity_monitor::Monitor current_event_monitor =
501 activity_monitor::GetApiEventMonitor();
502 DCHECK(!current_event_monitor || current_event_monitor == &LogApiEvent);
503 if (!current_function_monitor)
504 activity_monitor::SetApiEventMonitor(&LogApiEvent);
505
506 activity_monitor::WebRequestMonitor current_web_request_monitor =
507 activity_monitor::GetWebRequestMonitor();
508 DCHECK(!current_web_request_monitor ||
509 current_web_request_monitor == &LogWebRequestActivity);
510 if (!current_web_request_monitor)
511 activity_monitor::SetWebRequestMonitor(&LogWebRequestActivity);
512 }
513
336 } // namespace 514 } // namespace
337 515
338 // SET THINGS UP. -------------------------------------------------------------- 516 // SET THINGS UP. --------------------------------------------------------------
339 517
340 static base::LazyInstance<BrowserContextKeyedAPIFactory<ActivityLog> > 518 static base::LazyInstance<BrowserContextKeyedAPIFactory<ActivityLog> >
341 g_factory = LAZY_INSTANCE_INITIALIZER; 519 g_factory = LAZY_INSTANCE_INITIALIZER;
342 520
343 BrowserContextKeyedAPIFactory<ActivityLog>* ActivityLog::GetFactoryInstance() { 521 BrowserContextKeyedAPIFactory<ActivityLog>* ActivityLog::GetFactoryInstance() {
344 return g_factory.Pointer(); 522 return g_factory.Pointer();
345 } 523 }
346 524
347 // static 525 // static
348 ActivityLog* ActivityLog::GetInstance(content::BrowserContext* context) { 526 ActivityLog* ActivityLog::GetInstance(content::BrowserContext* context) {
349 return ActivityLog::GetFactoryInstance()->Get( 527 return ActivityLog::GetFactoryInstance()->Get(
350 Profile::FromBrowserContext(context)); 528 Profile::FromBrowserContext(context));
351 } 529 }
352 530
353 // Use GetInstance instead of directly creating an ActivityLog. 531 // Use GetInstance instead of directly creating an ActivityLog.
354 ActivityLog::ActivityLog(content::BrowserContext* context) 532 ActivityLog::ActivityLog(content::BrowserContext* context)
355 : database_policy_(NULL), 533 : database_policy_(NULL),
356 database_policy_type_(ActivityLogPolicy::POLICY_INVALID), 534 database_policy_type_(ActivityLogPolicy::POLICY_INVALID),
357 profile_(Profile::FromBrowserContext(context)), 535 profile_(Profile::FromBrowserContext(context)),
358 db_enabled_(false), 536 db_enabled_(false),
359 testing_mode_(false), 537 testing_mode_(false),
360 has_threads_(true), 538 has_threads_(true),
361 extension_registry_observer_(this), 539 extension_registry_observer_(this),
362 watchdog_apps_active_(0) { 540 watchdog_apps_active_(0),
541 is_active_(false) {
542 SetActivityHandlers();
543
363 // This controls whether logging statements are printed & which policy is set. 544 // This controls whether logging statements are printed & which policy is set.
364 testing_mode_ = base::CommandLine::ForCurrentProcess()->HasSwitch( 545 testing_mode_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
365 switches::kEnableExtensionActivityLogTesting); 546 switches::kEnableExtensionActivityLogTesting);
366 547
367 // Check if the watchdog extension is previously installed and active. 548 // Check if the watchdog extension is previously installed and active.
368 watchdog_apps_active_ = 549 watchdog_apps_active_ =
369 profile_->GetPrefs()->GetInteger(prefs::kWatchdogExtensionActive); 550 profile_->GetPrefs()->GetInteger(prefs::kWatchdogExtensionActive);
370 551
371 observers_ = new base::ObserverListThreadSafe<Observer>; 552 observers_ = new base::ObserverListThreadSafe<Observer>;
372 553
373 // Check that the right threads exist for logging to the database. 554 // Check that the right threads exist for logging to the database.
374 // If not, we shouldn't try to do things that require them. 555 // If not, we shouldn't try to do things that require them.
375 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || 556 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) ||
376 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || 557 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) ||
377 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 558 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
378 has_threads_ = false; 559 has_threads_ = false;
379 } 560 }
380 561
381 db_enabled_ = 562 db_enabled_ =
382 has_threads_ && (base::CommandLine::ForCurrentProcess()->HasSwitch( 563 has_threads_ && (base::CommandLine::ForCurrentProcess()->HasSwitch(
383 switches::kEnableExtensionActivityLogging) || 564 switches::kEnableExtensionActivityLogging) ||
384 watchdog_apps_active_); 565 watchdog_apps_active_);
385 566
386 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); 567 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
387 ChooseDatabasePolicy(); 568 ChooseDatabasePolicy();
569
570 CheckActive();
388 } 571 }
389 572
390 void ActivityLog::SetDatabasePolicy( 573 void ActivityLog::SetDatabasePolicy(
391 ActivityLogPolicy::PolicyType policy_type) { 574 ActivityLogPolicy::PolicyType policy_type) {
392 if (database_policy_type_ == policy_type) 575 if (database_policy_type_ == policy_type)
393 return; 576 return;
394 if (!IsDatabaseEnabled() && !IsWatchdogAppActive()) 577 if (!IsDatabaseEnabled() && !IsWatchdogAppActive())
395 return; 578 return;
396 579
397 // Deleting the old policy takes place asynchronously, on the database 580 // Deleting the old policy takes place asynchronously, on the database
(...skipping 17 matching lines...) Expand all
415 default: 598 default:
416 NOTREACHED(); 599 NOTREACHED();
417 } 600 }
418 database_policy_->Init(); 601 database_policy_->Init();
419 database_policy_type_ = policy_type; 602 database_policy_type_ = policy_type;
420 } 603 }
421 604
422 ActivityLog::~ActivityLog() { 605 ActivityLog::~ActivityLog() {
423 if (database_policy_) 606 if (database_policy_)
424 database_policy_->Close(); 607 database_policy_->Close();
608 if (is_active_)
609 g_activity_log_state.Get().RemoveActiveContext(profile_);
425 } 610 }
426 611
427 // MAINTAIN STATUS. ------------------------------------------------------------ 612 // MAINTAIN STATUS. ------------------------------------------------------------
428 613
429 void ActivityLog::ChooseDatabasePolicy() { 614 void ActivityLog::ChooseDatabasePolicy() {
430 if (!(IsDatabaseEnabled() || IsWatchdogAppActive())) 615 if (!(IsDatabaseEnabled() || IsWatchdogAppActive()))
431 return; 616 return;
432 if (testing_mode_) 617 if (testing_mode_)
433 SetDatabasePolicy(ActivityLogPolicy::POLICY_FULLSTREAM); 618 SetDatabasePolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
434 else 619 else
435 SetDatabasePolicy(ActivityLogPolicy::POLICY_COUNTS); 620 SetDatabasePolicy(ActivityLogPolicy::POLICY_COUNTS);
436 } 621 }
437 622
438 bool ActivityLog::IsDatabaseEnabled() { 623 bool ActivityLog::IsDatabaseEnabled() {
439 // Make sure we are not enabled when there are no threads. 624 // Make sure we are not enabled when there are no threads.
440 DCHECK(has_threads_ || !db_enabled_); 625 DCHECK(has_threads_ || !db_enabled_);
441 return db_enabled_; 626 return db_enabled_;
442 } 627 }
443 628
444 bool ActivityLog::IsWatchdogAppActive() { 629 bool ActivityLog::IsWatchdogAppActive() {
445 return (watchdog_apps_active_ > 0); 630 return (watchdog_apps_active_ > 0);
446 } 631 }
447 632
448 void ActivityLog::SetWatchdogAppActiveForTesting(bool active) { 633 void ActivityLog::SetWatchdogAppActiveForTesting(bool active) {
449 watchdog_apps_active_ = active ? 1 : 0; 634 watchdog_apps_active_ = active ? 1 : 0;
635 CheckActive();
450 } 636 }
451 637
452 void ActivityLog::OnExtensionLoaded(content::BrowserContext* browser_context, 638 void ActivityLog::OnExtensionLoaded(content::BrowserContext* browser_context,
453 const Extension* extension) { 639 const Extension* extension) {
454 if (!ActivityLogAPI::IsExtensionWhitelisted(extension->id())) return; 640 if (!ActivityLogAPI::IsExtensionWhitelisted(extension->id()))
641 return;
455 if (has_threads_) 642 if (has_threads_)
456 db_enabled_ = true; 643 db_enabled_ = true;
644 g_activity_log_state.Get().AddWhitelistedId(extension->id());
457 watchdog_apps_active_++; 645 watchdog_apps_active_++;
458 profile_->GetPrefs()->SetInteger(prefs::kWatchdogExtensionActive, 646 profile_->GetPrefs()->SetInteger(prefs::kWatchdogExtensionActive,
459 watchdog_apps_active_); 647 watchdog_apps_active_);
460 if (watchdog_apps_active_ == 1) 648 if (watchdog_apps_active_ == 1)
461 ChooseDatabasePolicy(); 649 ChooseDatabasePolicy();
650
651 if (!is_active_)
652 CheckActive();
462 } 653 }
463 654
464 void ActivityLog::OnExtensionUnloaded(content::BrowserContext* browser_context, 655 void ActivityLog::OnExtensionUnloaded(content::BrowserContext* browser_context,
465 const Extension* extension, 656 const Extension* extension,
466 UnloadedExtensionInfo::Reason reason) { 657 UnloadedExtensionInfo::Reason reason) {
467 if (!ActivityLogAPI::IsExtensionWhitelisted(extension->id())) return; 658 if (!ActivityLogAPI::IsExtensionWhitelisted(extension->id()))
659 return;
468 watchdog_apps_active_--; 660 watchdog_apps_active_--;
469 profile_->GetPrefs()->SetInteger(prefs::kWatchdogExtensionActive, 661 profile_->GetPrefs()->SetInteger(prefs::kWatchdogExtensionActive,
470 watchdog_apps_active_); 662 watchdog_apps_active_);
471 if (watchdog_apps_active_ == 0 && 663 if (watchdog_apps_active_ == 0 &&
472 !base::CommandLine::ForCurrentProcess()->HasSwitch( 664 !base::CommandLine::ForCurrentProcess()->HasSwitch(
473 switches::kEnableExtensionActivityLogging)) { 665 switches::kEnableExtensionActivityLogging)) {
474 db_enabled_ = false; 666 db_enabled_ = false;
475 } 667 }
668
669 if (is_active_)
670 CheckActive();
476 } 671 }
477 672
478 // OnExtensionUnloaded will also be called right before this. 673 // OnExtensionUnloaded will also be called right before this.
479 void ActivityLog::OnExtensionUninstalled( 674 void ActivityLog::OnExtensionUninstalled(
480 content::BrowserContext* browser_context, 675 content::BrowserContext* browser_context,
481 const Extension* extension, 676 const Extension* extension,
482 extensions::UninstallReason reason) { 677 extensions::UninstallReason reason) {
483 if (ActivityLogAPI::IsExtensionWhitelisted(extension->id()) && 678 if (ActivityLogAPI::IsExtensionWhitelisted(extension->id()) &&
484 !base::CommandLine::ForCurrentProcess()->HasSwitch( 679 !base::CommandLine::ForCurrentProcess()->HasSwitch(
485 switches::kEnableExtensionActivityLogging) && 680 switches::kEnableExtensionActivityLogging) &&
(...skipping 14 matching lines...) Expand all
500 695
501 // static 696 // static
502 void ActivityLog::RegisterProfilePrefs( 697 void ActivityLog::RegisterProfilePrefs(
503 user_prefs::PrefRegistrySyncable* registry) { 698 user_prefs::PrefRegistrySyncable* registry) {
504 registry->RegisterIntegerPref(prefs::kWatchdogExtensionActive, false); 699 registry->RegisterIntegerPref(prefs::kWatchdogExtensionActive, false);
505 } 700 }
506 701
507 // LOG ACTIONS. ---------------------------------------------------------------- 702 // LOG ACTIONS. ----------------------------------------------------------------
508 703
509 void ActivityLog::LogAction(scoped_refptr<Action> action) { 704 void ActivityLog::LogAction(scoped_refptr<Action> action) {
510 if (ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) 705 DCHECK(ShouldLog(action->extension_id()));
511 return;
512 706
513 // Perform some preprocessing of the Action data: convert tab IDs to URLs and 707 // Perform some preprocessing of the Action data: convert tab IDs to URLs and
514 // mask out incognito URLs if appropriate. 708 // mask out incognito URLs if appropriate.
515 ExtractUrls(action, profile_); 709 ExtractUrls(action, profile_);
516 710
517 // Mark DOM XHR requests as such, for easier processing later. 711 // Mark DOM XHR requests as such, for easier processing later.
518 if (action->action_type() == Action::ACTION_DOM_ACCESS && 712 if (action->action_type() == Action::ACTION_DOM_ACCESS &&
519 base::StartsWith(action->api_name(), kDomXhrPrefix, 713 base::StartsWith(action->api_name(), kDomXhrPrefix,
520 base::CompareCase::SENSITIVE) && 714 base::CompareCase::SENSITIVE) &&
521 action->other()) { 715 action->other()) {
522 base::DictionaryValue* other = action->mutable_other(); 716 base::DictionaryValue* other = action->mutable_other();
523 int dom_verb = -1; 717 int dom_verb = -1;
524 if (other->GetInteger(constants::kActionDomVerb, &dom_verb) && 718 if (other->GetInteger(constants::kActionDomVerb, &dom_verb) &&
525 dom_verb == DomActionType::METHOD) { 719 dom_verb == DomActionType::METHOD) {
526 other->SetInteger(constants::kActionDomVerb, DomActionType::XHR); 720 other->SetInteger(constants::kActionDomVerb, DomActionType::XHR);
527 } 721 }
528 } 722 }
529 723
530 if (IsDatabaseEnabled() && database_policy_) 724 if (IsDatabaseEnabled() && database_policy_)
531 database_policy_->ProcessAction(action); 725 database_policy_->ProcessAction(action);
532 if (IsWatchdogAppActive()) 726 if (IsWatchdogAppActive())
533 observers_->Notify(FROM_HERE, &Observer::OnExtensionActivity, action); 727 observers_->Notify(FROM_HERE, &Observer::OnExtensionActivity, action);
534 if (testing_mode_) 728 if (testing_mode_)
535 VLOG(1) << action->PrintForDebug(); 729 VLOG(1) << action->PrintForDebug();
536 } 730 }
537 731
732 bool ActivityLog::ShouldLog(const std::string& extension_id) const {
733 return is_active_ && !ActivityLogAPI::IsExtensionWhitelisted(extension_id);
734 }
735
538 void ActivityLog::OnScriptsExecuted( 736 void ActivityLog::OnScriptsExecuted(
539 const content::WebContents* web_contents, 737 const content::WebContents* web_contents,
540 const ExecutingScriptsMap& extension_ids, 738 const ExecutingScriptsMap& extension_ids,
541 const GURL& on_url) { 739 const GURL& on_url) {
542 Profile* profile = 740 if (!is_active_)
543 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 741 return;
544 ExtensionRegistry* registry = ExtensionRegistry::Get(profile); 742 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
545 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); 743 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin();
546 it != extension_ids.end(); ++it) { 744 it != extension_ids.end(); ++it) {
547 const Extension* extension = 745 const Extension* extension =
548 registry->GetExtensionById(it->first, ExtensionRegistry::ENABLED); 746 registry->GetExtensionById(it->first, ExtensionRegistry::ENABLED);
549 if (!extension || ActivityLogAPI::IsExtensionWhitelisted(extension->id())) 747 if (!extension || ActivityLogAPI::IsExtensionWhitelisted(extension->id()))
550 continue; 748 continue;
551 749
552 // If OnScriptsExecuted is fired because of tabs.executeScript, the list 750 // If OnScriptsExecuted is fired because of tabs.executeScript, the list
553 // of content scripts will be empty. We don't want to log it because 751 // of content scripts will be empty. We don't want to log it because
554 // the call to tabs.executeScript will have already been logged anyway. 752 // the call to tabs.executeScript will have already been logged anyway.
555 if (!it->second.empty()) { 753 if (!it->second.empty()) {
556 scoped_refptr<Action> action; 754 scoped_refptr<Action> action;
557 action = new Action(extension->id(), 755 action = new Action(extension->id(),
558 base::Time::Now(), 756 base::Time::Now(),
559 Action::ACTION_CONTENT_SCRIPT, 757 Action::ACTION_CONTENT_SCRIPT,
560 ""); // no API call here 758 ""); // no API call here
561 action->set_page_url(on_url); 759 action->set_page_url(on_url);
562 action->set_page_title(base::UTF16ToUTF8(web_contents->GetTitle())); 760 action->set_page_title(base::UTF16ToUTF8(web_contents->GetTitle()));
563 action->set_page_incognito( 761 action->set_page_incognito(
564 web_contents->GetBrowserContext()->IsOffTheRecord()); 762 web_contents->GetBrowserContext()->IsOffTheRecord());
565 763
566 const prerender::PrerenderManager* prerender_manager = 764 const prerender::PrerenderManager* prerender_manager =
567 prerender::PrerenderManagerFactory::GetForProfile(profile); 765 prerender::PrerenderManagerFactory::GetForProfile(profile_);
568 if (prerender_manager && 766 if (prerender_manager &&
569 prerender_manager->IsWebContentsPrerendering(web_contents, NULL)) 767 prerender_manager->IsWebContentsPrerendering(web_contents, NULL))
570 action->mutable_other()->SetBoolean(constants::kActionPrerender, true); 768 action->mutable_other()->SetBoolean(constants::kActionPrerender, true);
571 for (std::set<std::string>::const_iterator it2 = it->second.begin(); 769 for (std::set<std::string>::const_iterator it2 = it->second.begin();
572 it2 != it->second.end(); 770 it2 != it->second.end();
573 ++it2) { 771 ++it2) {
574 action->mutable_args()->AppendString(*it2); 772 action->mutable_args()->AppendString(*it2);
575 } 773 }
576 LogAction(action); 774 LogAction(action);
577 } 775 }
578 } 776 }
579 } 777 }
580 778
581 void ActivityLog::OnApiEventDispatched(
582 const std::string& extension_id,
583 const std::string& event_name,
584 std::unique_ptr<base::ListValue> event_args) {
585 DCHECK_CURRENTLY_ON(BrowserThread::UI);
586 scoped_refptr<Action> action = new Action(extension_id,
587 base::Time::Now(),
588 Action::ACTION_API_EVENT,
589 event_name);
590 action->set_args(std::move(event_args));
591 LogAction(action);
592 }
593
594 void ActivityLog::OnApiFunctionCalled(const std::string& extension_id,
595 const std::string& api_name,
596 std::unique_ptr<base::ListValue> args) {
597 DCHECK_CURRENTLY_ON(BrowserThread::UI);
598 scoped_refptr<Action> action = new Action(extension_id,
599 base::Time::Now(),
600 Action::ACTION_API_CALL,
601 api_name);
602 action->set_args(std::move(args));
603 LogAction(action);
604 }
605
606 // LOOKUP ACTIONS. ------------------------------------------------------------- 779 // LOOKUP ACTIONS. -------------------------------------------------------------
607 780
608 void ActivityLog::GetFilteredActions( 781 void ActivityLog::GetFilteredActions(
609 const std::string& extension_id, 782 const std::string& extension_id,
610 const Action::ActionType type, 783 const Action::ActionType type,
611 const std::string& api_name, 784 const std::string& api_name,
612 const std::string& page_url, 785 const std::string& page_url,
613 const std::string& arg_url, 786 const std::string& arg_url,
614 const int daysAgo, 787 const int daysAgo,
615 const base::Callback< 788 const base::Callback<
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 urls.push_back(url); 826 urls.push_back(url);
654 RemoveURLs(urls); 827 RemoveURLs(urls);
655 } 828 }
656 829
657 void ActivityLog::DeleteDatabase() { 830 void ActivityLog::DeleteDatabase() {
658 if (!database_policy_) 831 if (!database_policy_)
659 return; 832 return;
660 database_policy_->DeleteDatabase(); 833 database_policy_->DeleteDatabase();
661 } 834 }
662 835
836 void ActivityLog::CheckActive() {
837 bool has_db = db_enabled_ && database_policy_;
838 ActivityLogState& state = g_activity_log_state.Get();
839 content::BrowserContext* off_the_record =
840 profile_->HasOffTheRecordProfile() ? profile_->GetOffTheRecordProfile()
841 : nullptr;
842 if (has_db || IsWatchdogAppActive()) {
843 if (is_active_)
844 return; // Already enabled.
845 state.AddActiveContext(profile_);
846 if (off_the_record)
847 state.AddActiveContext(off_the_record);
848 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
849 content::NotificationService::AllSources());
850 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
851 content::NotificationService::AllSources());
852 is_active_ = true;
853 } else if (is_active_) {
854 state.RemoveActiveContext(profile_);
855 if (off_the_record)
856 state.RemoveActiveContext(off_the_record);
857 registrar_.RemoveAll();
858 is_active_ = false;
859 }
860 }
861
862 void ActivityLog::Observe(int type,
863 const content::NotificationSource& source,
864 const content::NotificationDetails& details) {
865 DCHECK(is_active_);
866 switch (type) {
867 case chrome::NOTIFICATION_PROFILE_CREATED: {
868 Profile* profile = content::Source<Profile>(source).ptr();
869 if (profile_->IsSameProfile(profile))
870 g_activity_log_state.Get().AddActiveContext(profile);
871 break;
872 }
873 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
874 Profile* profile = content::Source<Profile>(source).ptr();
875 if (profile_->IsSameProfile(profile))
876 g_activity_log_state.Get().RemoveActiveContext(profile);
877 break;
878 }
879 default:
880 NOTREACHED();
881 }
882 }
883
663 template <> 884 template <>
664 void BrowserContextKeyedAPIFactory<ActivityLog>::DeclareFactoryDependencies() { 885 void BrowserContextKeyedAPIFactory<ActivityLog>::DeclareFactoryDependencies() {
665 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); 886 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
666 DependsOn(ExtensionRegistryFactory::GetInstance()); 887 DependsOn(ExtensionRegistryFactory::GetInstance());
667 } 888 }
668 889
669 } // namespace extensions 890 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698