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