| Index: chrome/browser/extensions/activity_log.h
|
| ===================================================================
|
| --- chrome/browser/extensions/activity_log.h (revision 177317)
|
| +++ 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.
|
| @@ -32,11 +45,12 @@
|
| virtual void OnExtensionActivity(
|
| const Extension* extension,
|
| Activity activity,
|
| - const std::vector<std::string>& messages) = 0;
|
| + const std::string& message) = 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,43 +60,126 @@
|
| // 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.
|
| + // This will create an APIAction for storage in the database.
|
| + void LogAPIAction(const Extension* extension,
|
| + const std::string& name, // e.g., chrome.tabs.get
|
| + const ListValue* args, // the argument values e.g. 46
|
| + const std::string& extra); // any extra logging info
|
|
|
| + // Log a blocked API call made by an extension.
|
| + // This will create a BlockedAction for storage in the database.
|
| + void LogBlockedAction(const Extension* extension,
|
| + const std::string& blocked_call, // eg chrome.tabs.get
|
| + const ListValue* args, // argument values
|
| + const char* reason, // why it's blocked
|
| + const std::string& extra); // extra logging info
|
| +
|
| + // Log an interaction between an extension and a URL.
|
| + // This will create a UrlAction for storage in the database.
|
| + // The technical message might be the list of content scripts that have been
|
| + // injected, or the DOM API call; it's what's shown under "More".
|
| + void LogUrlAction(const Extension* extension,
|
| + const UrlAction::UrlActionType verb, // eg XHR
|
| + const GURL& url, // target URL
|
| + const string16& url_title, // title of the URL,
|
| + // can be empty string
|
| + const std::string& technical_message, // "More"
|
| + const std::string& extra); // extra logging info
|
| +
|
| + // 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,
|
| int32 page_id,
|
| const GURL& on_url) OVERRIDE;
|
|
|
| + // The callback when initializing the database.
|
| + void OnDBInitComplete();
|
| +
|
| static const char* ActivityToString(Activity activity);
|
|
|
| - // A lock used to synchronize access to member variables.
|
| - mutable base::Lock lock_;
|
| + // The Schedule 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));
|
| + }
|
|
|
| + template<typename DatabaseFunc, typename ArgA, typename ArgB>
|
| + void ScheduleAndForget(DatabaseFunc func, ArgA a, ArgB b) {
|
| + if (db_.get())
|
| + BrowserThread::PostTask(BrowserThread::DB,
|
| + FROM_HERE,
|
| + base::Bind(func, db_.get(), a, b));
|
| + }
|
| +
|
| typedef ObserverListThreadSafe<Observer> ObserverList;
|
| typedef std::map<const Extension*, scoped_refptr<ObserverList> >
|
| ObserverMap;
|
| // 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_;
|
| +
|
| + // 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_
|
| +
|
|
|