activity_log.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 6#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 7 8#include <map> 9#include <string> 10#include <vector> 11 12#include "base/callback.h" 13#include "base/observer_list_threadsafe.h" 14#include "base/synchronization/lock.h" 15#include "base/threading/thread.h" 16#include "chrome/browser/extensions/activity_log/activity_actions.h" 17#include "chrome/browser/extensions/activity_log/activity_log_policy.h" 18#include "chrome/browser/extensions/install_observer.h" 19#include "chrome/browser/extensions/tab_helper.h" 20#include "chrome/common/extensions/dom_action_types.h" 21#include "extensions/browser/api_activity_monitor.h" 22#include "extensions/browser/browser_context_keyed_api_factory.h" 23 24class Profile; 25 26namespace content { 27class BrowserContext; 28} 29 30namespace user_prefs { 31class PrefRegistrySyncable; 32} 33 34namespace extensions { 35class Extension; 36class InstallTracker; 37 38// A utility for tracing interesting activity for each extension. 39// It writes to an ActivityDatabase on a separate thread to record the activity. 40// Each profile has different extensions, so we keep a different database for 41// each profile. 42class ActivityLog : public BrowserContextKeyedAPI, 43 public ApiActivityMonitor, 44 public TabHelper::ScriptExecutionObserver, 45 public InstallObserver { 46 public: 47 // Observers can listen for activity events. There is probably only one 48 // observer: the activityLogPrivate API. 49 class Observer { 50 public: 51 virtual void OnExtensionActivity(scoped_refptr<Action> activity) = 0; 52 }; 53 54 static BrowserContextKeyedAPIFactory<ActivityLog>* GetFactoryInstance(); 55 56 // ActivityLog is a KeyedService, so don't instantiate it with 57 // the constructor; use GetInstance instead. 58 static ActivityLog* GetInstance(content::BrowserContext* context); 59 60 // Add/remove observer: the activityLogPrivate API only listens when the 61 // ActivityLog extension is registered for an event. 62 void AddObserver(Observer* observer); 63 void RemoveObserver(Observer* observer); 64 65 // Logs an extension action: passes it to any installed policy to be logged 66 // to the database, to any observers, and logs to the console if in testing 67 // mode. 68 void LogAction(scoped_refptr<Action> action); 69 70 // Gets all actions that match the specified fields. URLs are treated like 71 // prefixes; other fields are exact matches. Empty strings are not matched to 72 // anything. For daysAgo, today is 0, yesterday is 1, etc.; a negative number 73 // of days is treated as a missing parameter. 74 void GetFilteredActions( 75 const std::string& extension_id, 76 const Action::ActionType type, 77 const std::string& api_name, 78 const std::string& page_url, 79 const std::string& arg_url, 80 const int days_ago, 81 const base::Callback 82 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback); 83 84 // Extension::InstallObserver 85 // We keep track of whether the whitelisted extension is installed; if it is, 86 // we want to recompute whether to have logging enabled. 87 virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE; 88 virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE; 89 virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE; 90 91 // ApiActivityMonitor 92 virtual void OnApiEventDispatched( 93 const std::string& extension_id, 94 const std::string& event_name, 95 scoped_ptr<base::ListValue> event_args) OVERRIDE; 96 virtual void OnApiFunctionCalled( 97 const std::string& extension_id, 98 const std::string& api_name, 99 scoped_ptr<base::ListValue> event_args) OVERRIDE; 100 101 // KeyedService 102 virtual void Shutdown() OVERRIDE; 103 104 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 105 106 // Remove actions from the activity log database which IDs specified in the 107 // action_ids array. 108 void RemoveActions(const std::vector<int64>& action_ids); 109 110 // Clean up URLs from the activity log database. 111 // If restrict_urls is empty then all URLs in the activity log database are 112 // removed, otherwise only those in restrict_urls are removed. 113 void RemoveURLs(const std::vector<GURL>& restrict_urls); 114 void RemoveURLs(const std::set<GURL>& restrict_urls); 115 void RemoveURL(const GURL& url); 116 117 // Deletes the database associated with the policy that's currently in use. 118 void DeleteDatabase(); 119 120 // If we're in a browser test, we need to pretend that the watchdog app is 121 // active. 122 void SetWatchdogAppActiveForTesting(bool active); 123 124 private: 125 friend class ActivityLogTest; 126 friend class BrowserContextKeyedAPIFactory<ActivityLog>; 127 128 explicit ActivityLog(content::BrowserContext* context); 129 virtual ~ActivityLog(); 130 131 // Specifies if the Watchdog app is active (installed & enabled). 132 // If so, we need to log to the database and stream to the API. 133 bool IsWatchdogAppActive(); 134 135 // Specifies if we need to record actions to the db. If so, we need to log to 136 // the database. This is true if the Watchdog app is active *or* the 137 // --enable-extension-activity-logging flag is set. 138 bool IsDatabaseEnabled(); 139 140 // Delayed initialization of Install Tracker which waits until after the 141 // ExtensionSystem/ExtensionService are done with their own setup. 142 void InitInstallTracker(); 143 144 // TabHelper::ScriptExecutionObserver implementation. 145 // Fires when a ContentScript is executed. 146 virtual void OnScriptsExecuted( 147 const content::WebContents* web_contents, 148 const ExecutingScriptsMap& extension_ids, 149 int32 page_id, 150 const GURL& on_url) OVERRIDE; 151 152 // At the moment, ActivityLog will use only one policy for summarization. 153 // These methods are used to choose and set the most appropriate policy. 154 // Changing policies at runtime is not recommended, and likely only should be 155 // done for unit tests. 156 void ChooseDatabasePolicy(); 157 void SetDatabasePolicy(ActivityLogPolicy::PolicyType policy_type); 158 159 // BrowserContextKeyedAPI implementation. 160 static const char* service_name() { return "ActivityLog"; } 161 static const bool kServiceRedirectedInIncognito = true; 162 static const bool kServiceIsCreatedWithBrowserContext = false; 163 164 typedef ObserverListThreadSafe<Observer> ObserverList; 165 scoped_refptr<ObserverList> observers_; 166 167 // Policy objects are owned by the ActivityLog, but cannot be scoped_ptrs 168 // since they may need to do some cleanup work on the database thread. 169 // Calling policy->Close() will free the object; see the comments on the 170 // ActivityDatabase class for full details. 171 172 // The database policy object takes care of recording & looking up data: 173 // data summarization, compression, and logging. There should only be a 174 // database_policy_ if the Watchdog app is installed or flag is set. 175 ActivityLogDatabasePolicy* database_policy_; 176 ActivityLogPolicy::PolicyType database_policy_type_; 177 178 // The UMA policy is used for recording statistics about extension behavior. 179 // This policy is always in use, except for Incognito profiles. 180 ActivityLogPolicy* uma_policy_; 181 182 Profile* profile_; 183 bool db_enabled_; // Whether logging to disk is currently enabled. 184 // testing_mode_ controls which policy is selected. 185 // * By default, we choose a policy that doesn't log most arguments to avoid 186 // saving too much data. We also elide some arguments for privacy reasons. 187 // * In testing mode, we choose a policy that logs all arguments. 188 // testing_mode_ also causes us to print to the console. 189 bool testing_mode_; 190 // We need the DB, FILE, and IO threads to write to the database. 191 // In some cases (tests), these threads might not exist, so we avoid 192 // dispatching anything to the policies/database to prevent things from 193 // exploding. 194 bool has_threads_; 195 196 // Used to track whether the whitelisted extension is installed. If it's 197 // added or removed, enabled_ may change. 198 InstallTracker* tracker_; 199 200 // Set if the watchdog app is installed and enabled. Maintained by 201 // kWatchdogExtensionActive pref variable. Since there are multiple valid 202 // extension IDs, this needs to be an int to count how many are installed. 203 int watchdog_apps_active_; 204 205 FRIEND_TEST_ALL_PREFIXES(ActivityLogApiTest, TriggerEvent); 206 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, AppAndCommandLine); 207 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, CommandLineSwitch); 208 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, NoSwitch); 209 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, PrefSwitch); 210 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, WatchdogSwitch); 211 DISALLOW_COPY_AND_ASSIGN(ActivityLog); 212}; 213 214template <> 215void BrowserContextKeyedAPIFactory<ActivityLog>::DeclareFactoryDependencies(); 216 217} // namespace extensions 218 219#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 220