Chromium Code Reviews| Index: chrome/browser/extensions/activity_log.h |
| =================================================================== |
| --- chrome/browser/extensions/activity_log.h (revision 173817) |
| +++ chrome/browser/extensions/activity_log.h (working copy) |
| @@ -9,16 +9,29 @@ |
| #include <string> |
| #include <vector> |
| +#include "base/bind.h" |
| #include "base/memory/singleton.h" |
| #include "base/observer_list_threadsafe.h" |
| #include "base/synchronization/lock.h" |
| +#include "base/threading/thread.h" |
| +#include "chrome/browser/extensions/activity_database.h" |
| #include "chrome/browser/extensions/tab_helper.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/profiles/profile_dependency_manager.h" |
| +#include "chrome/browser/profiles/profile_keyed_service.h" |
| +#include "chrome/browser/profiles/profile_keyed_service_factory.h" |
| +#include "content/public/browser/browser_thread.h" |
| +class Profile; |
| +using content::BrowserThread; |
| + |
| namespace extensions { |
| class Extension; |
| // A utility for tracing interesting activity for each extension. |
| -class ActivityLog : public TabHelper::ScriptExecutionObserver { |
| +// It writes to an ActivityDatabase on a separate thread to record the activity. |
| +class ActivityLog : public ProfileKeyedService, |
| + public TabHelper::ScriptExecutionObserver { |
| public: |
| enum Activity { |
| ACTIVITY_EXTENSION_API_CALL, // Extension API invocation is called. |
| @@ -35,8 +48,9 @@ |
| const std::vector<std::string>& messages) = 0; |
| }; |
| - virtual ~ActivityLog(); |
| - static ActivityLog* GetInstance(); |
| + // ActivityLog is a singleton, so don't instantiate it with the constructor; |
| + // use GetInstance instead. |
| + static ActivityLog* GetInstance(Profile* profile); |
| // Add/remove observer. |
| void AddObserver(const Extension* extension, Observer* observer); |
| @@ -46,19 +60,39 @@ |
| // Check for the existence observer list by extension_id. |
| bool HasObservers(const Extension* extension) const; |
| - // Log |activity| for |extension|. |
| - void Log(const Extension* extension, |
| - Activity activity, |
| - const std::string& message) const; |
| - void Log(const Extension* extension, |
| - Activity activity, |
| - const std::vector<std::string>& messages) const; |
| + // Log a successful API call made by an extension. |
| + void LogAPIAction(const Extension* extension, |
| + const std::string& name, |
| + const ListValue* args); |
| + // Log a blocked API call made by an extension. |
| + void LogBlockedAction(const Extension* extension, |
| + const std::string& blocked_call, |
| + const ListValue* args, |
| + const char* reason); |
| + |
| + // Log an interaction between an extension and a URL. |
| + // The message might be the list of content scripts that have been injected, |
| + // or the list of DOM nodes that have been touched. Either way, the message |
| + // is not intended to be shown to average users. |
| + void LogUrlAction(const Extension* extension, |
| + const GURL& url, |
| + const string16& url_title, |
| + std::string& message, |
| + const UrlAction::UrlActionType verb); |
| + |
| + // An error has happened; we want to rollback and close the db. |
| + // Needs to be public so the error delegate can call it. |
| + void KillActivityLogDatabase(); |
| + |
| private: |
| - ActivityLog(); |
| - friend struct DefaultSingletonTraits<ActivityLog>; |
| + friend class ActivityLogFactory; |
| + explicit ActivityLog(Profile* profile); |
| + virtual ~ActivityLog(); |
| + |
| // TabHelper::ScriptExecutionObserver implementation. |
| + // Fires when a ContentScript is executed. |
| virtual void OnScriptsExecuted( |
| const content::WebContents* web_contents, |
| const ExecutingScriptsMap& extension_ids, |
| @@ -67,12 +101,23 @@ |
| static const char* ActivityToString(Activity activity); |
| - // A lock used to synchronize access to member variables. |
| - mutable base::Lock lock_; |
| + // The ScheduleAndForget methods dispatch the calls to the database on a |
| + // separate thread. |
| + template<typename DatabaseFunc> |
| + void ScheduleAndForget(DatabaseFunc func) { |
| + if (db_.get()) |
| + BrowserThread::PostTask(BrowserThread::DB, |
| + FROM_HERE, |
| + base::Bind(func, db_.get())); |
| + } |
| - // Whether to log activity to stdout. This is set by checking the |
| - // enable-extension-activity-logging switch. |
| - bool log_activity_to_stdout_; |
| + template<typename DatabaseFunc, typename ArgA> |
| + void ScheduleAndForget(DatabaseFunc func, ArgA a) { |
| + if (db_.get()) |
| + BrowserThread::PostTask(BrowserThread::DB, |
| + FROM_HERE, |
| + base::Bind(func, db_.get(), a)); |
| + } |
| typedef ObserverListThreadSafe<Observer> ObserverList; |
| typedef std::map<const Extension*, scoped_refptr<ObserverList> > |
| @@ -80,9 +125,46 @@ |
| // A map of extensions to activity observers for that extension. |
| ObserverMap observers_; |
| + // The database wrapper that does the actual database I/O. |
| + scoped_refptr<extensions::ActivityDatabase> db_; |
| + |
| + // A lock used to synchronize access to member variables. |
| + mutable base::Lock lock_; |
|
Matt Perry
2013/01/03 20:53:35
Is this lock needed? It sounds like this class can
felt
2013/01/07 23:44:22
It should only be accessed from the main (UI) thre
|
| + |
| + // Whether to log activity to stdout. This is set by checking the |
| + // enable-extension-activity-logging switch. |
| + bool log_activity_to_stdout_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(ActivityLog); |
| }; |
| +// Each profile has different extensions, so we keep a different database for |
| +// each profile. |
| +class ActivityLogFactory : public ProfileKeyedServiceFactory { |
| + public: |
| + static ActivityLog* GetForProfile(Profile* profile) { |
| + return static_cast<ActivityLog*>( |
| + GetInstance()->GetServiceForProfile(profile, true)); |
| + } |
| + |
| + static ActivityLogFactory* GetInstance(); |
| + |
| + private: |
| + friend struct DefaultSingletonTraits<ActivityLogFactory>; |
| + ActivityLogFactory() |
| + : ProfileKeyedServiceFactory("ActivityLog", |
| + ProfileDependencyManager::GetInstance()) {} |
| + virtual ~ActivityLogFactory() {} |
| + |
| + virtual ProfileKeyedService* BuildServiceInstanceFor( |
| + Profile* profile) const OVERRIDE; |
| + |
| + virtual bool ServiceRedirectedInIncognito() const OVERRIDE; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ActivityLogFactory); |
| +}; |
| + |
| + |
| } // namespace extensions |
| #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_H_ |