Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <set> | 5 #include <set> |
| 6 #include <vector> | 6 #include <vector> |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/threading/thread_checker.h" | 11 #include "base/threading/thread_checker.h" |
| 12 #include "chrome/browser/extensions/activity_log/activity_log.h" | 12 #include "chrome/browser/extensions/activity_log/activity_log.h" |
| 13 #include "chrome/browser/extensions/activity_log/api_actions.h" | 13 #include "chrome/browser/extensions/activity_log/api_actions.h" |
| 14 #include "chrome/browser/extensions/activity_log/blocked_actions.h" | 14 #include "chrome/browser/extensions/activity_log/blocked_actions.h" |
| 15 #include "chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h" | |
| 15 #include "chrome/browser/extensions/extension_service.h" | 16 #include "chrome/browser/extensions/extension_service.h" |
| 16 #include "chrome/browser/extensions/extension_system.h" | 17 #include "chrome/browser/extensions/extension_system.h" |
| 17 #include "chrome/browser/profiles/incognito_helpers.h" | 18 #include "chrome/browser/profiles/incognito_helpers.h" |
| 18 #include "chrome/common/chrome_constants.h" | 19 #include "chrome/common/chrome_constants.h" |
| 19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/extensions/extension.h" | 21 #include "chrome/common/extensions/extension.h" |
| 21 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
| 22 #include "googleurl/src/gurl.h" | 23 #include "googleurl/src/gurl.h" |
| 23 #include "sql/error_delegate_util.h" | 24 #include "sql/error_delegate_util.h" |
| 24 #include "third_party/re2/re2/re2.h" | 25 #include "third_party/re2/re2/re2.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 // static | 82 // static |
| 82 bool ActivityLog::IsLogEnabled() { | 83 bool ActivityLog::IsLogEnabled() { |
| 83 return LogIsEnabled::GetInstance()->enabled(); | 84 return LogIsEnabled::GetInstance()->enabled(); |
| 84 } | 85 } |
| 85 | 86 |
| 86 // static | 87 // static |
| 87 void ActivityLog::RecomputeLoggingIsEnabled() { | 88 void ActivityLog::RecomputeLoggingIsEnabled() { |
| 88 return LogIsEnabled::GetInstance()->ComputeIsEnabled(); | 89 return LogIsEnabled::GetInstance()->ComputeIsEnabled(); |
| 89 } | 90 } |
| 90 | 91 |
| 91 // This handles errors from the database. | |
| 92 class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate { | |
| 93 public: | |
| 94 explicit KillActivityDatabaseErrorDelegate(ActivityLog* backend) | |
| 95 : backend_(backend), | |
| 96 scheduled_death_(false) {} | |
| 97 | |
| 98 virtual int OnError(int error, | |
| 99 sql::Connection* connection, | |
| 100 sql::Statement* stmt) OVERRIDE { | |
| 101 if (!scheduled_death_ && sql::IsErrorCatastrophic(error)) { | |
| 102 ScheduleDeath(); | |
| 103 } | |
| 104 return error; | |
| 105 } | |
| 106 | |
| 107 // Schedules death if an error wasn't already reported. | |
| 108 void ScheduleDeath() { | |
| 109 if (!scheduled_death_) { | |
| 110 scheduled_death_ = true; | |
| 111 backend_->KillActivityLogDatabase(); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 bool scheduled_death() const { | |
| 116 return scheduled_death_; | |
| 117 } | |
| 118 | |
| 119 private: | |
| 120 ActivityLog* backend_; | |
| 121 bool scheduled_death_; | |
| 122 | |
| 123 DISALLOW_COPY_AND_ASSIGN(KillActivityDatabaseErrorDelegate); | |
| 124 }; | |
| 125 | |
| 126 // ActivityLogFactory | 92 // ActivityLogFactory |
| 127 | 93 |
| 128 ActivityLogFactory* ActivityLogFactory::GetInstance() { | 94 ActivityLogFactory* ActivityLogFactory::GetInstance() { |
| 129 return Singleton<ActivityLogFactory>::get(); | 95 return Singleton<ActivityLogFactory>::get(); |
| 130 } | 96 } |
| 131 | 97 |
| 132 ProfileKeyedService* ActivityLogFactory::BuildServiceInstanceFor( | 98 ProfileKeyedService* ActivityLogFactory::BuildServiceInstanceFor( |
| 133 content::BrowserContext* profile) const { | 99 content::BrowserContext* profile) const { |
| 134 return new ActivityLog(static_cast<Profile*>(profile)); | 100 return new ActivityLog(static_cast<Profile*>(profile)); |
| 135 } | 101 } |
| 136 | 102 |
| 137 content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse( | 103 content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse( |
| 138 content::BrowserContext* context) const { | 104 content::BrowserContext* context) const { |
| 139 return chrome::GetBrowserContextRedirectedInIncognito(context); | 105 return chrome::GetBrowserContextRedirectedInIncognito(context); |
| 140 } | 106 } |
| 141 | 107 |
| 142 // ActivityLog | 108 // ActivityLog |
| 143 | 109 |
| 144 // Use GetInstance instead of directly creating an ActivityLog. | 110 // Use GetInstance instead of directly creating an ActivityLog. |
| 145 ActivityLog::ActivityLog(Profile* profile) : profile_(profile) { | 111 ActivityLog::ActivityLog(Profile* profile) : policy_(NULL), profile_(profile) { |
| 146 // enable-extension-activity-logging and enable-extension-activity-ui | 112 // enable-extension-activity-logging and enable-extension-activity-ui |
| 147 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()->HasSwitch( | 113 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| 148 switches::kEnableExtensionActivityLogging); | 114 switches::kEnableExtensionActivityLogging); |
| 149 log_activity_to_ui_ = CommandLine::ForCurrentProcess()->HasSwitch( | 115 log_activity_to_ui_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| 150 switches::kEnableExtensionActivityUI); | 116 switches::kEnableExtensionActivityUI); |
| 151 | 117 |
| 152 // enable-extension-activity-log-testing | 118 // enable-extension-activity-log-testing |
| 153 // This controls whether arguments are collected. | 119 // This controls whether arguments are collected. |
| 154 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( | 120 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| 155 switches::kEnableExtensionActivityLogTesting); | 121 switches::kEnableExtensionActivityLogTesting); |
| 156 if (!testing_mode_) { | 122 if (!testing_mode_) { |
| 157 for (int i = 0; i < APIAction::kSizeAlwaysLog; i++) { | 123 for (int i = 0; i < APIAction::kSizeAlwaysLog; i++) { |
| 158 arg_whitelist_api_.insert(std::string(APIAction::kAlwaysLog[i])); | 124 arg_whitelist_api_.insert(std::string(APIAction::kAlwaysLog[i])); |
| 159 } | 125 } |
| 160 } | 126 } |
| 161 | 127 |
| 162 // We normally dispatch DB requests to the DB thread, but the thread might | 128 // TODO(dbabic) In the next iteration, we should support multiple policies, |
| 163 // not exist if we are under test conditions. Substitute the UI thread for | 129 // which are then polled by the ActivityLog object |
| 164 // this case. | 130 if (IsLogEnabled()){ |
| 165 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) { | 131 if (testing_mode_) { |
| 166 dispatch_thread_ = BrowserThread::DB; | 132 policy_ = new FullStreamUIPolicy(profile); |
| 167 } else { | 133 } else { |
| 168 LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!"; | 134 policy_ = new StreamWithoutArgsUIPolicy(profile); |
| 169 dispatch_thread_ = BrowserThread::UI; | 135 } |
| 170 } | 136 } |
| 171 | |
| 172 // If the database cannot be initialized for some reason, we keep | |
| 173 // chugging along but nothing will get recorded. If the UI is | |
| 174 // available, things will still get sent to the UI even if nothing | |
| 175 // is being written to the database. | |
| 176 db_ = new ActivityDatabase(); | |
| 177 if (!IsLogEnabled()) return; | |
| 178 base::FilePath base_dir = profile->GetPath(); | |
| 179 base::FilePath database_name = base_dir.Append( | |
| 180 chrome::kExtensionActivityLogFilename); | |
| 181 KillActivityDatabaseErrorDelegate* error_delegate = | |
| 182 new KillActivityDatabaseErrorDelegate(this); | |
| 183 db_->SetErrorDelegate(error_delegate); | |
| 184 ScheduleAndForget(&ActivityDatabase::Init, database_name); | |
| 185 } | 137 } |
| 186 | 138 |
| 187 ActivityLog::~ActivityLog() { | 139 ActivityLog::~ActivityLog() { |
| 188 ScheduleAndForget(&ActivityDatabase::Close); | 140 delete policy_; |
| 189 } | 141 } |
| 190 | 142 |
| 191 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { | 143 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { |
| 192 testing_mode_ = log_arguments; | 144 testing_mode_ = log_arguments; |
| 193 } | 145 } |
| 194 | 146 |
| 195 // static | 147 // static |
| 196 ActivityLog* ActivityLog::GetInstance(Profile* profile) { | 148 ActivityLog* ActivityLog::GetInstance(Profile* profile) { |
| 197 return ActivityLogFactory::GetForProfile(profile); | 149 return ActivityLogFactory::GetForProfile(profile); |
| 198 } | 150 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 215 const std::string& api_call, | 167 const std::string& api_call, |
| 216 ListValue* args, | 168 ListValue* args, |
| 217 const std::string& extra, | 169 const std::string& extra, |
| 218 const APIAction::Type type) { | 170 const APIAction::Type type) { |
| 219 std::string verb, manager; | 171 std::string verb, manager; |
| 220 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); | 172 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); |
| 221 if (matches) { | 173 if (matches) { |
| 222 if (!args->empty() && manager == "tabs") { | 174 if (!args->empty() && manager == "tabs") { |
| 223 APIAction::LookupTabId(api_call, args, profile_); | 175 APIAction::LookupTabId(api_call, args, profile_); |
| 224 } | 176 } |
| 177 | |
| 178 if (policy_) { | |
| 179 DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) && | |
| 180 "Unexpected APIAction call type."); | |
| 181 CHECK(extension && "Must pass a valid extension ptr."); | |
| 182 policy_->ProcessAction( | |
| 183 type == APIAction::CALL ? ActivityLogPolicy::ACTION_API : | |
| 184 ActivityLogPolicy::ACTION_EVENT, | |
| 185 *extension, | |
| 186 api_call, | |
| 187 NULL, | |
| 188 args, | |
| 189 NULL); | |
| 190 } | |
| 191 | |
| 192 // TODO(felt) Logging should be done more efficiently, so that it | |
| 193 // doesn't require construction of the action object. | |
| 225 scoped_refptr<APIAction> action = new APIAction( | 194 scoped_refptr<APIAction> action = new APIAction( |
| 226 extension->id(), | 195 extension->id(), |
| 227 base::Time::Now(), | 196 base::Time::Now(), |
| 228 type, | 197 type, |
| 229 api_call, | 198 api_call, |
| 230 MakeArgList(args), | 199 MakeArgList(args), |
| 231 extra); | 200 extra); |
| 232 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 233 | 201 |
| 234 // Display the action. | 202 // Display the action. |
| 235 ObserverMap::const_iterator iter = observers_.find(extension); | 203 ObserverMap::const_iterator iter = observers_.find(extension); |
| 236 if (iter != observers_.end()) { | 204 if (iter != observers_.end()) { |
| 237 if (type == APIAction::CALL) { | 205 if (type == APIAction::CALL) { |
| 238 iter->second->Notify(&Observer::OnExtensionActivity, | 206 iter->second->Notify(&Observer::OnExtensionActivity, |
| 239 extension, | 207 extension, |
| 240 ActivityLog::ACTIVITY_EXTENSION_API_CALL, | 208 ActivityLog::ACTIVITY_EXTENSION_API_CALL, |
| 241 MakeCallSignature(api_call, args)); | 209 MakeCallSignature(api_call, args)); |
| 242 } else if (type == APIAction::EVENT_CALLBACK) { | 210 } else if (type == APIAction::EVENT_CALLBACK) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 253 } | 221 } |
| 254 } | 222 } |
| 255 | 223 |
| 256 // A wrapper around LogAPIActionInternal, but we know it's an API call. | 224 // A wrapper around LogAPIActionInternal, but we know it's an API call. |
| 257 void ActivityLog::LogAPIAction(const Extension* extension, | 225 void ActivityLog::LogAPIAction(const Extension* extension, |
| 258 const std::string& api_call, | 226 const std::string& api_call, |
| 259 ListValue* args, | 227 ListValue* args, |
| 260 const std::string& extra) { | 228 const std::string& extra) { |
| 261 if (!IsLogEnabled()) return; | 229 if (!IsLogEnabled()) return; |
| 262 if (!testing_mode_ && | 230 if (!testing_mode_ && |
| 263 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | 231 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) { |
| 264 args->Clear(); | 232 args->Clear(); |
| 233 } | |
| 265 LogAPIActionInternal(extension, | 234 LogAPIActionInternal(extension, |
| 266 api_call, | 235 api_call, |
| 267 args, | 236 args, |
| 268 extra, | 237 extra, |
| 269 APIAction::CALL); | 238 APIAction::CALL); |
| 270 } | 239 } |
| 271 | 240 |
| 272 // A wrapper around LogAPIActionInternal, but we know it's actually an event | 241 // A wrapper around LogAPIActionInternal, but we know it's actually an event |
| 273 // being fired and triggering extension code. Having the two separate methods | 242 // being fired and triggering extension code. Having the two separate methods |
| 274 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to | 243 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to |
| 275 // handle them. Right now they're being handled almost the same. | 244 // handle them. Right now they're being handled almost the same. |
| 276 void ActivityLog::LogEventAction(const Extension* extension, | 245 void ActivityLog::LogEventAction(const Extension* extension, |
| 277 const std::string& api_call, | 246 const std::string& api_call, |
| 278 ListValue* args, | 247 ListValue* args, |
| 279 const std::string& extra) { | 248 const std::string& extra) { |
| 280 if (!IsLogEnabled()) return; | 249 if (!IsLogEnabled()) return; |
| 281 if (!testing_mode_ && | 250 if (!testing_mode_ && |
| 282 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | 251 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) { |
| 283 args->Clear(); | 252 args->Clear(); |
| 253 } | |
| 284 LogAPIActionInternal(extension, | 254 LogAPIActionInternal(extension, |
| 285 api_call, | 255 api_call, |
| 286 args, | 256 args, |
| 287 extra, | 257 extra, |
| 288 APIAction::EVENT_CALLBACK); | 258 APIAction::EVENT_CALLBACK); |
| 289 } | 259 } |
| 290 | 260 |
| 291 void ActivityLog::LogBlockedAction(const Extension* extension, | 261 void ActivityLog::LogBlockedAction(const Extension* extension, |
| 292 const std::string& blocked_call, | 262 const std::string& blocked_call, |
| 293 ListValue* args, | 263 ListValue* args, |
| 294 BlockedAction::Reason reason, | 264 BlockedAction::Reason reason, |
| 295 const std::string& extra) { | 265 const std::string& extra) { |
| 296 if (!IsLogEnabled()) return; | 266 if (!IsLogEnabled()) return; |
| 297 if (!testing_mode_ && | 267 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.
| |
| 298 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) | 268 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) { |
| 299 args->Clear(); | 269 args->Clear(); |
| 270 } | |
| 271 | |
| 272 if (policy_) { | |
| 273 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | |
| 274 std::string key; | |
| 275 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON, key); | |
| 276 details->SetInteger(key, static_cast<int>(reason)); | |
| 277 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.
| |
| 278 policy_->ProcessAction( | |
| 279 ActivityLogPolicy::ACTION_BLOCKED, | |
| 280 *extension, | |
| 281 blocked_call, | |
| 282 NULL, | |
| 283 args, | |
| 284 details.get()); | |
| 285 } | |
| 286 | |
| 287 // TODO(felt) Logging should be done more efficiently, so that it | |
| 288 // 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.
| |
| 300 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), | 289 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), |
| 301 base::Time::Now(), | 290 base::Time::Now(), |
| 302 blocked_call, | 291 blocked_call, |
| 303 MakeArgList(args), | 292 MakeArgList(args), |
| 304 reason, | 293 reason, |
| 305 extra); | 294 extra); |
| 306 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 307 // Display the action. | 295 // Display the action. |
| 308 ObserverMap::const_iterator iter = observers_.find(extension); | 296 ObserverMap::const_iterator iter = observers_.find(extension); |
| 309 if (iter != observers_.end()) { | 297 if (iter != observers_.end()) { |
| 310 std::string blocked_str = MakeCallSignature(blocked_call, args); | 298 std::string blocked_str = MakeCallSignature(blocked_call, args); |
| 311 iter->second->Notify(&Observer::OnExtensionActivity, | 299 iter->second->Notify(&Observer::OnExtensionActivity, |
| 312 extension, | 300 extension, |
| 313 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, | 301 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, |
| 314 blocked_str); | 302 blocked_str); |
| 315 } | 303 } |
| 316 if (log_activity_to_stdout_) | 304 if (log_activity_to_stdout_) |
| 317 LOG(INFO) << action->PrintForDebug(); | 305 LOG(INFO) << action->PrintForDebug(); |
| 318 } | 306 } |
| 319 | 307 |
| 320 void ActivityLog::LogDOMActionInternal(const Extension* extension, | 308 void ActivityLog::LogDOMActionInternal(const Extension* extension, |
| 321 const GURL& url, | 309 const GURL& url, |
| 322 const string16& url_title, | 310 const string16& url_title, |
| 323 const std::string& api_call, | 311 const std::string& api_call, |
| 324 const ListValue* args, | 312 const ListValue* args, |
| 325 const std::string& extra, | 313 const std::string& extra, |
| 326 DOMAction::DOMActionType verb) { | 314 DOMAction::DOMActionType verb) { |
| 315 | |
| 316 if (policy_) { | |
| 317 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | |
| 318 std::string key; | |
| 319 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION, key); | |
| 320 details->SetInteger(key, static_cast<int>(verb)); | |
| 321 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE, key); | |
| 322 details->SetString(key, url_title); | |
| 323 CHECK(extension && "Must pass a valid extension ptr."); | |
| 324 policy_->ProcessAction( | |
| 325 ActivityLogPolicy::ACTION_DOM, | |
| 326 *extension, | |
| 327 api_call, | |
| 328 &url, | |
| 329 args, | |
| 330 details.get()); | |
| 331 } | |
| 332 | |
| 333 | |
| 334 // TODO(felt) Logging should be done more efficiently, so that it | |
| 335 // doesn't require construction of the action object. | |
| 327 scoped_refptr<DOMAction> action = new DOMAction( | 336 scoped_refptr<DOMAction> action = new DOMAction( |
| 328 extension->id(), | 337 extension->id(), |
| 329 base::Time::Now(), | 338 base::Time::Now(), |
| 330 verb, | 339 verb, |
| 331 url, | 340 url, |
| 332 url_title, | 341 url_title, |
| 333 api_call, | 342 api_call, |
| 334 MakeArgList(args), | 343 MakeArgList(args), |
| 335 extra); | 344 extra); |
| 336 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 337 | 345 |
| 338 // Display the action. | 346 // Display the action. |
| 339 ObserverMap::const_iterator iter = observers_.find(extension); | 347 ObserverMap::const_iterator iter = observers_.find(extension); |
| 340 if (iter != observers_.end()) { | 348 if (iter != observers_.end()) { |
| 341 // TODO(felt): This is a kludge, planning to update this when new | 349 // TODO(felt): This is a kludge, planning to update this when new |
| 342 // UI is in place. | 350 // UI is in place. |
| 343 if (verb == DOMAction::INSERTED) { | 351 if (verb == DOMAction::INSERTED) { |
| 344 iter->second->Notify(&Observer::OnExtensionActivity, | 352 iter->second->Notify(&Observer::OnExtensionActivity, |
| 345 extension, | 353 extension, |
| 346 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | 354 ActivityLog::ACTIVITY_CONTENT_SCRIPT, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 367 if (extra == "Getter") { | 375 if (extra == "Getter") { |
| 368 action = DOMAction::GETTER; | 376 action = DOMAction::GETTER; |
| 369 } else if (extra == "Setter") { | 377 } else if (extra == "Setter") { |
| 370 action = DOMAction::SETTER; | 378 action = DOMAction::SETTER; |
| 371 } else if (api_call == "XMLHttpRequest.open") { | 379 } else if (api_call == "XMLHttpRequest.open") { |
| 372 // Has to come before the Method check because XHR is also a Method. | 380 // Has to come before the Method check because XHR is also a Method. |
| 373 action = DOMAction::XHR; | 381 action = DOMAction::XHR; |
| 374 } else if (extra == "Method") { | 382 } else if (extra == "Method") { |
| 375 action = DOMAction::METHOD; | 383 action = DOMAction::METHOD; |
| 376 } | 384 } |
| 385 | |
| 377 LogDOMActionInternal(extension, | 386 LogDOMActionInternal(extension, |
| 378 url, | 387 url, |
| 379 url_title, | 388 url_title, |
| 380 api_call, | 389 api_call, |
| 381 args, | 390 args, |
| 382 extra, | 391 extra, |
| 383 action); | 392 action); |
| 384 } | 393 } |
| 385 | 394 |
| 386 void ActivityLog::LogWebRequestAction(const Extension* extension, | 395 void ActivityLog::LogWebRequestAction(const Extension* extension, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 397 DictionaryValue::Iterator details_iterator(*details); | 406 DictionaryValue::Iterator details_iterator(*details); |
| 398 while (!details_iterator.IsAtEnd()) { | 407 while (!details_iterator.IsAtEnd()) { |
| 399 details->SetBoolean(details_iterator.key(), true); | 408 details->SetBoolean(details_iterator.key(), true); |
| 400 details_iterator.Advance(); | 409 details_iterator.Advance(); |
| 401 } | 410 } |
| 402 } | 411 } |
| 403 std::string details_string; | 412 std::string details_string; |
| 404 JSONStringValueSerializer serializer(&details_string); | 413 JSONStringValueSerializer serializer(&details_string); |
| 405 serializer.SerializeAndOmitBinaryValues(*details); | 414 serializer.SerializeAndOmitBinaryValues(*details); |
| 406 | 415 |
| 416 if (policy_) { | |
| 417 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | |
| 418 std::string key; | |
| 419 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DETAILS_STRING, key); | |
| 420 details->SetString(key, details_string); | |
| 421 CHECK(extension && "Must pass a valid extension ptr."); | |
| 422 policy_->ProcessAction( | |
| 423 ActivityLogPolicy::ACTION_WEB_REQUEST, | |
| 424 *extension, | |
| 425 api_call, | |
| 426 &url, | |
| 427 NULL, | |
| 428 details.get()); | |
| 429 } | |
| 430 | |
| 431 // TODO(felt) Logging should be done more efficiently, so that it | |
| 432 // doesn't require construction of the action object. | |
| 407 scoped_refptr<DOMAction> action = new DOMAction( | 433 scoped_refptr<DOMAction> action = new DOMAction( |
| 408 extension->id(), | 434 extension->id(), |
| 409 base::Time::Now(), | 435 base::Time::Now(), |
| 410 DOMAction::WEBREQUEST, | 436 DOMAction::WEBREQUEST, |
| 411 url, | 437 url, |
| 412 null_title, | 438 null_title, |
| 413 api_call, | 439 api_call, |
| 414 details_string, | 440 details_string, |
| 415 extra); | 441 extra); |
| 416 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 417 | 442 |
| 418 // Display the action. | 443 // Display the action. |
| 419 ObserverMap::const_iterator iter = observers_.find(extension); | 444 ObserverMap::const_iterator iter = observers_.find(extension); |
| 420 if (iter != observers_.end()) { | 445 if (iter != observers_.end()) { |
| 421 iter->second->Notify(&Observer::OnExtensionActivity, | 446 iter->second->Notify(&Observer::OnExtensionActivity, |
| 422 extension, | 447 extension, |
| 423 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | 448 ActivityLog::ACTIVITY_CONTENT_SCRIPT, |
| 424 action->PrintForDebug()); | 449 action->PrintForDebug()); |
| 425 } | 450 } |
| 426 if (log_activity_to_stdout_) | 451 if (log_activity_to_stdout_) |
| 427 LOG(INFO) << action->PrintForDebug(); | 452 LOG(INFO) << action->PrintForDebug(); |
| 428 } | 453 } |
| 429 | 454 |
| 430 void ActivityLog::GetActions( | 455 void ActivityLog::GetActions( |
| 431 const std::string& extension_id, | 456 const std::string& extension_id, |
| 432 const int day, | 457 const int day, |
| 433 const base::Callback | 458 const base::Callback |
| 434 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { | 459 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
| 435 BrowserThread::PostTaskAndReplyWithResult( | 460 if (policy_) { |
| 436 dispatch_thread_, | 461 policy_->ReadData(extension_id, day, callback); |
| 437 FROM_HERE, | 462 } |
| 438 base::Bind(&ActivityDatabase::GetActions, | |
| 439 base::Unretained(db_), | |
| 440 extension_id, | |
| 441 day), | |
| 442 callback); | |
| 443 } | 463 } |
| 444 | 464 |
| 445 void ActivityLog::OnScriptsExecuted( | 465 void ActivityLog::OnScriptsExecuted( |
| 446 const content::WebContents* web_contents, | 466 const content::WebContents* web_contents, |
| 447 const ExecutingScriptsMap& extension_ids, | 467 const ExecutingScriptsMap& extension_ids, |
| 448 int32 on_page_id, | 468 int32 on_page_id, |
| 449 const GURL& on_url) { | 469 const GURL& on_url) { |
| 450 if (!IsLogEnabled()) return; | 470 if (!IsLogEnabled()) return; |
| 451 Profile* profile = | 471 Profile* profile = |
| 452 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 472 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 471 ext_scripts_str += *it2; | 491 ext_scripts_str += *it2; |
| 472 ext_scripts_str += " "; | 492 ext_scripts_str += " "; |
| 473 } | 493 } |
| 474 scoped_ptr<ListValue> script_names(new ListValue()); | 494 scoped_ptr<ListValue> script_names(new ListValue()); |
| 475 script_names->Set(0, new StringValue(ext_scripts_str)); | 495 script_names->Set(0, new StringValue(ext_scripts_str)); |
| 476 LogDOMActionInternal(extension, | 496 LogDOMActionInternal(extension, |
| 477 on_url, | 497 on_url, |
| 478 web_contents->GetTitle(), | 498 web_contents->GetTitle(), |
| 479 std::string(), // no api call here | 499 std::string(), // no api call here |
| 480 script_names.get(), | 500 script_names.get(), |
| 481 std::string(), // no extras either | 501 std::string(), |
| 482 DOMAction::INSERTED); | 502 DOMAction::INSERTED); // no extras either |
| 483 } | 503 } |
| 484 } | 504 } |
| 485 } | 505 } |
| 486 | 506 |
| 487 void ActivityLog::KillActivityLogDatabase() { | |
| 488 ScheduleAndForget(&ActivityDatabase::KillDatabase); | |
| 489 } | |
| 490 | |
| 491 // static | 507 // static |
| 492 const char* ActivityLog::ActivityToString(Activity activity) { | 508 const char* ActivityLog::ActivityToString(Activity activity) { |
| 493 switch (activity) { | 509 switch (activity) { |
| 494 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: | 510 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: |
| 495 return "api_call"; | 511 return "api_call"; |
| 496 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: | 512 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: |
| 497 return "api_block"; | 513 return "api_block"; |
| 498 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: | 514 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: |
| 499 return "content_script"; | 515 return "content_script"; |
| 500 case ActivityLog::ACTIVITY_EVENT_DISPATCH: | 516 case ActivityLog::ACTIVITY_EVENT_DISPATCH: |
| 501 return "event_dispatch"; | 517 return "event_dispatch"; |
| 502 default: | 518 default: |
| 503 NOTREACHED(); | 519 NOTREACHED(); |
| 504 return ""; | 520 return ""; |
| 505 } | 521 } |
| 506 } | 522 } |
| 507 | 523 |
| 508 } // namespace extensions | 524 } // namespace extensions |
| OLD | NEW |