| 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/api/processes/processes_api.h" | 5 #include "chrome/browser/extensions/api/processes/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/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 scoped_ptr<base::ListValue> args(new base::ListValue()); | 307 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 308 base::DictionaryValue* process = CreateProcessFromModel( | 308 base::DictionaryValue* process = CreateProcessFromModel( |
| 309 model_->GetUniqueChildProcessId(index), model_, index, false); | 309 model_->GetUniqueChildProcessId(index), model_, index, false); |
| 310 DCHECK(process != NULL); | 310 DCHECK(process != NULL); |
| 311 | 311 |
| 312 if (process == NULL) | 312 if (process == NULL) |
| 313 return; | 313 return; |
| 314 | 314 |
| 315 args->Append(process); | 315 args->Append(process); |
| 316 | 316 |
| 317 DispatchEvent(keys::kOnCreated, args.Pass()); | 317 DispatchEvent(events::PROCESSES_ON_CREATED, keys::kOnCreated, args.Pass()); |
| 318 #endif // defined(ENABLE_TASK_MANAGER) | 318 #endif // defined(ENABLE_TASK_MANAGER) |
| 319 } | 319 } |
| 320 | 320 |
| 321 void ProcessesEventRouter::OnItemsChanged(int start, int length) { | 321 void ProcessesEventRouter::OnItemsChanged(int start, int length) { |
| 322 #if defined(ENABLE_TASK_MANAGER) | 322 #if defined(ENABLE_TASK_MANAGER) |
| 323 // If we don't have any listeners, return immediately. | 323 // If we don't have any listeners, return immediately. |
| 324 if (listeners_ == 0) | 324 if (listeners_ == 0) |
| 325 return; | 325 return; |
| 326 | 326 |
| 327 if (!model_) | 327 if (!model_) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 355 for (; !it.IsAtEnd(); it.Advance()) { | 355 for (; !it.IsAtEnd(); it.Advance()) { |
| 356 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) | 356 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) |
| 357 continue; | 357 continue; |
| 358 | 358 |
| 359 // Store each process indexed by the string version of its id. | 359 // Store each process indexed by the string version of its id. |
| 360 processes->Set(base::IntToString(id), it.GetCurrentValue()); | 360 processes->Set(base::IntToString(id), it.GetCurrentValue()); |
| 361 } | 361 } |
| 362 | 362 |
| 363 scoped_ptr<base::ListValue> args(new base::ListValue()); | 363 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 364 args->Append(processes); | 364 args->Append(processes); |
| 365 DispatchEvent(keys::kOnUpdated, args.Pass()); | 365 DispatchEvent(events::PROCESSES_ON_UPDATED, keys::kOnUpdated, args.Pass()); |
| 366 } | 366 } |
| 367 | 367 |
| 368 if (updated_memory) { | 368 if (updated_memory) { |
| 369 IDMap<base::DictionaryValue>::iterator it(&processes_map); | 369 IDMap<base::DictionaryValue>::iterator it(&processes_map); |
| 370 for (; !it.IsAtEnd(); it.Advance()) { | 370 for (; !it.IsAtEnd(); it.Advance()) { |
| 371 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) | 371 if (!it.GetCurrentValue()->GetInteger(idkey, &id)) |
| 372 continue; | 372 continue; |
| 373 | 373 |
| 374 AddMemoryDetails(it.GetCurrentValue(), model_, it.GetCurrentKey()); | 374 AddMemoryDetails(it.GetCurrentValue(), model_, it.GetCurrentKey()); |
| 375 | 375 |
| 376 // Store each process indexed by the string version of its id if we didn't | 376 // Store each process indexed by the string version of its id if we didn't |
| 377 // already insert it as part of the onUpdated processing above. | 377 // already insert it as part of the onUpdated processing above. |
| 378 if (!updated) | 378 if (!updated) |
| 379 processes->Set(base::IntToString(id), it.GetCurrentValue()); | 379 processes->Set(base::IntToString(id), it.GetCurrentValue()); |
| 380 } | 380 } |
| 381 | 381 |
| 382 scoped_ptr<base::ListValue> args(new base::ListValue()); | 382 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 383 args->Append(processes); | 383 args->Append(processes); |
| 384 DispatchEvent(keys::kOnUpdatedWithMemory, args.Pass()); | 384 DispatchEvent(events::PROCESSES_ON_UPDATED_WITH_MEMORY, |
| 385 keys::kOnUpdatedWithMemory, args.Pass()); |
| 385 } | 386 } |
| 386 #endif // defined(ENABLE_TASK_MANAGER) | 387 #endif // defined(ENABLE_TASK_MANAGER) |
| 387 } | 388 } |
| 388 | 389 |
| 389 void ProcessesEventRouter::OnItemsToBeRemoved(int start, int length) { | 390 void ProcessesEventRouter::OnItemsToBeRemoved(int start, int length) { |
| 390 #if defined(ENABLE_TASK_MANAGER) | 391 #if defined(ENABLE_TASK_MANAGER) |
| 391 DCHECK_EQ(length, 1); | 392 DCHECK_EQ(length, 1); |
| 392 | 393 |
| 393 // Process exit for renderer processes has the data about exit code and | 394 // Process exit for renderer processes has the data about exit code and |
| 394 // termination status, therefore we will rely on notifications and not on | 395 // termination status, therefore we will rely on notifications and not on |
| 395 // the Task Manager data. We do use the rest of this method for non-renderer | 396 // the Task Manager data. We do use the rest of this method for non-renderer |
| 396 // processes. | 397 // processes. |
| 397 if (model_->GetResourceType(start) == task_manager::Resource::RENDERER) | 398 if (model_->GetResourceType(start) == task_manager::Resource::RENDERER) |
| 398 return; | 399 return; |
| 399 | 400 |
| 400 // The callback function parameters. | 401 // The callback function parameters. |
| 401 scoped_ptr<base::ListValue> args(new base::ListValue()); | 402 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 402 | 403 |
| 403 // First arg: The id of the process that was closed. | 404 // First arg: The id of the process that was closed. |
| 404 args->Append(new base::FundamentalValue( | 405 args->Append(new base::FundamentalValue( |
| 405 model_->GetUniqueChildProcessId(start))); | 406 model_->GetUniqueChildProcessId(start))); |
| 406 | 407 |
| 407 // Second arg: The exit type for the process. | 408 // Second arg: The exit type for the process. |
| 408 args->Append(new base::FundamentalValue(0)); | 409 args->Append(new base::FundamentalValue(0)); |
| 409 | 410 |
| 410 // Third arg: The exit code for the process. | 411 // Third arg: The exit code for the process. |
| 411 args->Append(new base::FundamentalValue(0)); | 412 args->Append(new base::FundamentalValue(0)); |
| 412 | 413 |
| 413 DispatchEvent(keys::kOnExited, args.Pass()); | 414 DispatchEvent(events::PROCESSES_ON_EXITED, keys::kOnExited, args.Pass()); |
| 414 #endif // defined(ENABLE_TASK_MANAGER) | 415 #endif // defined(ENABLE_TASK_MANAGER) |
| 415 } | 416 } |
| 416 | 417 |
| 417 void ProcessesEventRouter::ProcessHangEvent(content::RenderWidgetHost* widget) { | 418 void ProcessesEventRouter::ProcessHangEvent(content::RenderWidgetHost* widget) { |
| 418 #if defined(ENABLE_TASK_MANAGER) | 419 #if defined(ENABLE_TASK_MANAGER) |
| 419 std::string event(keys::kOnUnresponsive); | 420 std::string event(keys::kOnUnresponsive); |
| 420 if (!HasEventListeners(event)) | 421 if (!HasEventListeners(event)) |
| 421 return; | 422 return; |
| 422 | 423 |
| 423 base::DictionaryValue* process = NULL; | 424 base::DictionaryValue* process = NULL; |
| 424 int count = model_->ResourceCount(); | 425 int count = model_->ResourceCount(); |
| 425 int id = widget->GetProcess()->GetID(); | 426 int id = widget->GetProcess()->GetID(); |
| 426 | 427 |
| 427 for (int i = 0; i < count; ++i) { | 428 for (int i = 0; i < count; ++i) { |
| 428 if (model_->IsResourceFirstInGroup(i)) { | 429 if (model_->IsResourceFirstInGroup(i)) { |
| 429 if (id == model_->GetUniqueChildProcessId(i)) { | 430 if (id == model_->GetUniqueChildProcessId(i)) { |
| 430 process = CreateProcessFromModel(id, model_, i, false); | 431 process = CreateProcessFromModel(id, model_, i, false); |
| 431 break; | 432 break; |
| 432 } | 433 } |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 | 436 |
| 436 if (process == NULL) | 437 if (process == NULL) |
| 437 return; | 438 return; |
| 438 | 439 |
| 439 scoped_ptr<base::ListValue> args(new base::ListValue()); | 440 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 440 args->Append(process); | 441 args->Append(process); |
| 441 | 442 |
| 442 DispatchEvent(keys::kOnUnresponsive, args.Pass()); | 443 DispatchEvent(events::PROCESSES_ON_UNRESPONSIVE, keys::kOnUnresponsive, |
| 444 args.Pass()); |
| 443 #endif // defined(ENABLE_TASK_MANAGER) | 445 #endif // defined(ENABLE_TASK_MANAGER) |
| 444 } | 446 } |
| 445 | 447 |
| 446 void ProcessesEventRouter::ProcessClosedEvent( | 448 void ProcessesEventRouter::ProcessClosedEvent( |
| 447 content::RenderProcessHost* rph, | 449 content::RenderProcessHost* rph, |
| 448 content::RenderProcessHost::RendererClosedDetails* details) { | 450 content::RenderProcessHost::RendererClosedDetails* details) { |
| 449 #if defined(ENABLE_TASK_MANAGER) | 451 #if defined(ENABLE_TASK_MANAGER) |
| 450 // The callback function parameters. | 452 // The callback function parameters. |
| 451 scoped_ptr<base::ListValue> args(new base::ListValue()); | 453 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 452 | 454 |
| 453 // First arg: The id of the process that was closed. | 455 // First arg: The id of the process that was closed. |
| 454 args->Append(new base::FundamentalValue(rph->GetID())); | 456 args->Append(new base::FundamentalValue(rph->GetID())); |
| 455 | 457 |
| 456 // Second arg: The exit type for the process. | 458 // Second arg: The exit type for the process. |
| 457 args->Append(new base::FundamentalValue(details->status)); | 459 args->Append(new base::FundamentalValue(details->status)); |
| 458 | 460 |
| 459 // Third arg: The exit code for the process. | 461 // Third arg: The exit code for the process. |
| 460 args->Append(new base::FundamentalValue(details->exit_code)); | 462 args->Append(new base::FundamentalValue(details->exit_code)); |
| 461 | 463 |
| 462 DispatchEvent(keys::kOnExited, args.Pass()); | 464 DispatchEvent(events::PROCESSES_ON_EXITED, keys::kOnExited, args.Pass()); |
| 463 #endif // defined(ENABLE_TASK_MANAGER) | 465 #endif // defined(ENABLE_TASK_MANAGER) |
| 464 } | 466 } |
| 465 | 467 |
| 466 void ProcessesEventRouter::DispatchEvent( | 468 void ProcessesEventRouter::DispatchEvent( |
| 469 events::HistogramValue histogram_value, |
| 467 const std::string& event_name, | 470 const std::string& event_name, |
| 468 scoped_ptr<base::ListValue> event_args) { | 471 scoped_ptr<base::ListValue> event_args) { |
| 469 EventRouter* event_router = EventRouter::Get(browser_context_); | 472 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 470 if (event_router) { | 473 if (event_router) { |
| 471 scoped_ptr<extensions::Event> event(new extensions::Event( | 474 scoped_ptr<Event> event( |
| 472 extensions::events::UNKNOWN, event_name, event_args.Pass())); | 475 new Event(histogram_value, event_name, event_args.Pass())); |
| 473 event_router->BroadcastEvent(event.Pass()); | 476 event_router->BroadcastEvent(event.Pass()); |
| 474 } | 477 } |
| 475 } | 478 } |
| 476 | 479 |
| 477 bool ProcessesEventRouter::HasEventListeners(const std::string& event_name) { | 480 bool ProcessesEventRouter::HasEventListeners(const std::string& event_name) { |
| 478 EventRouter* event_router = EventRouter::Get(browser_context_); | 481 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 479 return event_router && event_router->HasEventListener(event_name); | 482 return event_router && event_router->HasEventListener(event_name); |
| 480 } | 483 } |
| 481 | 484 |
| 482 ProcessesAPI::ProcessesAPI(content::BrowserContext* context) | 485 ProcessesAPI::ProcessesAPI(content::BrowserContext* context) |
| 483 : browser_context_(context) { | 486 : browser_context_(context) { |
| 484 EventRouter* event_router = EventRouter::Get(browser_context_); | 487 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 485 event_router->RegisterObserver(this, processes_api_constants::kOnUpdated); | 488 event_router->RegisterObserver(this, processes_api_constants::kOnUpdated); |
| 486 event_router->RegisterObserver(this, | 489 event_router->RegisterObserver(this, |
| 487 processes_api_constants::kOnUpdatedWithMemory); | 490 processes_api_constants::kOnUpdatedWithMemory); |
| 488 ExtensionFunctionRegistry* registry = | 491 ExtensionFunctionRegistry* registry = |
| 489 ExtensionFunctionRegistry::GetInstance(); | 492 ExtensionFunctionRegistry::GetInstance(); |
| 490 registry->RegisterFunction<extensions::GetProcessIdForTabFunction>(); | 493 registry->RegisterFunction<GetProcessIdForTabFunction>(); |
| 491 registry->RegisterFunction<extensions::TerminateFunction>(); | 494 registry->RegisterFunction<TerminateFunction>(); |
| 492 registry->RegisterFunction<extensions::GetProcessInfoFunction>(); | 495 registry->RegisterFunction<GetProcessInfoFunction>(); |
| 493 } | 496 } |
| 494 | 497 |
| 495 ProcessesAPI::~ProcessesAPI() { | 498 ProcessesAPI::~ProcessesAPI() { |
| 496 } | 499 } |
| 497 | 500 |
| 498 void ProcessesAPI::Shutdown() { | 501 void ProcessesAPI::Shutdown() { |
| 499 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 502 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
| 500 } | 503 } |
| 501 | 504 |
| 502 static base::LazyInstance<BrowserContextKeyedAPIFactory<ProcessesAPI> > | 505 static base::LazyInstance<BrowserContextKeyedAPIFactory<ProcessesAPI> > |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 void GetProcessIdForTabFunction::GetProcessIdForTab() { | 575 void GetProcessIdForTabFunction::GetProcessIdForTab() { |
| 573 content::WebContents* contents = NULL; | 576 content::WebContents* contents = NULL; |
| 574 int tab_index = -1; | 577 int tab_index = -1; |
| 575 if (!ExtensionTabUtil::GetTabById(tab_id_, | 578 if (!ExtensionTabUtil::GetTabById(tab_id_, |
| 576 GetProfile(), | 579 GetProfile(), |
| 577 include_incognito(), | 580 include_incognito(), |
| 578 NULL, | 581 NULL, |
| 579 NULL, | 582 NULL, |
| 580 &contents, | 583 &contents, |
| 581 &tab_index)) { | 584 &tab_index)) { |
| 582 error_ = ErrorUtils::FormatErrorMessage( | 585 error_ = ErrorUtils::FormatErrorMessage(tabs_constants::kTabNotFoundError, |
| 583 extensions::tabs_constants::kTabNotFoundError, | 586 base::IntToString(tab_id_)); |
| 584 base::IntToString(tab_id_)); | |
| 585 SetResult(new base::FundamentalValue(-1)); | 587 SetResult(new base::FundamentalValue(-1)); |
| 586 SendResponse(false); | 588 SendResponse(false); |
| 587 } else { | 589 } else { |
| 588 int process_id = contents->GetRenderProcessHost()->GetID(); | 590 int process_id = contents->GetRenderProcessHost()->GetID(); |
| 589 SetResult(new base::FundamentalValue(process_id)); | 591 SetResult(new base::FundamentalValue(process_id)); |
| 590 SendResponse(true); | 592 SendResponse(true); |
| 591 } | 593 } |
| 592 | 594 |
| 593 // Balance the AddRef in the RunAsync. | 595 // Balance the AddRef in the RunAsync. |
| 594 Release(); | 596 Release(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 | 680 |
| 679 GetProcessInfoFunction::~GetProcessInfoFunction() { | 681 GetProcessInfoFunction::~GetProcessInfoFunction() { |
| 680 } | 682 } |
| 681 | 683 |
| 682 bool GetProcessInfoFunction::RunAsync() { | 684 bool GetProcessInfoFunction::RunAsync() { |
| 683 #if defined(ENABLE_TASK_MANAGER) | 685 #if defined(ENABLE_TASK_MANAGER) |
| 684 base::Value* processes = NULL; | 686 base::Value* processes = NULL; |
| 685 | 687 |
| 686 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &processes)); | 688 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &processes)); |
| 687 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &memory_)); | 689 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &memory_)); |
| 688 | 690 EXTENSION_FUNCTION_VALIDATE(ReadOneOrMoreIntegers(processes, &process_ids_)); |
| 689 EXTENSION_FUNCTION_VALIDATE(extensions::ReadOneOrMoreIntegers( | |
| 690 processes, &process_ids_)); | |
| 691 | 691 |
| 692 // Add a reference, which is balanced in GatherProcessInfo to keep the object | 692 // Add a reference, which is balanced in GatherProcessInfo to keep the object |
| 693 // around and allow for the callback to be invoked. | 693 // around and allow for the callback to be invoked. |
| 694 AddRef(); | 694 AddRef(); |
| 695 | 695 |
| 696 // If the task manager is already listening, just post a task to execute | 696 // If the task manager is already listening, just post a task to execute |
| 697 // which will invoke the callback once we have returned from this function. | 697 // which will invoke the callback once we have returned from this function. |
| 698 // Otherwise, wait for the notification that the task manager is done with | 698 // Otherwise, wait for the notification that the task manager is done with |
| 699 // the data gathering. | 699 // the data gathering. |
| 700 if (ProcessesAPI::Get(GetProfile()) | 700 if (ProcessesAPI::Get(GetProfile()) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 | 762 |
| 763 SetResult(processes); | 763 SetResult(processes); |
| 764 SendResponse(true); | 764 SendResponse(true); |
| 765 | 765 |
| 766 // Balance the AddRef in the RunAsync. | 766 // Balance the AddRef in the RunAsync. |
| 767 Release(); | 767 Release(); |
| 768 #endif // defined(ENABLE_TASK_MANAGER) | 768 #endif // defined(ENABLE_TASK_MANAGER) |
| 769 } | 769 } |
| 770 | 770 |
| 771 } // namespace extensions | 771 } // namespace extensions |
| OLD | NEW |