Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/extension_processes_api.h" | 5 #include "chrome/browser/extensions/extension_processes_api.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 std::string event(keys::kOnCreated); | 304 std::string event(keys::kOnCreated); |
| 305 if (!HasEventListeners(event)) | 305 if (!HasEventListeners(event)) |
| 306 return; | 306 return; |
| 307 | 307 |
| 308 // If the item being added is not the first one in the group, find the base | 308 // If the item being added is not the first one in the group, find the base |
| 309 // index and use it for retrieving the process data. | 309 // index and use it for retrieving the process data. |
| 310 if (!model_->IsResourceFirstInGroup(start)) { | 310 if (!model_->IsResourceFirstInGroup(start)) { |
| 311 index = model_->GetGroupIndexForResource(start); | 311 index = model_->GetGroupIndexForResource(start); |
| 312 } | 312 } |
| 313 | 313 |
| 314 ListValue args; | 314 ListValue* args = new ListValue(); |
| 315 DictionaryValue* process = CreateProcessFromModel( | 315 DictionaryValue* process = CreateProcessFromModel( |
| 316 model_->GetUniqueChildProcessId(index), model_, index, false); | 316 model_->GetUniqueChildProcessId(index), model_, index, false); |
| 317 DCHECK(process != NULL); | 317 DCHECK(process != NULL); |
| 318 | 318 |
| 319 if (process == NULL) | 319 if (process == NULL) |
| 320 return; | 320 return; |
| 321 | 321 |
| 322 args.Append(process); | 322 args->Append(process); |
| 323 | 323 |
| 324 std::string json_args; | 324 NotifyProfiles(keys::kOnCreated, args); |
| 325 base::JSONWriter::Write(&args, &json_args); | |
| 326 NotifyProfiles(keys::kOnCreated, json_args); | |
| 327 #endif // defined(ENABLE_TASK_MANAGER) | 325 #endif // defined(ENABLE_TASK_MANAGER) |
| 328 } | 326 } |
| 329 | 327 |
| 330 void ExtensionProcessesEventRouter::OnItemsChanged(int start, int length) { | 328 void ExtensionProcessesEventRouter::OnItemsChanged(int start, int length) { |
| 331 #if defined(ENABLE_TASK_MANAGER) | 329 #if defined(ENABLE_TASK_MANAGER) |
| 332 // If we don't have any listeners, return immediately. | 330 // If we don't have any listeners, return immediately. |
| 333 if (listeners_ == 0) | 331 if (listeners_ == 0) |
| 334 return; | 332 return; |
| 335 | 333 |
| 336 if (!model_) | 334 if (!model_) |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 361 if (updated) { | 359 if (updated) { |
| 362 IDMap<DictionaryValue>::iterator it(&processes_map); | 360 IDMap<DictionaryValue>::iterator it(&processes_map); |
| 363 for (; !it.IsAtEnd(); it.Advance()) { | 361 for (; !it.IsAtEnd(); it.Advance()) { |
| 364 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) | 362 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) |
| 365 continue; | 363 continue; |
| 366 | 364 |
| 367 // Store each process indexed by the string version of its id. | 365 // Store each process indexed by the string version of its id. |
| 368 processes->Set(base::IntToString(id), it.GetCurrentValue()); | 366 processes->Set(base::IntToString(id), it.GetCurrentValue()); |
| 369 } | 367 } |
| 370 | 368 |
| 371 ListValue args; | 369 ListValue* args = new ListValue(); |
| 372 args.Append(processes); | 370 args->Append(processes); |
| 373 std::string json_args; | 371 NotifyProfiles(keys::kOnUpdated, args); |
| 374 base::JSONWriter::Write(&args, &json_args); | |
| 375 NotifyProfiles(keys::kOnUpdated, json_args); | |
| 376 } | 372 } |
| 377 | 373 |
| 378 if (updated_memory) { | 374 if (updated_memory) { |
| 379 IDMap<DictionaryValue>::iterator it(&processes_map); | 375 IDMap<DictionaryValue>::iterator it(&processes_map); |
| 380 for (; !it.IsAtEnd(); it.Advance()) { | 376 for (; !it.IsAtEnd(); it.Advance()) { |
| 381 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) | 377 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) |
| 382 continue; | 378 continue; |
| 383 | 379 |
| 384 AddMemoryDetails(it.GetCurrentValue(), model_, it.GetCurrentKey()); | 380 AddMemoryDetails(it.GetCurrentValue(), model_, it.GetCurrentKey()); |
| 385 | 381 |
| 386 // Store each process indexed by the string version of its id if we didn't | 382 // Store each process indexed by the string version of its id if we didn't |
| 387 // already insert it as part of the onUpdated processing above. | 383 // already insert it as part of the onUpdated processing above. |
| 388 if (!updated) | 384 if (!updated) |
| 389 processes->Set(base::IntToString(id), it.GetCurrentValue()); | 385 processes->Set(base::IntToString(id), it.GetCurrentValue()); |
| 390 } | 386 } |
| 391 | 387 |
| 392 ListValue args; | 388 ListValue* args = new ListValue(); |
| 393 args.Append(processes); | 389 args->Append(processes); |
| 394 std::string json_args; | 390 NotifyProfiles(keys::kOnUpdatedWithMemory, args); |
| 395 base::JSONWriter::Write(&args, &json_args); | |
| 396 NotifyProfiles(keys::kOnUpdatedWithMemory, json_args); | |
| 397 } | 391 } |
| 398 #endif // defined(ENABLE_TASK_MANAGER) | 392 #endif // defined(ENABLE_TASK_MANAGER) |
| 399 } | 393 } |
| 400 | 394 |
| 401 void ExtensionProcessesEventRouter::OnItemsToBeRemoved(int start, int length) { | 395 void ExtensionProcessesEventRouter::OnItemsToBeRemoved(int start, int length) { |
| 402 #if defined(ENABLE_TASK_MANAGER) | 396 #if defined(ENABLE_TASK_MANAGER) |
| 403 DCHECK(length == 1); | 397 DCHECK(length == 1); |
| 404 | 398 |
| 405 // Process exit for renderer processes has the data about exit code and | 399 // Process exit for renderer processes has the data about exit code and |
| 406 // termination status, therefore we will rely on notifications and not on | 400 // termination status, therefore we will rely on notifications and not on |
| 407 // the Task Manager data. We do use the rest of this method for non-renderer | 401 // the Task Manager data. We do use the rest of this method for non-renderer |
| 408 // processes. | 402 // processes. |
| 409 if (model_->GetResourceType(start) == TaskManager::Resource::RENDERER) | 403 if (model_->GetResourceType(start) == TaskManager::Resource::RENDERER) |
| 410 return; | 404 return; |
| 411 | 405 |
| 412 // The callback function parameters. | 406 // The callback function parameters. |
| 413 ListValue args; | 407 ListValue* args = new ListValue(); |
| 414 | 408 |
| 415 // First arg: The id of the process that was closed. | 409 // First arg: The id of the process that was closed. |
| 416 args.Append(Value::CreateIntegerValue( | 410 args->Append(Value::CreateIntegerValue( |
| 417 model_->GetUniqueChildProcessId(start))); | 411 model_->GetUniqueChildProcessId(start))); |
| 418 | 412 |
| 419 // Second arg: The exit type for the process. | 413 // Second arg: The exit type for the process. |
| 420 args.Append(Value::CreateIntegerValue(0)); | 414 args->Append(Value::CreateIntegerValue(0)); |
| 421 | 415 |
| 422 // Third arg: The exit code for the process. | 416 // Third arg: The exit code for the process. |
| 423 args.Append(Value::CreateIntegerValue(0)); | 417 args->Append(Value::CreateIntegerValue(0)); |
| 424 | 418 |
| 425 std::string json_args; | 419 NotifyProfiles(keys::kOnExited, args); |
| 426 base::JSONWriter::Write(&args, &json_args); | |
| 427 NotifyProfiles(keys::kOnExited, json_args); | |
| 428 #endif // defined(ENABLE_TASK_MANAGER) | 420 #endif // defined(ENABLE_TASK_MANAGER) |
| 429 } | 421 } |
| 430 | 422 |
| 431 void ExtensionProcessesEventRouter::ProcessHangEvent( | 423 void ExtensionProcessesEventRouter::ProcessHangEvent( |
| 432 content::RenderWidgetHost* widget) { | 424 content::RenderWidgetHost* widget) { |
| 433 #if defined(ENABLE_TASK_MANAGER) | 425 #if defined(ENABLE_TASK_MANAGER) |
| 434 std::string event(keys::kOnUnresponsive); | 426 std::string event(keys::kOnUnresponsive); |
| 435 if (!HasEventListeners(event)) | 427 if (!HasEventListeners(event)) |
| 436 return; | 428 return; |
| 437 | 429 |
| 438 DictionaryValue* process = NULL; | 430 DictionaryValue* process = NULL; |
| 439 int count = model_->ResourceCount(); | 431 int count = model_->ResourceCount(); |
| 440 int id = widget->GetProcess()->GetID(); | 432 int id = widget->GetProcess()->GetID(); |
| 441 | 433 |
| 442 for (int i = 0; i < count; ++i) { | 434 for (int i = 0; i < count; ++i) { |
| 443 if (model_->IsResourceFirstInGroup(i)) { | 435 if (model_->IsResourceFirstInGroup(i)) { |
| 444 if (id == model_->GetUniqueChildProcessId(i)) { | 436 if (id == model_->GetUniqueChildProcessId(i)) { |
| 445 process = CreateProcessFromModel(id, model_, i, false); | 437 process = CreateProcessFromModel(id, model_, i, false); |
| 446 break; | 438 break; |
| 447 } | 439 } |
| 448 } | 440 } |
| 449 } | 441 } |
| 450 | 442 |
| 451 DCHECK(process); | 443 DCHECK(process); |
| 452 if (process == NULL) | 444 if (process == NULL) |
| 453 return; | 445 return; |
| 454 | 446 |
| 455 ListValue args; | 447 ListValue* args = new ListValue(); |
| 456 args.Append(process); | 448 args->Append(process); |
| 457 | 449 |
| 458 std::string json_args; | 450 NotifyProfiles(keys::kOnUnresponsive, args); |
| 459 base::JSONWriter::Write(&args, &json_args); | |
| 460 NotifyProfiles(keys::kOnUnresponsive, json_args); | |
| 461 #endif // defined(ENABLE_TASK_MANAGER) | 451 #endif // defined(ENABLE_TASK_MANAGER) |
| 462 } | 452 } |
| 463 | 453 |
| 464 void ExtensionProcessesEventRouter::ProcessClosedEvent( | 454 void ExtensionProcessesEventRouter::ProcessClosedEvent( |
| 465 content::RenderProcessHost* rph, | 455 content::RenderProcessHost* rph, |
| 466 content::RenderProcessHost::RendererClosedDetails* details) { | 456 content::RenderProcessHost::RendererClosedDetails* details) { |
| 467 #if defined(ENABLE_TASK_MANAGER) | 457 #if defined(ENABLE_TASK_MANAGER) |
| 468 // The callback function parameters. | 458 // The callback function parameters. |
| 469 ListValue args; | 459 ListValue* args = new ListValue(); |
| 470 | 460 |
| 471 // First arg: The id of the process that was closed. | 461 // First arg: The id of the process that was closed. |
| 472 args.Append(Value::CreateIntegerValue(rph->GetID())); | 462 args->Append(Value::CreateIntegerValue(rph->GetID())); |
| 473 | 463 |
| 474 // Second arg: The exit type for the process. | 464 // Second arg: The exit type for the process. |
| 475 args.Append(Value::CreateIntegerValue(details->status)); | 465 args->Append(Value::CreateIntegerValue(details->status)); |
| 476 | 466 |
| 477 // Third arg: The exit code for the process. | 467 // Third arg: The exit code for the process. |
| 478 args.Append(Value::CreateIntegerValue(details->exit_code)); | 468 args->Append(Value::CreateIntegerValue(details->exit_code)); |
| 479 | 469 |
| 480 std::string json_args; | 470 NotifyProfiles(keys::kOnExited, args); |
| 481 base::JSONWriter::Write(&args, &json_args); | |
| 482 NotifyProfiles(keys::kOnExited, json_args); | |
| 483 #endif // defined(ENABLE_TASK_MANAGER) | 471 #endif // defined(ENABLE_TASK_MANAGER) |
| 484 } | 472 } |
| 485 | 473 |
| 486 void ExtensionProcessesEventRouter::DispatchEvent( | 474 void ExtensionProcessesEventRouter::DispatchEvent( |
| 487 Profile* profile, | 475 Profile* profile, |
| 488 const char* event_name, | 476 const char* event_name, |
| 489 const std::string& json_args) { | 477 ListValue* event_args) { |
| 490 if (profile && profile->GetExtensionEventRouter()) { | 478 if (profile && profile->GetExtensionEventRouter()) { |
| 491 profile->GetExtensionEventRouter()->DispatchEventToRenderers( | 479 profile->GetExtensionEventRouter()->DispatchEventToRenderers( |
| 492 event_name, json_args, NULL, GURL(), EventFilteringInfo()); | 480 event_name, event_args, NULL, GURL(), EventFilteringInfo()); |
| 493 } | 481 } |
| 494 } | 482 } |
| 495 | 483 |
| 496 void ExtensionProcessesEventRouter::NotifyProfiles(const char* event_name, | 484 void ExtensionProcessesEventRouter::NotifyProfiles(const char* event_name, |
| 497 std::string json_args) { | 485 ListValue* event_args) { |
| 486 scoped_ptr<ListValue> delete_event_args(event_args); | |
|
miket_OOO
2012/07/10 22:33:19
That's pretty tricky. I am only about 51% sure it'
| |
| 498 for (ProfileSet::iterator it = profiles_.begin(); | 487 for (ProfileSet::iterator it = profiles_.begin(); |
| 499 it != profiles_.end(); it++) { | 488 it != profiles_.end(); it++) { |
| 500 Profile* profile = *it; | 489 Profile* profile = *it; |
| 501 DispatchEvent(profile, event_name, json_args); | 490 DispatchEvent(profile, event_name, event_args->DeepCopy()); |
| 502 } | 491 } |
| 503 } | 492 } |
| 504 | 493 |
| 505 // In order to determine whether there are any listeners for the event of | 494 // In order to determine whether there are any listeners for the event of |
| 506 // interest, we need to ask each profile whether it has one registered. | 495 // interest, we need to ask each profile whether it has one registered. |
| 507 // We only need to look for the profiles that have registered with the | 496 // We only need to look for the profiles that have registered with the |
| 508 // this extension API. | 497 // this extension API. |
| 509 bool ExtensionProcessesEventRouter::HasEventListeners(std::string& event_name) { | 498 bool ExtensionProcessesEventRouter::HasEventListeners(std::string& event_name) { |
| 510 for (ProfileSet::iterator it = profiles_.begin(); | 499 for (ProfileSet::iterator it = profiles_.begin(); |
| 511 it != profiles_.end(); it++) { | 500 it != profiles_.end(); it++) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 744 DCHECK(process_ids_.size() == 0); | 733 DCHECK(process_ids_.size() == 0); |
| 745 } | 734 } |
| 746 | 735 |
| 747 result_.reset(processes); | 736 result_.reset(processes); |
| 748 SendResponse(true); | 737 SendResponse(true); |
| 749 | 738 |
| 750 // Balance the AddRef in the RunImpl. | 739 // Balance the AddRef in the RunImpl. |
| 751 Release(); | 740 Release(); |
| 752 #endif // defined(ENABLE_TASK_MANAGER) | 741 #endif // defined(ENABLE_TASK_MANAGER) |
| 753 } | 742 } |
| OLD | NEW |