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