| 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/strings/utf_string_conversions.h" |
| 11 #include "base/threading/thread_checker.h" | 12 #include "base/threading/thread_checker.h" |
| 13 #include "chrome/browser/extensions/activity_log/activity_action_constants.h" |
| 12 #include "chrome/browser/extensions/activity_log/activity_log.h" | 14 #include "chrome/browser/extensions/activity_log/activity_log.h" |
| 13 #include "chrome/browser/extensions/activity_log/api_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/activity_log/stream_noargs_ui_policy.h" |
| 16 #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" |
| 17 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 18 #include "chrome/browser/extensions/extension_system.h" | 18 #include "chrome/browser/extensions/extension_system.h" |
| 19 #include "chrome/browser/extensions/extension_system_factory.h" | 19 #include "chrome/browser/extensions/extension_system_factory.h" |
| 20 #include "chrome/browser/extensions/install_tracker_factory.h" | 20 #include "chrome/browser/extensions/install_tracker_factory.h" |
| 21 #include "chrome/browser/prerender/prerender_manager.h" | 21 #include "chrome/browser/prerender/prerender_manager.h" |
| 22 #include "chrome/browser/prerender/prerender_manager_factory.h" | 22 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| 23 #include "chrome/browser/profiles/incognito_helpers.h" | 23 #include "chrome/browser/profiles/incognito_helpers.h" |
| 24 #include "chrome/common/chrome_constants.h" | 24 #include "chrome/common/chrome_constants.h" |
| 25 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
| 26 #include "chrome/common/extensions/extension.h" | 26 #include "chrome/common/extensions/extension.h" |
| 27 #include "components/browser_context_keyed_service/browser_context_dependency_ma
nager.h" | 27 #include "components/browser_context_keyed_service/browser_context_dependency_ma
nager.h" |
| 28 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 29 #include "third_party/re2/re2/re2.h" | 29 #include "third_party/re2/re2/re2.h" |
| 30 #include "url/gurl.h" | 30 #include "url/gurl.h" |
| 31 | 31 |
| 32 namespace constants = activity_log_constants; |
| 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 // Concatenate arguments. | 36 // Concatenate arguments. |
| 35 std::string MakeArgList(const base::ListValue* args) { | 37 std::string MakeArgList(const base::ListValue* args) { |
| 36 std::string call_signature; | 38 std::string call_signature; |
| 37 base::ListValue::const_iterator it = args->begin(); | 39 base::ListValue::const_iterator it = args->begin(); |
| 38 for (; it != args->end(); ++it) { | 40 for (; it != args->end(); ++it) { |
| 39 std::string arg; | 41 std::string arg; |
| 40 JSONStringValueSerializer serializer(&arg); | 42 JSONStringValueSerializer serializer(&arg); |
| 41 if (serializer.SerializeAndOmitBinaryValues(**it)) { | 43 if (serializer.SerializeAndOmitBinaryValues(**it)) { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 } | 248 } |
| 247 | 249 |
| 248 void ActivityLog::AddObserver(ActivityLog::Observer* observer) { | 250 void ActivityLog::AddObserver(ActivityLog::Observer* observer) { |
| 249 observers_->AddObserver(observer); | 251 observers_->AddObserver(observer); |
| 250 } | 252 } |
| 251 | 253 |
| 252 void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { | 254 void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { |
| 253 observers_->RemoveObserver(observer); | 255 observers_->RemoveObserver(observer); |
| 254 } | 256 } |
| 255 | 257 |
| 258 void ActivityLog::LogAction(scoped_refptr<Action> action) { |
| 259 if (IsLogEnabled() && |
| 260 !ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) { |
| 261 if (policy_) |
| 262 policy_->ProcessAction(action); |
| 263 observers_->Notify(&Observer::OnExtensionActivity, action); |
| 264 if (testing_mode_) |
| 265 LOG(INFO) << action->PrintForDebug(); |
| 266 } |
| 267 } |
| 268 |
| 256 void ActivityLog::LogAPIActionInternal(const std::string& extension_id, | 269 void ActivityLog::LogAPIActionInternal(const std::string& extension_id, |
| 257 const std::string& api_call, | 270 const std::string& api_call, |
| 258 base::ListValue* args, | 271 base::ListValue* args, |
| 259 const std::string& extra, | 272 const std::string& extra, |
| 260 const APIAction::Type type) { | 273 const APIAction::Type type) { |
| 261 std::string verb, manager; | 274 std::string verb, manager; |
| 262 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); | 275 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); |
| 263 if (matches) { | 276 if (matches) { |
| 264 if (!args->empty() && manager == "tabs") { | 277 if (!args->empty() && manager == "tabs") { |
| 265 APIAction::LookupTabId(api_call, args, profile_); | 278 APIAction::LookupTabId(api_call, args, profile_); |
| 266 } | 279 } |
| 267 | 280 |
| 268 if (policy_) { | 281 DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) && |
| 269 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | 282 "Unexpected APIAction call type."); |
| 270 std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA); | |
| 271 details->SetString(key, extra); | |
| 272 DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) && | |
| 273 "Unexpected APIAction call type."); | |
| 274 policy_->ProcessAction( | |
| 275 type == APIAction::CALL ? ActivityLogPolicy::ACTION_API : | |
| 276 ActivityLogPolicy::ACTION_EVENT, | |
| 277 extension_id, | |
| 278 api_call, | |
| 279 GURL(), | |
| 280 args, | |
| 281 details.get()); | |
| 282 } | |
| 283 | 283 |
| 284 // TODO(felt) Logging should be done more efficiently, so that it | 284 scoped_refptr<Action> action; |
| 285 // doesn't require construction of the action object. | 285 action = new Action(extension_id, |
| 286 scoped_refptr<APIAction> action = new APIAction( | 286 base::Time::Now(), |
| 287 extension_id, | 287 type == APIAction::CALL ? Action::ACTION_API_CALL |
| 288 base::Time::Now(), | 288 : Action::ACTION_API_EVENT, |
| 289 type, | 289 api_call); |
| 290 api_call, | 290 action->set_args(make_scoped_ptr(args->DeepCopy())); |
| 291 MakeArgList(args), | 291 if (!extra.empty()) |
| 292 *args, | 292 action->mutable_other()->SetString(constants::kActionExtra, extra); |
| 293 extra); | |
| 294 | 293 |
| 295 observers_->Notify(&Observer::OnExtensionActivity, action); | 294 LogAction(action); |
| 296 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | |
| 297 } else { | 295 } else { |
| 298 LOG(ERROR) << "Unknown API call! " << api_call; | 296 LOG(ERROR) << "Unknown API call! " << api_call; |
| 299 } | 297 } |
| 300 } | 298 } |
| 301 | 299 |
| 302 // A wrapper around LogAPIActionInternal, but we know it's an API call. | 300 // A wrapper around LogAPIActionInternal, but we know it's an API call. |
| 303 void ActivityLog::LogAPIAction(const std::string& extension_id, | 301 void ActivityLog::LogAPIAction(const std::string& extension_id, |
| 304 const std::string& api_call, | 302 const std::string& api_call, |
| 305 base::ListValue* args, | 303 base::ListValue* args, |
| 306 const std::string& extra) { | 304 const std::string& extra) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 331 } | 329 } |
| 332 | 330 |
| 333 void ActivityLog::LogBlockedAction(const std::string& extension_id, | 331 void ActivityLog::LogBlockedAction(const std::string& extension_id, |
| 334 const std::string& blocked_call, | 332 const std::string& blocked_call, |
| 335 base::ListValue* args, | 333 base::ListValue* args, |
| 336 BlockedAction::Reason reason, | 334 BlockedAction::Reason reason, |
| 337 const std::string& extra) { | 335 const std::string& extra) { |
| 338 if (!IsLogEnabled() || | 336 if (!IsLogEnabled() || |
| 339 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 337 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 340 | 338 |
| 341 if (policy_) { | 339 scoped_refptr<Action> action; |
| 342 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | 340 action = new Action(extension_id, |
| 343 std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON); | 341 base::Time::Now(), |
| 344 details->SetInteger(key, static_cast<int>(reason)); | 342 Action::ACTION_API_BLOCKED, |
| 345 key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA); | 343 blocked_call); |
| 346 details->SetString(key, extra); | 344 action->set_args(make_scoped_ptr(args->DeepCopy())); |
| 347 policy_->ProcessAction( | 345 action->mutable_other() |
| 348 ActivityLogPolicy::ACTION_BLOCKED, | 346 ->SetInteger(constants::kActionBlockedReason, static_cast<int>(reason)); |
| 349 extension_id, | 347 if (!extra.empty()) |
| 350 blocked_call, | 348 action->mutable_other()->SetString(constants::kActionExtra, extra); |
| 351 GURL(), | |
| 352 args, | |
| 353 details.get()); | |
| 354 } | |
| 355 | 349 |
| 356 scoped_refptr<BlockedAction> action = new BlockedAction(extension_id, | 350 LogAction(action); |
| 357 base::Time::Now(), | |
| 358 blocked_call, | |
| 359 MakeArgList(args), | |
| 360 reason, | |
| 361 extra); | |
| 362 observers_->Notify(&Observer::OnExtensionActivity, action); | |
| 363 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | |
| 364 } | 351 } |
| 365 | 352 |
| 366 void ActivityLog::LogDOMAction(const std::string& extension_id, | 353 void ActivityLog::LogDOMAction(const std::string& extension_id, |
| 367 const GURL& url, | 354 const GURL& url, |
| 368 const string16& url_title, | 355 const string16& url_title, |
| 369 const std::string& api_call, | 356 const std::string& api_call, |
| 370 const base::ListValue* args, | 357 const base::ListValue* args, |
| 371 DomActionType::Type call_type, | 358 DomActionType::Type call_type, |
| 372 const std::string& extra) { | 359 const std::string& extra) { |
| 373 if (!IsLogEnabled() || | 360 if (!IsLogEnabled() || |
| 374 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 361 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 375 if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open") | 362 |
| 363 Action::ActionType action_type = Action::ACTION_DOM_ACCESS; |
| 364 if (call_type == DomActionType::INSERTED) { |
| 365 action_type = Action::ACTION_CONTENT_SCRIPT; |
| 366 } else if (call_type == DomActionType::METHOD && |
| 367 api_call == "XMLHttpRequest.open") { |
| 376 call_type = DomActionType::XHR; | 368 call_type = DomActionType::XHR; |
| 377 | 369 action_type = Action::ACTION_DOM_XHR; |
| 378 if (policy_) { | |
| 379 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | |
| 380 std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION); | |
| 381 details->SetInteger(key, static_cast<int>(call_type)); | |
| 382 key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE); | |
| 383 details->SetString(key, url_title); | |
| 384 key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA); | |
| 385 details->SetString(key, extra); | |
| 386 policy_->ProcessAction( | |
| 387 ActivityLogPolicy::ACTION_DOM, | |
| 388 extension_id, | |
| 389 api_call, | |
| 390 url, | |
| 391 args, | |
| 392 details.get()); | |
| 393 } | 370 } |
| 394 | 371 |
| 372 scoped_refptr<Action> action; |
| 373 action = new Action(extension_id, base::Time::Now(), action_type, api_call); |
| 374 if (args) |
| 375 action->set_args(make_scoped_ptr(args->DeepCopy())); |
| 376 action->set_page_url(url); |
| 377 action->set_page_title(base::UTF16ToUTF8(url_title)); |
| 378 action->mutable_other() |
| 379 ->SetInteger(constants::kActionDomVerb, static_cast<int>(call_type)); |
| 380 if (!extra.empty()) |
| 381 action->mutable_other()->SetString(constants::kActionExtra, extra); |
| 395 | 382 |
| 396 // TODO(felt) Logging should be done more efficiently, so that it | 383 LogAction(action); |
| 397 // doesn't require construction of the action object. | |
| 398 scoped_refptr<DOMAction> action = new DOMAction( | |
| 399 extension_id, | |
| 400 base::Time::Now(), | |
| 401 call_type, | |
| 402 url, | |
| 403 url_title, | |
| 404 api_call, | |
| 405 MakeArgList(args), | |
| 406 extra); | |
| 407 observers_->Notify(&Observer::OnExtensionActivity, action); | |
| 408 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | |
| 409 } | 384 } |
| 410 | 385 |
| 411 void ActivityLog::LogWebRequestAction(const std::string& extension_id, | 386 void ActivityLog::LogWebRequestAction(const std::string& extension_id, |
| 412 const GURL& url, | 387 const GURL& url, |
| 413 const std::string& api_call, | 388 const std::string& api_call, |
| 414 scoped_ptr<DictionaryValue> details, | 389 scoped_ptr<DictionaryValue> details, |
| 415 const std::string& extra) { | 390 const std::string& extra) { |
| 416 string16 null_title; | |
| 417 if (!IsLogEnabled() || | 391 if (!IsLogEnabled() || |
| 418 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; | 392 ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return; |
| 419 | 393 |
| 420 std::string details_string; | 394 scoped_refptr<Action> action; |
| 421 if (policy_) { | 395 action = new Action( |
| 422 scoped_ptr<base::DictionaryValue> details(new DictionaryValue()); | 396 extension_id, base::Time::Now(), Action::ACTION_WEB_REQUEST, api_call); |
| 423 std::string key = policy_->GetKey( | 397 action->set_page_url(url); |
| 424 ActivityLogPolicy::PARAM_KEY_DETAILS_STRING); | 398 action->mutable_other()->Set(constants::kActionWebRequest, details.release()); |
| 425 details->SetString(key, details_string); | 399 if (!extra.empty()) |
| 426 key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA); | 400 action->mutable_other()->SetString(constants::kActionExtra, extra); |
| 427 details->SetString(key, extra); | |
| 428 policy_->ProcessAction( | |
| 429 ActivityLogPolicy::ACTION_WEB_REQUEST, | |
| 430 extension_id, | |
| 431 api_call, | |
| 432 url, | |
| 433 NULL, | |
| 434 details.get()); | |
| 435 } | |
| 436 | 401 |
| 437 JSONStringValueSerializer serializer(&details_string); | 402 LogAction(action); |
| 438 serializer.SerializeAndOmitBinaryValues(*details); | |
| 439 | |
| 440 // TODO(felt) Logging should be done more efficiently, so that it | |
| 441 // doesn't require construction of the action object. | |
| 442 scoped_refptr<DOMAction> action = new DOMAction( | |
| 443 extension_id, | |
| 444 base::Time::Now(), | |
| 445 DomActionType::WEBREQUEST, | |
| 446 url, | |
| 447 null_title, | |
| 448 api_call, | |
| 449 details_string, | |
| 450 extra); | |
| 451 observers_->Notify(&Observer::OnExtensionActivity, action); | |
| 452 if (testing_mode_) LOG(INFO) << action->PrintForDebug(); | |
| 453 } | 403 } |
| 454 | 404 |
| 455 void ActivityLog::GetActions( | 405 void ActivityLog::GetActions( |
| 456 const std::string& extension_id, | 406 const std::string& extension_id, |
| 457 const int day, | 407 const int day, |
| 458 const base::Callback | 408 const base::Callback |
| 459 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { | 409 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
| 460 if (policy_) { | 410 if (policy_) { |
| 461 policy_->ReadData(extension_id, day, callback); | 411 policy_->ReadData(extension_id, day, callback); |
| 462 } | 412 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 web_contents->GetTitle(), | 456 web_contents->GetTitle(), |
| 507 std::string(), // no api call here | 457 std::string(), // no api call here |
| 508 script_names.get(), | 458 script_names.get(), |
| 509 DomActionType::INSERTED, | 459 DomActionType::INSERTED, |
| 510 extra); | 460 extra); |
| 511 } | 461 } |
| 512 } | 462 } |
| 513 } | 463 } |
| 514 | 464 |
| 515 } // namespace extensions | 465 } // namespace extensions |
| OLD | NEW |