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/strings/string_util.h" | 10 #include "base/strings/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/api/activity_log_private/activity_log_privat e_api.h" | 16 #include "chrome/browser/extensions/api/activity_log_private/activity_log_privat e_api.h" |
| 16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 17 #include "chrome/browser/extensions/extension_system.h" | 18 #include "chrome/browser/extensions/extension_system.h" |
| 18 #include "chrome/browser/extensions/extension_system_factory.h" | 19 #include "chrome/browser/extensions/extension_system_factory.h" |
| 19 #include "chrome/browser/extensions/install_tracker_factory.h" | 20 #include "chrome/browser/extensions/install_tracker_factory.h" |
| 20 #include "chrome/browser/prerender/prerender_manager.h" | 21 #include "chrome/browser/prerender/prerender_manager.h" |
| 21 #include "chrome/browser/prerender/prerender_manager_factory.h" | 22 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| 22 #include "chrome/browser/profiles/incognito_helpers.h" | 23 #include "chrome/browser/profiles/incognito_helpers.h" |
| 23 #include "chrome/common/chrome_constants.h" | 24 #include "chrome/common/chrome_constants.h" |
| 24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 BrowserContextDependencyManager::GetInstance()) { | 122 BrowserContextDependencyManager::GetInstance()) { |
| 122 DependsOn(ExtensionSystemFactory::GetInstance()); | 123 DependsOn(ExtensionSystemFactory::GetInstance()); |
| 123 DependsOn(InstallTrackerFactory::GetInstance()); | 124 DependsOn(InstallTrackerFactory::GetInstance()); |
| 124 } | 125 } |
| 125 | 126 |
| 126 ActivityLogFactory::~ActivityLogFactory() { | 127 ActivityLogFactory::~ActivityLogFactory() { |
| 127 } | 128 } |
| 128 | 129 |
| 129 // ActivityLog | 130 // ActivityLog |
| 130 | 131 |
| 132 void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) { | |
| 133 if (policy_type != policy_type_ && IsLogEnabled()) { | |
| 134 delete policy_; | |
| 135 | |
| 136 // We normally dispatch DB requests to the DB thread, but the thread might | |
| 137 // not exist if we are under test conditions. Substitute the UI thread for | |
| 138 // this case. | |
| 139 content::BrowserThread::ID dispatch_thread; | |
| 140 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) { | |
| 141 dispatch_thread = BrowserThread::DB; | |
| 142 } else { | |
| 143 LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!"; | |
| 144 dispatch_thread = BrowserThread::UI; | |
| 145 } | |
| 146 | |
| 147 switch (policy_type) { | |
| 148 case ActivityLogPolicy::POLICY_FULLSTREAM: | |
| 149 policy_ = new FullStreamUIPolicy(profile_, dispatch_thread); | |
| 150 break; | |
| 151 case ActivityLogPolicy::POLICY_NOARGS: | |
| 152 policy_ = new StreamWithoutArgsUIPolicy(profile_, dispatch_thread); | |
| 153 break; | |
| 154 default: | |
| 155 if (testing_mode_) | |
| 156 LOG(INFO) << "Calling SetDefaultPolicy with invalid policy type?"; | |
| 157 } | |
| 158 policy_type_ = policy_type; | |
| 159 } | |
| 160 } | |
| 161 | |
| 131 // Use GetInstance instead of directly creating an ActivityLog. | 162 // Use GetInstance instead of directly creating an ActivityLog. |
| 132 ActivityLog::ActivityLog(Profile* profile) | 163 ActivityLog::ActivityLog(Profile* profile) |
| 133 : profile_(profile), | 164 : policy_type_(ActivityLogPolicy::POLICY_INVALID), |
| 165 profile_(profile), | |
| 134 first_time_checking_(true), | 166 first_time_checking_(true), |
| 135 tracker_(NULL), | 167 has_threads_(true), |
| 136 has_threads_(true) { | 168 tracker_(NULL) { |
| 137 enabled_ = IsLogEnabledOnAnyProfile(); | 169 enabled_ = IsLogEnabledOnAnyProfile(); |
| 138 | 170 |
| 139 // enable-extension-activity-log-testing | |
| 140 // This controls whether arguments are collected. | |
| 141 // It also controls whether logging statements are printed. | |
| 142 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 143 switches::kEnableExtensionActivityLogTesting); | |
| 144 if (!testing_mode_) { | |
| 145 for (int i = 0; i < APIAction::kSizeAlwaysLog; i++) { | |
| 146 arg_whitelist_api_.insert(std::string(APIAction::kAlwaysLog[i])); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 // Check that the right threads exist. If not, we shouldn't try to do things | 171 // Check that the right threads exist. If not, we shouldn't try to do things |
| 151 // that require them. | 172 // that require them. |
|
felt
2013/06/13 18:52:02
This code was being used to control whether we dis
dbabic
2013/06/13 23:10:08
If has_threads_ is false, IsLogEnabled() will retu
felt
2013/06/13 23:23:37
Hmm... originally I had meant for IsLogEnabled to
dbabic
2013/06/14 00:30:37
Ok.
| |
| 152 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || | 173 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || |
| 153 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || | 174 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || |
| 154 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { | 175 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { |
| 155 LOG(ERROR) << "Missing threads, disabling Activity Logging!"; | 176 LOG(ERROR) << "Missing threads, disabling Activity Logging!"; |
| 156 has_threads_ = false; | 177 has_threads_ = false; |
| 157 } | 178 } |
| 158 | 179 |
| 180 // enable-extension-activity-log-testing | |
| 181 // This controls whether arguments are collected. | |
| 182 // It also controls whether logging statements are printed. | |
| 183 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 184 switches::kEnableExtensionActivityLogTesting); | |
| 185 if (!testing_mode_) { | |
| 186 SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS); | |
| 187 } else { | |
| 188 SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); | |
| 189 } | |
| 190 | |
| 159 observers_ = new ObserverListThreadSafe<Observer>; | 191 observers_ = new ObserverListThreadSafe<Observer>; |
| 160 | |
| 161 // We initialize the database whether or not the AL is enabled, since we might | |
| 162 // be enabled later on. If the database cannot be initialized for some | |
| 163 // reason, we keep chugging along but nothing will get recorded. If the UI is | |
| 164 // available, things will still get sent to the UI even if nothing | |
| 165 // is being written to the database. | |
| 166 db_ = new ActivityDatabase(); | |
| 167 if (!has_threads_) return; | |
| 168 base::FilePath base_dir = profile->GetPath(); | |
| 169 base::FilePath database_name = base_dir.Append( | |
| 170 chrome::kExtensionActivityLogFilename); | |
| 171 ScheduleAndForget(&ActivityDatabase::Init, database_name); | |
| 172 } | 192 } |
| 173 | 193 |
| 174 void ActivityLog::Shutdown() { | 194 void ActivityLog::Shutdown() { |
| 175 if (!first_time_checking_ && tracker_) tracker_->RemoveObserver(this); | 195 if (!first_time_checking_ && tracker_) tracker_->RemoveObserver(this); |
| 176 } | 196 } |
| 177 | 197 |
| 178 ActivityLog::~ActivityLog() { | 198 ActivityLog::~ActivityLog() { |
| 179 if (has_threads_) | 199 delete policy_; |
| 180 ScheduleAndForget(&ActivityDatabase::Close); | |
| 181 else | |
| 182 db_->Close(); | |
| 183 } | 200 } |
| 184 | 201 |
| 185 // We can't register for the InstallTrackerFactory events or talk to the | 202 // We can't register for the InstallTrackerFactory events or talk to the |
| 186 // extension service in the constructor, so we do that here the first time | 203 // extension service in the constructor, so we do that here the first time |
| 187 // this is called (as identified by first_time_checking_). | 204 // this is called (as identified by first_time_checking_). |
| 188 bool ActivityLog::IsLogEnabled() { | 205 bool ActivityLog::IsLogEnabled() { |
| 189 if (!first_time_checking_) return enabled_; | 206 if (!first_time_checking_) return enabled_; |
| 190 if (!has_threads_) return false; | 207 if (!has_threads_) return false; |
| 191 tracker_ = InstallTrackerFactory::GetForProfile(profile_); | 208 tracker_ = InstallTrackerFactory::GetForProfile(profile_); |
| 192 tracker_->AddObserver(this); | 209 tracker_->AddObserver(this); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 219 // is reenabled. | 236 // is reenabled. |
| 220 void ActivityLog::OnExtensionDisabled(const Extension* extension) { | 237 void ActivityLog::OnExtensionDisabled(const Extension* extension) { |
| 221 if (extension->id() != kActivityLogExtensionId) return; | 238 if (extension->id() != kActivityLogExtensionId) return; |
| 222 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 239 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 223 switches::kEnableExtensionActivityLogging)) | 240 switches::kEnableExtensionActivityLogging)) |
| 224 enabled_ = false; | 241 enabled_ = false; |
| 225 } | 242 } |
| 226 | 243 |
| 227 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { | 244 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { |
| 228 testing_mode_ = log_arguments; | 245 testing_mode_ = log_arguments; |
| 246 /* | |
| 247 ===== | |
| 248 delete policy_; | |
| 249 >>>>> approved-policy-patch | |
| 250 // */ | |
|
Matt Perry
2013/06/13 18:23:23
merge junk
dbabic
2013/06/13 23:10:08
Done.
| |
| 229 } | 251 } |
| 230 | 252 |
| 231 // static | 253 // static |
| 232 ActivityLog* ActivityLog::GetInstance(Profile* profile) { | 254 ActivityLog* ActivityLog::GetInstance(Profile* profile) { |
| 233 return ActivityLogFactory::GetForProfile(profile); | 255 return ActivityLogFactory::GetForProfile(profile); |
| 234 } | 256 } |
| 235 | 257 |
| 236 void ActivityLog::AddObserver(ActivityLog::Observer* observer) { | 258 void ActivityLog::AddObserver(ActivityLog::Observer* observer) { |
| 237 observers_->AddObserver(observer); | 259 observers_->AddObserver(observer); |
| 238 } | 260 } |
| 239 | 261 |
| 240 void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { | 262 void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { |
| 241 observers_->RemoveObserver(observer); | 263 observers_->RemoveObserver(observer); |
| 242 } | 264 } |
| 243 | 265 |
| 244 void ActivityLog::LogAPIActionInternal(const std::string& extension_id, | 266 void ActivityLog::LogAPIActionInternal(const std::string& extension_id, |
| 245 const std::string& api_call, | 267 const std::string& api_call, |
| 246 ListValue* args, | 268 ListValue* args, |
| 247 const std::string& extra, | 269 const std::string& extra, |
| 248 const APIAction::Type type) { | 270 const APIAction::Type type) { |
| 249 std::string verb, manager; | 271 std::string verb, manager; |
| 250 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); | 272 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); |
| 251 if (matches) { | 273 if (matches) { |
| 252 if (!args->empty() && manager == "tabs") { | 274 if (!args->empty() && manager == "tabs") { |
| 253 APIAction::LookupTabId(api_call, args, profile_); | 275 APIAction::LookupTabId(api_call, args, profile_); |
| 254 } | 276 } |
| 277 | |
| 278 if (policy_) { | |
| 279 DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) && | |
| 280 "Unexpected APIAction call type."); | |
| 281 policy_->ProcessAction( | |
| 282 type == APIAction::CALL ? ActivityLogPolicy::ACTION_API : | |
| 283 ActivityLogPolicy::ACTION_EVENT, | |
| 284 extension_id, | |
| 285 api_call, | |
| 286 NULL, | |
| 287 args, | |
| 288 NULL); | |
|
felt
2013/06/13 18:52:02
Note that we've started using the extra fields so
dbabic
2013/06/13 23:10:08
Done.
| |
| 289 } | |
| 290 | |
| 291 // TODO(felt) Logging should be done more efficiently, so that it | |
| 292 // doesn't require construction of the action object. | |
| 255 scoped_refptr<APIAction> action = new APIAction( | 293 scoped_refptr<APIAction> action = new APIAction( |
| 256 extension_id, | 294 extension_id, |
| 257 base::Time::Now(), | 295 base::Time::Now(), |
| 258 type, | 296 type, |
| 259 api_call, | 297 api_call, |
| 260 MakeArgList(args), | 298 MakeArgList(args), |
| 261 extra); | 299 extra); |
| 262 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 300 |
| 263 observers_->Notify(&Observer::OnExtensionActivity, action); | 301 observers_->Notify(&Observer::OnExtensionActivity, action); |
| 264 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | 302 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); |
| 265 } else { | 303 } else { |
| 266 LOG(ERROR) << "Unknown API call! " << api_call; | 304 LOG(ERROR) << "Unknown API call! " << api_call; |
| 267 } | 305 } |
| 268 } | 306 } |
| 269 | 307 |
| 270 // A wrapper around LogAPIActionInternal, but we know it's an API call. | 308 // A wrapper around LogAPIActionInternal, but we know it's an API call. |
| 271 void ActivityLog::LogAPIAction(const std::string& extension_id, | 309 void ActivityLog::LogAPIAction(const std::string& extension_id, |
| 272 const std::string& api_call, | 310 const std::string& api_call, |
| 273 ListValue* args, | 311 ListValue* args, |
| 274 const std::string& extra) { | 312 const std::string& extra) { |
| 275 if (!IsLogEnabled() || | 313 if (!IsLogEnabled() || |
| 276 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 314 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 277 if (!testing_mode_ && | |
| 278 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | |
| 279 args->Clear(); | |
| 280 LogAPIActionInternal(extension_id, | 315 LogAPIActionInternal(extension_id, |
| 281 api_call, | 316 api_call, |
| 282 args, | 317 args, |
| 283 extra, | 318 extra, |
| 284 APIAction::CALL); | 319 APIAction::CALL); |
| 285 } | 320 } |
| 286 | 321 |
| 287 // A wrapper around LogAPIActionInternal, but we know it's actually an event | 322 // A wrapper around LogAPIActionInternal, but we know it's actually an event |
| 288 // being fired and triggering extension code. Having the two separate methods | 323 // being fired and triggering extension code. Having the two separate methods |
| 289 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to | 324 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to |
| 290 // handle them. Right now they're being handled almost the same. | 325 // handle them. Right now they're being handled almost the same. |
| 291 void ActivityLog::LogEventAction(const std::string& extension_id, | 326 void ActivityLog::LogEventAction(const std::string& extension_id, |
| 292 const std::string& api_call, | 327 const std::string& api_call, |
| 293 ListValue* args, | 328 ListValue* args, |
| 294 const std::string& extra) { | 329 const std::string& extra) { |
| 295 if (!IsLogEnabled() || | 330 if (!IsLogEnabled() || |
| 296 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 331 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 297 if (!testing_mode_ && | |
| 298 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | |
| 299 args->Clear(); | |
| 300 LogAPIActionInternal(extension_id, | 332 LogAPIActionInternal(extension_id, |
| 301 api_call, | 333 api_call, |
| 302 args, | 334 args, |
| 303 extra, | 335 extra, |
| 304 APIAction::EVENT_CALLBACK); | 336 APIAction::EVENT_CALLBACK); |
| 305 } | 337 } |
| 306 | 338 |
| 307 void ActivityLog::LogBlockedAction(const std::string& extension_id, | 339 void ActivityLog::LogBlockedAction(const std::string& extension_id, |
| 308 const std::string& blocked_call, | 340 const std::string& blocked_call, |
| 309 ListValue* args, | 341 ListValue* args, |
| 310 BlockedAction::Reason reason, | 342 BlockedAction::Reason reason, |
| 311 const std::string& extra) { | 343 const std::string& extra) { |
| 312 if (!IsLogEnabled() || | 344 if (!IsLogEnabled() || |
| 313 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 345 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 314 if (!testing_mode_ && | 346 |
| 315 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) | 347 if (policy_) { |
| 316 args->Clear(); | 348 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); |
| 349 std::string key; | |
| 350 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON, &key); | |
| 351 details->SetInteger(key, static_cast<int>(reason)); | |
| 352 policy_->ProcessAction( | |
| 353 ActivityLogPolicy::ACTION_BLOCKED, | |
| 354 extension_id, | |
| 355 blocked_call, | |
| 356 NULL, | |
| 357 args, | |
| 358 details.get()); | |
| 359 } | |
| 360 | |
| 361 // TODO(felt) Logging should be done more efficiently, so that it | |
| 362 // doesn't require construction of the action object. | |
|
felt
2013/06/13 18:52:02
This isn't going to happen: we need to make action
dbabic
2013/06/13 23:10:08
Done.
| |
| 317 scoped_refptr<BlockedAction> action = new BlockedAction(extension_id, | 363 scoped_refptr<BlockedAction> action = new BlockedAction(extension_id, |
| 318 base::Time::Now(), | 364 base::Time::Now(), |
| 319 blocked_call, | 365 blocked_call, |
| 320 MakeArgList(args), | 366 MakeArgList(args), |
| 321 reason, | 367 reason, |
| 322 extra); | 368 extra); |
| 323 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 324 observers_->Notify(&Observer::OnExtensionActivity, action); | 369 observers_->Notify(&Observer::OnExtensionActivity, action); |
| 325 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | 370 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); |
| 326 } | 371 } |
| 327 | 372 |
| 328 void ActivityLog::LogDOMAction(const std::string& extension_id, | 373 void ActivityLog::LogDOMAction(const std::string& extension_id, |
| 329 const GURL& url, | 374 const GURL& url, |
| 330 const string16& url_title, | 375 const string16& url_title, |
| 331 const std::string& api_call, | 376 const std::string& api_call, |
| 332 const ListValue* args, | 377 const ListValue* args, |
| 333 DomActionType::Type call_type, | 378 DomActionType::Type call_type, |
| 334 const std::string& extra) { | 379 const std::string& extra) { |
| 335 if (!IsLogEnabled() || | 380 if (!IsLogEnabled() || |
| 336 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 381 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 337 if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open") | 382 if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open") |
| 338 call_type = DomActionType::XHR; | 383 call_type = DomActionType::XHR; |
| 384 | |
| 385 if (policy_) { | |
| 386 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | |
| 387 std::string key; | |
| 388 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION, &key); | |
| 389 details->SetInteger(key, static_cast<int>(call_type)); | |
| 390 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE, &key); | |
| 391 details->SetString(key, url_title); | |
| 392 policy_->ProcessAction( | |
| 393 ActivityLogPolicy::ACTION_DOM, | |
| 394 extension_id, | |
| 395 api_call, | |
| 396 &url, | |
| 397 args, | |
| 398 details.get()); | |
| 399 } | |
| 400 | |
| 401 | |
| 402 // TODO(felt) Logging should be done more efficiently, so that it | |
| 403 // doesn't require construction of the action object. | |
| 339 scoped_refptr<DOMAction> action = new DOMAction( | 404 scoped_refptr<DOMAction> action = new DOMAction( |
| 340 extension_id, | 405 extension_id, |
| 341 base::Time::Now(), | 406 base::Time::Now(), |
| 342 call_type, | 407 call_type, |
| 343 url, | 408 url, |
| 344 url_title, | 409 url_title, |
| 345 api_call, | 410 api_call, |
| 346 MakeArgList(args), | 411 MakeArgList(args), |
| 347 extra); | 412 extra); |
| 348 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 349 observers_->Notify(&Observer::OnExtensionActivity, action); | 413 observers_->Notify(&Observer::OnExtensionActivity, action); |
| 350 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | 414 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); |
| 351 } | 415 } |
| 352 | 416 |
| 353 void ActivityLog::LogWebRequestAction(const std::string& extension_id, | 417 void ActivityLog::LogWebRequestAction(const std::string& extension_id, |
| 354 const GURL& url, | 418 const GURL& url, |
| 355 const std::string& api_call, | 419 const std::string& api_call, |
| 356 scoped_ptr<DictionaryValue> details, | 420 scoped_ptr<DictionaryValue> details, |
| 357 const std::string& extra) { | 421 const std::string& extra) { |
| 358 string16 null_title; | 422 string16 null_title; |
| 359 if (!IsLogEnabled() || | 423 if (!IsLogEnabled() || |
| 360 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 424 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 361 | 425 |
| 362 // Strip details of the web request modifications (for privacy reasons), | 426 std::string details_string; |
| 363 // unless testing is enabled. | 427 if (policy_) { |
| 364 if (!testing_mode_) { | 428 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); |
| 365 DictionaryValue::Iterator details_iterator(*details); | 429 std::string key; |
| 366 while (!details_iterator.IsAtEnd()) { | 430 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DETAILS_STRING, &key); |
| 367 details->SetBoolean(details_iterator.key(), true); | 431 details->SetString(key, details_string); |
| 368 details_iterator.Advance(); | 432 policy_->ProcessAction( |
| 369 } | 433 ActivityLogPolicy::ACTION_WEB_REQUEST, |
| 434 extension_id, | |
| 435 api_call, | |
| 436 &url, | |
| 437 NULL, | |
| 438 details.get()); | |
| 370 } | 439 } |
| 371 std::string details_string; | 440 |
| 372 JSONStringValueSerializer serializer(&details_string); | 441 JSONStringValueSerializer serializer(&details_string); |
| 373 serializer.SerializeAndOmitBinaryValues(*details); | 442 serializer.SerializeAndOmitBinaryValues(*details); |
| 374 | 443 |
| 444 // TODO(felt) Logging should be done more efficiently, so that it | |
| 445 // doesn't require construction of the action object. | |
| 375 scoped_refptr<DOMAction> action = new DOMAction( | 446 scoped_refptr<DOMAction> action = new DOMAction( |
| 376 extension_id, | 447 extension_id, |
| 377 base::Time::Now(), | 448 base::Time::Now(), |
| 378 DomActionType::WEBREQUEST, | 449 DomActionType::WEBREQUEST, |
| 379 url, | 450 url, |
| 380 null_title, | 451 null_title, |
| 381 api_call, | 452 api_call, |
| 382 details_string, | 453 details_string, |
| 383 extra); | 454 extra); |
| 384 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | |
| 385 observers_->Notify(&Observer::OnExtensionActivity, action); | 455 observers_->Notify(&Observer::OnExtensionActivity, action); |
| 386 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | 456 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); |
| 387 } | 457 } |
| 388 | 458 |
| 389 void ActivityLog::GetActions( | 459 void ActivityLog::GetActions( |
| 390 const std::string& extension_id, | 460 const std::string& extension_id, |
| 391 const int day, | 461 const int day, |
| 392 const base::Callback | 462 const base::Callback |
| 393 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { | 463 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
| 394 if (!has_threads_) return; | 464 if (policy_) { |
| 395 BrowserThread::PostTaskAndReplyWithResult( | 465 policy_->ReadData(extension_id, day, callback); |
| 396 BrowserThread::DB, | 466 } |
| 397 FROM_HERE, | |
| 398 base::Bind(&ActivityDatabase::GetActions, | |
| 399 base::Unretained(db_), | |
| 400 extension_id, | |
| 401 day), | |
| 402 callback); | |
| 403 } | 467 } |
| 404 | 468 |
| 405 void ActivityLog::OnScriptsExecuted( | 469 void ActivityLog::OnScriptsExecuted( |
| 406 const content::WebContents* web_contents, | 470 const content::WebContents* web_contents, |
| 407 const ExecutingScriptsMap& extension_ids, | 471 const ExecutingScriptsMap& extension_ids, |
| 408 int32 on_page_id, | 472 int32 on_page_id, |
| 409 const GURL& on_url) { | 473 const GURL& on_url) { |
| 410 if (!IsLogEnabled()) return; | 474 if (!IsLogEnabled()) return; |
| 411 Profile* profile = | 475 Profile* profile = |
| 412 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 476 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 web_contents->GetTitle(), | 510 web_contents->GetTitle(), |
| 447 std::string(), // no api call here | 511 std::string(), // no api call here |
| 448 script_names.get(), | 512 script_names.get(), |
| 449 DomActionType::INSERTED, | 513 DomActionType::INSERTED, |
| 450 extra); | 514 extra); |
| 451 } | 515 } |
| 452 } | 516 } |
| 453 } | 517 } |
| 454 | 518 |
| 455 } // namespace extensions | 519 } // namespace extensions |
| OLD | NEW |