Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1472)

Unified Diff: chrome/browser/extensions/activity_log.h

Issue 11421192: Save extension activity log to a file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Another small fix Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_

Powered by Google App Engine
This is Rietveld 408576698