activity_log.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_string_value_serializer.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/utf_string_conversions.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_checker.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_system_factory.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/install_tracker_factory.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager_factory.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/incognito_helpers.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/re2/re2/re2.h"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace constants = activity_log_constants;
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Concatenate arguments.
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string MakeArgList(const base::ListValue* args) {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string call_signature;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ListValue::const_iterator it = args->begin();
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (; it != args->end(); ++it) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string arg;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    JSONStringValueSerializer serializer(&arg);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (serializer.SerializeAndOmitBinaryValues(**it)) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it != args->begin())
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        call_signature += ", ";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      call_signature += arg;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return call_signature;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is a hack for AL callers who don't have access to a profile object
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// when deciding whether or not to do the work required for logging. The state
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// is accessed through the static ActivityLog::IsLogEnabledOnAnyProfile()
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// method. It returns true if --enable-extension-activity-logging is set on the
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// command line OR *ANY* profile has the activity log whitelisted extension
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// installed.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LogIsEnabled {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogIsEnabled() : any_profile_enabled_(false) {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ComputeIsFlagEnabled();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void ComputeIsFlagEnabled() {
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cmd_line_enabled_ = CommandLine::ForCurrentProcess()->
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        HasSwitch(switches::kEnableExtensionActivityLogging);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static LogIsEnabled* GetInstance() {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Singleton<LogIsEnabled>::get();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool IsEnabled() {
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return cmd_line_enabled_ || any_profile_enabled_;
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void SetProfileEnabled(bool any_profile_enabled) {
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    any_profile_enabled_ = any_profile_enabled;
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::Lock lock_;
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool any_profile_enabled_;
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool cmd_line_enabled_;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ActivityLog::IsLogEnabledOnAnyProfile() {
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return LogIsEnabled::GetInstance()->IsEnabled();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::RecomputeLoggingIsEnabled(bool profile_enabled) {
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogIsEnabled::GetInstance()->ComputeIsFlagEnabled();
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogIsEnabled::GetInstance()->SetProfileEnabled(profile_enabled);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ActivityLogFactory
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ActivityLogFactory* ActivityLogFactory::GetInstance() {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Singleton<ActivityLogFactory>::get();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* ActivityLogFactory::BuildServiceInstanceFor(
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::BrowserContext* profile) const {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new ActivityLog(static_cast<Profile*>(profile));
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse(
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::BrowserContext* context) const {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chrome::GetBrowserContextRedirectedInIncognito(context);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLogFactory::ActivityLogFactory()
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : BrowserContextKeyedServiceFactory(
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "ActivityLog",
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        BrowserContextDependencyManager::GetInstance()) {
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DependsOn(ExtensionSystemFactory::GetInstance());
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DependsOn(InstallTrackerFactory::GetInstance());
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLogFactory::~ActivityLogFactory() {
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ActivityLog
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) {
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Can't use IsLogEnabled() here because this is called from inside Init.
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (policy_type != policy_type_ && enabled_) {
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Deleting the old policy takes place asynchronously, on the database
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // thread.  Initializing a new policy below similarly happens
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // asynchronously.  Since the two operations are both queued for the
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // database, the queue ordering should ensure that the deletion completes
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // before database initialization occurs.
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // However, changing policies at runtime is still not recommended, and
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // likely only should be done for unit tests.
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (policy_)
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      policy_->Close();
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    switch (policy_type) {
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      case ActivityLogPolicy::POLICY_FULLSTREAM:
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        policy_ = new FullStreamUIPolicy(profile_);
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        break;
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      case ActivityLogPolicy::POLICY_NOARGS:
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        policy_ = new StreamWithoutArgsUIPolicy(profile_);
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        break;
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      default:
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    policy_type_ = policy_type;
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use GetInstance instead of directly creating an ActivityLog.
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLog::ActivityLog(Profile* profile)
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : policy_(NULL),
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      policy_type_(ActivityLogPolicy::POLICY_INVALID),
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      profile_(profile),
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      enabled_(false),
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      initialized_(false),
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      policy_chosen_(false),
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      testing_mode_(false),
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      has_threads_(true),
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      tracker_(NULL) {
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // This controls whether logging statements are printed, which policy is set,
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // etc.
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch(
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    switches::kEnableExtensionActivityLogTesting);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Check that the right threads exist. If not, we shouldn't try to do things
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // that require them.
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) ||
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) ||
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LOG(ERROR) << "Missing threads, disabling Activity Logging!";
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    has_threads_ = false;
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    enabled_ = IsLogEnabledOnAnyProfile();
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ExtensionSystem::Get(profile_)->ready().Post(
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE, base::Bind(&ActivityLog::Init, base::Unretained(this)));
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  observers_ = new ObserverListThreadSafe<Observer>;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::Init() {
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(has_threads_);
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!initialized_);
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const Extension* whitelisted_extension = ExtensionSystem::Get(profile_)->
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      extension_service()->GetExtensionById(kActivityLogExtensionId, false);
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (whitelisted_extension) {
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    enabled_ = true;
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LogIsEnabled::GetInstance()->SetProfileEnabled(true);
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  tracker_ = InstallTrackerFactory::GetForProfile(profile_);
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  tracker_->AddObserver(this);
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ChooseDefaultPolicy();
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  initialized_ = true;
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::ChooseDefaultPolicy() {
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (policy_chosen_ || !enabled_) return;
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (testing_mode_)
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  else
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS);
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::Shutdown() {
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (tracker_) tracker_->RemoveObserver(this);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ActivityLog::~ActivityLog() {
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (policy_)
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    policy_->Close();
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ActivityLog::IsLogEnabled() {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!has_threads_ || !initialized_) return false;
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return enabled_;
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::OnExtensionLoaded(const Extension* extension) {
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension->id() != kActivityLogExtensionId) return;
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  enabled_ = true;
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogIsEnabled::GetInstance()->SetProfileEnabled(true);
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ChooseDefaultPolicy();
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::OnExtensionUnloaded(const Extension* extension) {
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension->id() != kActivityLogExtensionId) return;
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      switches::kEnableExtensionActivityLogging))
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    enabled_ = false;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ActivityLog* ActivityLog::GetInstance(Profile* profile) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ActivityLogFactory::GetForProfile(profile);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::AddObserver(ActivityLog::Observer* observer) {
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  observers_->AddObserver(observer);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) {
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  observers_->RemoveObserver(observer);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ActivityLog::LogAction(scoped_refptr<Action> action) {
259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (IsLogEnabled() &&
260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      !ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) {
261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (policy_)
262558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      policy_->ProcessAction(action);
263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    observers_->Notify(&Observer::OnExtensionActivity, action);
264558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (testing_mode_)
265558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      LOG(INFO) << action->PrintForDebug();
266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
267558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogAPIActionInternal(const std::string& extension_id,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const std::string& api_call,
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                       base::ListValue* args,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const std::string& extra,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const APIAction::Type type) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string verb, manager;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (matches) {
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!args->empty() && manager == "tabs") {
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      APIAction::LookupTabId(api_call, args, profile_);
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) &&
282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch           "Unexpected APIAction call type.");
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    scoped_refptr<Action> action;
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action = new Action(extension_id,
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        base::Time::Now(),
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        type == APIAction::CALL ? Action::ACTION_API_CALL
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                : Action::ACTION_API_EVENT,
289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        api_call);
290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action->set_args(make_scoped_ptr(args->DeepCopy()));
291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!extra.empty())
292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      action->mutable_other()->SetString(constants::kActionExtra, extra);
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LogAction(action);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Unknown API call! " << api_call;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A wrapper around LogAPIActionInternal, but we know it's an API call.
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogAPIAction(const std::string& extension_id,
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& api_call,
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               base::ListValue* args,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& extra) {
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!IsLogEnabled() ||
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogAPIActionInternal(extension_id,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       api_call,
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       args,
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       extra,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       APIAction::CALL);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A wrapper around LogAPIActionInternal, but we know it's actually an event
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// being fired and triggering extension code. Having the two separate methods
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (LogAPIAction vs LogEventAction) lets us hide how we actually choose to
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// handle them. Right now they're being handled almost the same.
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogEventAction(const std::string& extension_id,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& api_call,
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 base::ListValue* args,
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& extra) {
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!IsLogEnabled() ||
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LogAPIActionInternal(extension_id,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       api_call,
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       args,
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       extra,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       APIAction::EVENT_CALLBACK);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogBlockedAction(const std::string& extension_id,
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const std::string& blocked_call,
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                   base::ListValue* args,
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   BlockedAction::Reason reason,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const std::string& extra) {
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!IsLogEnabled() ||
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
339558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<Action> action;
340558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action = new Action(extension_id,
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      base::Time::Now(),
342558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      Action::ACTION_API_BLOCKED,
343558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      blocked_call);
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->set_args(make_scoped_ptr(args->DeepCopy()));
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->mutable_other()
346558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      ->SetInteger(constants::kActionBlockedReason, static_cast<int>(reason));
347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!extra.empty())
348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action->mutable_other()->SetString(constants::kActionExtra, extra);
349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  LogAction(action);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogDOMAction(const std::string& extension_id,
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               const GURL& url,
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               const string16& url_title,
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               const std::string& api_call,
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               const base::ListValue* args,
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               DomActionType::Type call_type,
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               const std::string& extra) {
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!IsLogEnabled() ||
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
363558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Action::ActionType action_type = Action::ACTION_DOM_ACCESS;
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (call_type == DomActionType::INSERTED) {
365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action_type = Action::ACTION_CONTENT_SCRIPT;
366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  } else if (call_type == DomActionType::METHOD &&
367558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch             api_call == "XMLHttpRequest.open") {
368558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    call_type = DomActionType::XHR;
369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action_type = Action::ACTION_DOM_XHR;
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
372558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<Action> action;
373558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action = new Action(extension_id, base::Time::Now(), action_type, api_call);
374558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (args)
375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action->set_args(make_scoped_ptr(args->DeepCopy()));
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->set_page_url(url);
377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->set_page_title(base::UTF16ToUTF8(url_title));
378558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->mutable_other()
379558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      ->SetInteger(constants::kActionDomVerb, static_cast<int>(call_type));
380558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!extra.empty())
381558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action->mutable_other()->SetString(constants::kActionExtra, extra);
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  LogAction(action);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::LogWebRequestAction(const std::string& extension_id,
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const GURL& url,
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const std::string& api_call,
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      scoped_ptr<DictionaryValue> details,
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const std::string& extra) {
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!IsLogEnabled() ||
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
394558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<Action> action;
395558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action = new Action(
396558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      extension_id, base::Time::Now(), Action::ACTION_WEB_REQUEST, api_call);
397558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->set_page_url(url);
398558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action->mutable_other()->Set(constants::kActionWebRequest, details.release());
399558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!extra.empty())
400558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    action->mutable_other()->SetString(constants::kActionExtra, extra);
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
402558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  LogAction(action);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ActivityLog::GetActions(
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& extension_id,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int day,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Callback
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) {
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (policy_) {
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    policy_->ReadData(extension_id, day, callback);
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ActivityLog::OnScriptsExecuted(
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::WebContents* web_contents,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ExecutingScriptsMap& extension_ids,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 on_page_id,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& on_url) {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsLogEnabled()) return;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile =
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile::FromBrowserContext(web_contents->GetBrowserContext());
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionService* extension_service =
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionSet* extensions = extension_service->extensions();
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const prerender::PrerenderManager* prerender_manager =
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prerender::PrerenderManagerFactory::GetForProfile(
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          Profile::FromBrowserContext(web_contents->GetBrowserContext()));
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string extra;
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (prerender_manager &&
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prerender_manager->IsWebContentsPrerendering(web_contents, NULL))
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extra = "(prerender)";
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExecutingScriptsMap::const_iterator it = extension_ids.begin();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != extension_ids.end(); ++it) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* extension = extensions->GetByID(it->first);
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!extension || ActivityLogAPI::IsExtensionWhitelisted(extension->id()))
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If OnScriptsExecuted is fired because of tabs.executeScript, the list
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // of content scripts will be empty.  We don't want to log it because
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the call to tabs.executeScript will have already been logged anyway.
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it->second.empty()) {
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string ext_scripts_str;
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (std::set<std::string>::const_iterator it2 = it->second.begin();
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           it2 != it->second.end();
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           ++it2) {
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ext_scripts_str += *it2;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ext_scripts_str += " ";
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scoped_ptr<base::ListValue> script_names(new base::ListValue());
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      script_names->Set(0, new base::StringValue(ext_scripts_str));
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      LogDOMAction(extension->id(),
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   on_url,
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   web_contents->GetTitle(),
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   std::string(),  // no api call here
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   script_names.get(),
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   DomActionType::INSERTED,
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   extra);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
466