| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ |
| 6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ | 6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | |
| 13 #include "base/bind_helpers.h" | |
| 14 #include "base/callback.h" | 12 #include "base/callback.h" |
| 15 #include "base/containers/hash_tables.h" | |
| 16 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 17 #include "base/observer_list_threadsafe.h" | 14 #include "base/observer_list_threadsafe.h" |
| 18 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
| 19 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 20 #include "chrome/browser/extensions/activity_log/activity_actions.h" | 17 #include "chrome/browser/extensions/activity_log/activity_actions.h" |
| 21 #include "chrome/browser/extensions/activity_log/activity_database.h" | 18 #include "chrome/browser/extensions/activity_log/activity_database.h" |
| 19 #include "chrome/browser/extensions/activity_log/activity_log_policy.h" |
| 22 #include "chrome/browser/extensions/install_observer.h" | 20 #include "chrome/browser/extensions/install_observer.h" |
| 23 #include "chrome/browser/extensions/install_tracker.h" | 21 #include "chrome/browser/extensions/install_tracker.h" |
| 24 #include "chrome/browser/extensions/tab_helper.h" | 22 #include "chrome/browser/extensions/tab_helper.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/common/extensions/dom_action_types.h" | 24 #include "chrome/common/extensions/dom_action_types.h" |
| 27 #include "components/browser_context_keyed_service/browser_context_dependency_ma
nager.h" | 25 #include "components/browser_context_keyed_service/browser_context_dependency_ma
nager.h" |
| 28 #include "components/browser_context_keyed_service/browser_context_keyed_service
.h" | 26 #include "components/browser_context_keyed_service/browser_context_keyed_service
.h" |
| 29 #include "components/browser_context_keyed_service/browser_context_keyed_service
_factory.h" | 27 #include "components/browser_context_keyed_service/browser_context_keyed_service
_factory.h" |
| 30 #include "content/public/browser/browser_thread.h" | |
| 31 | 28 |
| 32 class Profile; | 29 class Profile; |
| 33 using content::BrowserThread; | 30 using content::BrowserThread; |
| 34 | 31 |
| 35 namespace extensions { | 32 namespace extensions { |
| 36 class Extension; | 33 class Extension; |
| 34 class ActivityLogPolicy; |
| 37 | 35 |
| 38 // A utility for tracing interesting activity for each extension. | 36 // A utility for tracing interesting activity for each extension. |
| 39 // It writes to an ActivityDatabase on a separate thread to record the activity. | 37 // It writes to an ActivityDatabase on a separate thread to record the activity. |
| 40 class ActivityLog : public BrowserContextKeyedService, | 38 class ActivityLog : public BrowserContextKeyedService, |
| 41 public TabHelper::ScriptExecutionObserver, | 39 public TabHelper::ScriptExecutionObserver, |
| 42 public InstallObserver { | 40 public InstallObserver { |
| 43 public: | 41 public: |
| 44 // Observers can listen for activity events. There is probably only one | 42 // Observers can listen for activity events. There is probably only one |
| 45 // observer: the activityLogPrivate API. | 43 // observer: the activityLogPrivate API. |
| 46 class Observer { | 44 class Observer { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 void LogEventAction(const std::string& extension_id, | 79 void LogEventAction(const std::string& extension_id, |
| 82 const std::string& name, // e.g., tabs.onUpdate | 80 const std::string& name, // e.g., tabs.onUpdate |
| 83 ListValue* args, // arguments to the callback | 81 ListValue* args, // arguments to the callback |
| 84 const std::string& extra); // any extra logging info | 82 const std::string& extra); // any extra logging info |
| 85 | 83 |
| 86 // Log a blocked API call made by an extension. | 84 // Log a blocked API call made by an extension. |
| 87 // This will create a BlockedAction for storage in the database. | 85 // This will create a BlockedAction for storage in the database. |
| 88 void LogBlockedAction(const std::string& extension_id, | 86 void LogBlockedAction(const std::string& extension_id, |
| 89 const std::string& blocked_call, // e.g., tabs.get | 87 const std::string& blocked_call, // e.g., tabs.get |
| 90 ListValue* args, // argument values | 88 ListValue* args, // argument values |
| 91 const BlockedAction::Reason reason, // why it's blocked | 89 BlockedAction::Reason reason, // why it's blocked |
| 92 const std::string& extra); // extra logging info | 90 const std::string& extra); // extra logging info |
| 93 | 91 |
| 94 // Log an interaction between an extension and a URL. | 92 // Log an interaction between an extension and a URL. |
| 95 // This will create a DOMAction for storage in the database. | 93 // This will create a DOMAction for storage in the database. |
| 96 void LogDOMAction(const std::string& extension_id, | 94 void LogDOMAction(const std::string& extension_id, |
| 97 const GURL& url, // target URL | 95 const GURL& url, // target URL |
| 98 const string16& url_title, // title of the URL | 96 const string16& url_title, // title of the URL |
| 99 const std::string& api_call, // api call | 97 const std::string& api_call, // api call |
| 100 const ListValue* args, // arguments | 98 const ListValue* args, // arguments |
| 101 DomActionType::Type call_type, // type of the call | 99 DomActionType::Type call_type, // type of the call |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 bool is_platform_app) OVERRIDE {} | 134 bool is_platform_app) OVERRIDE {} |
| 137 virtual void OnDownloadProgress(const std::string& extension_id, | 135 virtual void OnDownloadProgress(const std::string& extension_id, |
| 138 int percent_downloaded) OVERRIDE {} | 136 int percent_downloaded) OVERRIDE {} |
| 139 virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {} | 137 virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {} |
| 140 virtual void OnAppsReordered() OVERRIDE {} | 138 virtual void OnAppsReordered() OVERRIDE {} |
| 141 virtual void OnAppInstalledToAppList( | 139 virtual void OnAppInstalledToAppList( |
| 142 const std::string& extension_id) OVERRIDE {} | 140 const std::string& extension_id) OVERRIDE {} |
| 143 virtual void OnShutdown() OVERRIDE {} | 141 virtual void OnShutdown() OVERRIDE {} |
| 144 | 142 |
| 145 // For unit tests only. | 143 // For unit tests only. |
| 144 // TODO(felt) In the future, when we'll have multiple policies, it might |
| 145 // be needed to rename the argument. |
| 146 void SetArgumentLoggingForTesting(bool log_arguments); | 146 void SetArgumentLoggingForTesting(bool log_arguments); |
| 147 static void RecomputeLoggingIsEnabled(bool profile_enabled); | 147 static void RecomputeLoggingIsEnabled(bool profile_enabled); |
| 148 | 148 |
| 149 // BrowserContextKeyedService | 149 // BrowserContextKeyedService |
| 150 virtual void Shutdown() OVERRIDE; | 150 virtual void Shutdown() OVERRIDE; |
| 151 | 151 |
| 152 // At the moment, ActivityLog will use only one policy for summarization |
| 153 // (POLICY_NOARGS by default). This static member function can be used |
| 154 // to change the default type, but has to be called before the first |
| 155 // GetInstance call. |
| 156 // TODO(dbabic,felt) ActivityLog should support multiple policies at the |
| 157 // same time, so this will need to be changed later. |
| 158 void SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type); |
| 159 |
| 152 private: | 160 private: |
| 153 friend class ActivityLogFactory; | 161 friend class ActivityLogFactory; |
| 154 | 162 |
| 155 explicit ActivityLog(Profile* profile); | 163 explicit ActivityLog(Profile* profile); |
| 156 virtual ~ActivityLog(); | 164 virtual ~ActivityLog(); |
| 157 | 165 |
| 158 // We log callbacks and API calls very similarly, so we handle them the same | 166 // We log callbacks and API calls very similarly, so we handle them the same |
| 159 // way internally. | 167 // way internally. |
| 160 void LogAPIActionInternal( | 168 void LogAPIActionInternal( |
| 161 const std::string& extension_id, | 169 const std::string& extension_id, |
| 162 const std::string& api_call, | 170 const std::string& api_call, |
| 163 ListValue* args, | 171 ListValue* args, |
| 164 const std::string& extra, | 172 const std::string& extra, |
| 165 const APIAction::Type type); | 173 const APIAction::Type type); |
| 166 | 174 |
| 167 // TabHelper::ScriptExecutionObserver implementation. | 175 // TabHelper::ScriptExecutionObserver implementation. |
| 168 // Fires when a ContentScript is executed. | 176 // Fires when a ContentScript is executed. |
| 169 virtual void OnScriptsExecuted( | 177 virtual void OnScriptsExecuted( |
| 170 const content::WebContents* web_contents, | 178 const content::WebContents* web_contents, |
| 171 const ExecutingScriptsMap& extension_ids, | 179 const ExecutingScriptsMap& extension_ids, |
| 172 int32 page_id, | 180 int32 page_id, |
| 173 const GURL& on_url) OVERRIDE; | 181 const GURL& on_url) OVERRIDE; |
| 174 | 182 |
| 175 // The Schedule methods dispatch the calls to the database on a | |
| 176 // separate thread. We dispatch to the UI thread if the DB thread doesn't | |
| 177 // exist, which should only happen in tests where there is no DB thread. | |
| 178 template<typename DatabaseFunc> | |
| 179 void ScheduleAndForget(DatabaseFunc func) { | |
| 180 if (!has_threads_) return; | |
| 181 BrowserThread::PostTask(BrowserThread::DB, | |
| 182 FROM_HERE, | |
| 183 base::Bind(func, base::Unretained(db_))); | |
| 184 } | |
| 185 | |
| 186 template<typename DatabaseFunc, typename ArgA> | |
| 187 void ScheduleAndForget(DatabaseFunc func, ArgA a) { | |
| 188 if (!has_threads_) return; | |
| 189 BrowserThread::PostTask(BrowserThread::DB, | |
| 190 FROM_HERE, | |
| 191 base::Bind(func, base::Unretained(db_), a)); | |
| 192 } | |
| 193 | |
| 194 template<typename DatabaseFunc, typename ArgA, typename ArgB> | |
| 195 void ScheduleAndForget(DatabaseFunc func, ArgA a, ArgB b) { | |
| 196 if (!has_threads_) return; | |
| 197 BrowserThread::PostTask(BrowserThread::DB, | |
| 198 FROM_HERE, | |
| 199 base::Bind(func, base::Unretained(db_), a, b)); | |
| 200 } | |
| 201 | |
| 202 typedef ObserverListThreadSafe<Observer> ObserverList; | 183 typedef ObserverListThreadSafe<Observer> ObserverList; |
| 203 scoped_refptr<ObserverList> observers_; | 184 scoped_refptr<ObserverList> observers_; |
| 204 | 185 |
| 205 // The database wrapper that does the actual database I/O. | 186 // The policy object takes care of data summarization, compression, and |
| 206 // We initialize this on the same thread as the ActivityLog, but then | 187 // logging |
| 207 // subsequent operations occur on the DB thread. Instead of destructing the | 188 extensions::ActivityLogPolicy* policy_; |
| 208 // ActivityDatabase, we call its Close() method on the DB thread and it | |
| 209 // commits suicide. | |
| 210 extensions::ActivityDatabase* db_; | |
| 211 | 189 |
| 190 // TODO(dbabic,felt) change this into a list of policy types later. |
| 191 ActivityLogPolicy::PolicyType policy_type_; |
| 192 |
| 193 Profile* profile_; |
| 194 // TODO(felt) These two flags could use a comment. |
| 195 bool enabled_; |
| 196 bool first_time_checking_; |
| 212 // testing_mode_ controls whether to log API call arguments. By default, we | 197 // testing_mode_ controls whether to log API call arguments. By default, we |
| 213 // don't log most arguments to avoid saving too much data. In testing mode, | 198 // don't log most arguments to avoid saving too much data. In testing mode, |
| 214 // argument collection is enabled. We also whitelist some arguments for | 199 // argument collection is enabled. We also whitelist some arguments for |
| 215 // collection regardless of whether this bool is true. | 200 // collection regardless of whether this bool is true. |
| 216 // When testing_mode_ is enabled, we also print to the console. | 201 // When testing_mode_ is enabled, we also print to the console. |
| 217 bool testing_mode_; | 202 bool testing_mode_; |
| 218 base::hash_set<std::string> arg_whitelist_api_; | |
| 219 | |
| 220 Profile* profile_; | |
| 221 bool enabled_; | |
| 222 bool first_time_checking_; | |
| 223 InstallTracker* tracker_; | |
| 224 | |
| 225 // We need the DB, FILE, and IO threads to operate. In some cases (tests), | 203 // We need the DB, FILE, and IO threads to operate. In some cases (tests), |
| 226 // these threads might not exist, so we avoid dispatching anything to the | 204 // these threads might not exist, so we avoid dispatching anything to the |
| 227 // ActivityDatabase to prevent things from exploding. | 205 // ActivityDatabase to prevent things from exploding. |
| 228 bool has_threads_; | 206 bool has_threads_; |
| 229 | 207 |
| 208 InstallTracker* tracker_; |
| 209 |
| 230 DISALLOW_COPY_AND_ASSIGN(ActivityLog); | 210 DISALLOW_COPY_AND_ASSIGN(ActivityLog); |
| 231 }; | 211 }; |
| 232 | 212 |
| 233 // Each profile has different extensions, so we keep a different database for | 213 // Each profile has different extensions, so we keep a different database for |
| 234 // each profile. | 214 // each profile. |
| 235 class ActivityLogFactory : public BrowserContextKeyedServiceFactory { | 215 class ActivityLogFactory : public BrowserContextKeyedServiceFactory { |
| 236 public: | 216 public: |
| 237 static ActivityLog* GetForProfile(Profile* profile) { | 217 static ActivityLog* GetForProfile(Profile* profile) { |
| 238 return static_cast<ActivityLog*>( | 218 return static_cast<ActivityLog*>( |
| 239 GetInstance()->GetServiceForBrowserContext(profile, true)); | 219 GetInstance()->GetServiceForBrowserContext(profile, true)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 252 virtual content::BrowserContext* GetBrowserContextToUse( | 232 virtual content::BrowserContext* GetBrowserContextToUse( |
| 253 content::BrowserContext* context) const OVERRIDE; | 233 content::BrowserContext* context) const OVERRIDE; |
| 254 | 234 |
| 255 DISALLOW_COPY_AND_ASSIGN(ActivityLogFactory); | 235 DISALLOW_COPY_AND_ASSIGN(ActivityLogFactory); |
| 256 }; | 236 }; |
| 257 | 237 |
| 258 | 238 |
| 259 } // namespace extensions | 239 } // namespace extensions |
| 260 | 240 |
| 261 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ | 241 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ |
| OLD | NEW |