Chromium Code Reviews| Index: chrome/browser/extensions/activity_log/activity_log.cc |
| diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc |
| index 994d3e20263170e0f3f3cad13a76d9eb4a3dc78c..d853d8079e72f295b7e0acac67d86f03f231ab7a 100644 |
| --- a/chrome/browser/extensions/activity_log/activity_log.cc |
| +++ b/chrome/browser/extensions/activity_log/activity_log.cc |
| @@ -12,6 +12,7 @@ |
| #include "chrome/browser/extensions/activity_log/activity_log.h" |
| #include "chrome/browser/extensions/activity_log/api_actions.h" |
| #include "chrome/browser/extensions/activity_log/blocked_actions.h" |
| +#include "chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_system.h" |
| #include "chrome/browser/profiles/incognito_helpers.h" |
| @@ -88,41 +89,6 @@ void ActivityLog::RecomputeLoggingIsEnabled() { |
| return LogIsEnabled::GetInstance()->ComputeIsEnabled(); |
| } |
| -// This handles errors from the database. |
| -class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate { |
| - public: |
| - explicit KillActivityDatabaseErrorDelegate(ActivityLog* backend) |
| - : backend_(backend), |
| - scheduled_death_(false) {} |
| - |
| - virtual int OnError(int error, |
| - sql::Connection* connection, |
| - sql::Statement* stmt) OVERRIDE { |
| - if (!scheduled_death_ && sql::IsErrorCatastrophic(error)) { |
| - ScheduleDeath(); |
| - } |
| - return error; |
| - } |
| - |
| - // Schedules death if an error wasn't already reported. |
| - void ScheduleDeath() { |
| - if (!scheduled_death_) { |
| - scheduled_death_ = true; |
| - backend_->KillActivityLogDatabase(); |
| - } |
| - } |
| - |
| - bool scheduled_death() const { |
| - return scheduled_death_; |
| - } |
| - |
| - private: |
| - ActivityLog* backend_; |
| - bool scheduled_death_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(KillActivityDatabaseErrorDelegate); |
| -}; |
| - |
| // ActivityLogFactory |
| ActivityLogFactory* ActivityLogFactory::GetInstance() { |
| @@ -142,7 +108,7 @@ content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse( |
| // ActivityLog |
| // Use GetInstance instead of directly creating an ActivityLog. |
| -ActivityLog::ActivityLog(Profile* profile) : profile_(profile) { |
| +ActivityLog::ActivityLog(Profile* profile) : policy_(NULL), profile_(profile) { |
| // enable-extension-activity-logging and enable-extension-activity-ui |
| log_activity_to_stdout_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableExtensionActivityLogging); |
| @@ -159,33 +125,19 @@ ActivityLog::ActivityLog(Profile* profile) : profile_(profile) { |
| } |
| } |
| - // We normally dispatch DB requests to the DB thread, but the thread might |
| - // not exist if we are under test conditions. Substitute the UI thread for |
| - // this case. |
| - if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) { |
| - dispatch_thread_ = BrowserThread::DB; |
| - } else { |
| - LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!"; |
| - dispatch_thread_ = BrowserThread::UI; |
| + // TODO(dbabic) In the next iteration, we should support multiple policies, |
| + // which are then polled by the ActivityLog object |
| + if (IsLogEnabled()){ |
| + if (testing_mode_) { |
| + policy_ = new FullStreamUIPolicy(profile); |
| + } else { |
| + policy_ = new StreamWithoutArgsUIPolicy(profile); |
| + } |
| } |
| - |
| - // If the database cannot be initialized for some reason, we keep |
| - // chugging along but nothing will get recorded. If the UI is |
| - // available, things will still get sent to the UI even if nothing |
| - // is being written to the database. |
| - db_ = new ActivityDatabase(); |
| - if (!IsLogEnabled()) return; |
| - base::FilePath base_dir = profile->GetPath(); |
| - base::FilePath database_name = base_dir.Append( |
| - chrome::kExtensionActivityLogFilename); |
| - KillActivityDatabaseErrorDelegate* error_delegate = |
| - new KillActivityDatabaseErrorDelegate(this); |
| - db_->SetErrorDelegate(error_delegate); |
| - ScheduleAndForget(&ActivityDatabase::Init, database_name); |
| } |
| ActivityLog::~ActivityLog() { |
| - ScheduleAndForget(&ActivityDatabase::Close); |
| + delete policy_; |
| } |
| void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { |
| @@ -222,6 +174,23 @@ void ActivityLog::LogAPIActionInternal(const Extension* extension, |
| if (!args->empty() && manager == "tabs") { |
| APIAction::LookupTabId(api_call, args, profile_); |
| } |
| + |
| + if (policy_) { |
| + DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) && |
| + "Unexpected APIAction call type."); |
| + CHECK(extension && "Must pass a valid extension ptr."); |
| + policy_->ProcessAction( |
| + type == APIAction::CALL ? ActivityLogPolicy::ACTION_API : |
| + ActivityLogPolicy::ACTION_EVENT, |
| + *extension, |
| + api_call, |
| + NULL, |
| + args, |
| + NULL); |
| + } |
| + |
| + // TODO(felt) Logging should be done more efficiently, so that it |
| + // doesn't require construction of the action object. |
| scoped_refptr<APIAction> action = new APIAction( |
| extension->id(), |
| base::Time::Now(), |
| @@ -229,7 +198,6 @@ void ActivityLog::LogAPIActionInternal(const Extension* extension, |
| api_call, |
| MakeArgList(args), |
| extra); |
| - ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
| // Display the action. |
| ObserverMap::const_iterator iter = observers_.find(extension); |
| @@ -260,8 +228,9 @@ void ActivityLog::LogAPIAction(const Extension* extension, |
| const std::string& extra) { |
| if (!IsLogEnabled()) return; |
| if (!testing_mode_ && |
| - arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) |
| + arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) { |
| args->Clear(); |
| + } |
| LogAPIActionInternal(extension, |
| api_call, |
| args, |
| @@ -279,8 +248,9 @@ void ActivityLog::LogEventAction(const Extension* extension, |
| const std::string& extra) { |
| if (!IsLogEnabled()) return; |
| if (!testing_mode_ && |
| - arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) |
| + arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) { |
| args->Clear(); |
| + } |
| LogAPIActionInternal(extension, |
| api_call, |
| args, |
| @@ -295,15 +265,33 @@ void ActivityLog::LogBlockedAction(const Extension* extension, |
| const std::string& extra) { |
| if (!IsLogEnabled()) return; |
| if (!testing_mode_ && |
|
felt
2013/05/22 19:55:46
Shouldn't this be moved into one of the policies?
dbabic
2013/05/23 01:35:04
Sure, if that's your preference. If you expect th
felt
2013/05/23 04:20:01
Yes, I expect this to change. Please move it into
dbabic
2013/05/24 00:35:07
Done.
|
| - arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) |
| + arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) { |
| args->Clear(); |
| + } |
| + |
| + if (policy_) { |
| + scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); |
| + std::string key; |
| + policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON, key); |
| + details->SetInteger(key, static_cast<int>(reason)); |
| + CHECK(extension && "Must pass a valid extension ptr."); |
|
felt
2013/05/22 19:55:46
In general, you probably want DCHECK here.
Regar
dbabic
2013/05/23 01:35:04
Infrequent or not, the old ActivityLog code will c
felt
2013/05/23 04:20:01
Yup, just letting you know it's a known bug. Pleas
dbabic
2013/05/24 00:35:07
Done.
|
| + policy_->ProcessAction( |
| + ActivityLogPolicy::ACTION_BLOCKED, |
| + *extension, |
| + blocked_call, |
| + NULL, |
| + args, |
| + details.get()); |
| + } |
| + |
| + // TODO(felt) Logging should be done more efficiently, so that it |
| + // doesn't require construction of the action object. |
|
felt
2013/05/22 19:55:46
Regardless, the following code will all be deleted
dbabic
2013/05/23 01:35:04
Ok.
|
| scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), |
| base::Time::Now(), |
| blocked_call, |
| MakeArgList(args), |
| reason, |
| extra); |
| - ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
| // Display the action. |
| ObserverMap::const_iterator iter = observers_.find(extension); |
| if (iter != observers_.end()) { |
| @@ -324,6 +312,27 @@ void ActivityLog::LogDOMActionInternal(const Extension* extension, |
| const ListValue* args, |
| const std::string& extra, |
| DOMAction::DOMActionType verb) { |
| + |
| + if (policy_) { |
| + scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); |
| + std::string key; |
| + policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION, key); |
| + details->SetInteger(key, static_cast<int>(verb)); |
| + policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE, key); |
| + details->SetString(key, url_title); |
| + CHECK(extension && "Must pass a valid extension ptr."); |
| + policy_->ProcessAction( |
| + ActivityLogPolicy::ACTION_DOM, |
| + *extension, |
| + api_call, |
| + &url, |
| + args, |
| + details.get()); |
| + } |
| + |
| + |
| + // TODO(felt) Logging should be done more efficiently, so that it |
| + // doesn't require construction of the action object. |
| scoped_refptr<DOMAction> action = new DOMAction( |
| extension->id(), |
| base::Time::Now(), |
| @@ -333,7 +342,6 @@ void ActivityLog::LogDOMActionInternal(const Extension* extension, |
| api_call, |
| MakeArgList(args), |
| extra); |
| - ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
| // Display the action. |
| ObserverMap::const_iterator iter = observers_.find(extension); |
| @@ -374,6 +382,7 @@ void ActivityLog::LogDOMAction(const Extension* extension, |
| } else if (extra == "Method") { |
| action = DOMAction::METHOD; |
| } |
| + |
| LogDOMActionInternal(extension, |
| url, |
| url_title, |
| @@ -404,6 +413,23 @@ void ActivityLog::LogWebRequestAction(const Extension* extension, |
| JSONStringValueSerializer serializer(&details_string); |
| serializer.SerializeAndOmitBinaryValues(*details); |
| + if (policy_) { |
| + scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); |
| + std::string key; |
| + policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DETAILS_STRING, key); |
| + details->SetString(key, details_string); |
| + CHECK(extension && "Must pass a valid extension ptr."); |
| + policy_->ProcessAction( |
| + ActivityLogPolicy::ACTION_WEB_REQUEST, |
| + *extension, |
| + api_call, |
| + &url, |
| + NULL, |
| + details.get()); |
| + } |
| + |
| + // TODO(felt) Logging should be done more efficiently, so that it |
| + // doesn't require construction of the action object. |
| scoped_refptr<DOMAction> action = new DOMAction( |
| extension->id(), |
| base::Time::Now(), |
| @@ -413,7 +439,6 @@ void ActivityLog::LogWebRequestAction(const Extension* extension, |
| api_call, |
| details_string, |
| extra); |
| - ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
| // Display the action. |
| ObserverMap::const_iterator iter = observers_.find(extension); |
| @@ -432,14 +457,9 @@ void ActivityLog::GetActions( |
| const int day, |
| const base::Callback |
| <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
| - BrowserThread::PostTaskAndReplyWithResult( |
| - dispatch_thread_, |
| - FROM_HERE, |
| - base::Bind(&ActivityDatabase::GetActions, |
| - base::Unretained(db_), |
| - extension_id, |
| - day), |
| - callback); |
| + if (policy_) { |
| + policy_->ReadData(extension_id, day, callback); |
| + } |
| } |
| void ActivityLog::OnScriptsExecuted( |
| @@ -478,16 +498,12 @@ void ActivityLog::OnScriptsExecuted( |
| web_contents->GetTitle(), |
| std::string(), // no api call here |
| script_names.get(), |
| - std::string(), // no extras either |
| - DOMAction::INSERTED); |
| + std::string(), |
| + DOMAction::INSERTED); // no extras either |
| } |
| } |
| } |
| -void ActivityLog::KillActivityLogDatabase() { |
| - ScheduleAndForget(&ActivityDatabase::KillDatabase); |
| -} |
| - |
| // static |
| const char* ActivityLog::ActivityToString(Activity activity) { |
| switch (activity) { |