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_ |