| 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/performance_monitor/performance_monitor.h" | 5 #include "chrome/browser/performance_monitor/performance_monitor.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "chrome/browser/ui/browser_list.h" | 25 #include "chrome/browser/ui/browser_list.h" |
| 26 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
| 27 #include "chrome/common/chrome_version_info.h" | 27 #include "chrome/common/chrome_version_info.h" |
| 28 #include "chrome/common/extensions/extension.h" | 28 #include "chrome/common/extensions/extension.h" |
| 29 #include "chrome/common/extensions/extension_constants.h" | 29 #include "chrome/common/extensions/extension_constants.h" |
| 30 #include "chrome/test/base/chrome_process_util.h" | 30 #include "chrome/test/base/chrome_process_util.h" |
| 31 #include "content/public/browser/browser_child_process_host.h" | 31 #include "content/public/browser/browser_child_process_host.h" |
| 32 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 33 #include "content/public/browser/notification_service.h" | 33 #include "content/public/browser/notification_service.h" |
| 34 #include "content/public/browser/notification_types.h" | 34 #include "content/public/browser/notification_types.h" |
| 35 #include "content/public/browser/render_process_host.h" | |
| 36 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 37 | 36 |
| 38 using content::BrowserThread; | 37 using content::BrowserThread; |
| 39 using extensions::Extension; | 38 using extensions::Extension; |
| 40 | 39 |
| 41 namespace { | 40 namespace { |
| 42 const uint32 kAccessFlags = base::kProcessAccessDuplicateHandle | | 41 const uint32 kAccessFlags = base::kProcessAccessDuplicateHandle | |
| 43 base::kProcessAccessQueryInformation | | 42 base::kProcessAccessQueryInformation | |
| 44 base::kProcessAccessTerminate | | 43 base::kProcessAccessTerminate | |
| 45 base::kProcessAccessWaitForTermination; | 44 base::kProcessAccessWaitForTermination; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 FROM_HERE, | 221 FROM_HERE, |
| 223 base::Bind(&PerformanceMonitor::AddEventOnBackgroundThread, | 222 base::Bind(&PerformanceMonitor::AddEventOnBackgroundThread, |
| 224 base::Unretained(this), | 223 base::Unretained(this), |
| 225 base::Passed(event.Pass()))); | 224 base::Passed(event.Pass()))); |
| 226 } | 225 } |
| 227 | 226 |
| 228 void PerformanceMonitor::AddEventOnBackgroundThread(scoped_ptr<Event> event) { | 227 void PerformanceMonitor::AddEventOnBackgroundThread(scoped_ptr<Event> event) { |
| 229 database_->AddEvent(*event.get()); | 228 database_->AddEvent(*event.get()); |
| 230 } | 229 } |
| 231 | 230 |
| 232 void PerformanceMonitor::GetStateValueOnBackgroundThread( | |
| 233 const std::string& key, | |
| 234 const StateValueCallback& callback) { | |
| 235 CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 236 std::string state_value = database_->GetStateValue(key); | |
| 237 | |
| 238 BrowserThread::PostTask(BrowserThread::UI, | |
| 239 FROM_HERE, | |
| 240 base::Bind(callback, state_value)); | |
| 241 } | |
| 242 | |
| 243 void PerformanceMonitor::NotifyInitialized() { | 231 void PerformanceMonitor::NotifyInitialized() { |
| 244 content::NotificationService::current()->Notify( | 232 content::NotificationService::current()->Notify( |
| 245 chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED, | 233 chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED, |
| 246 content::Source<PerformanceMonitor>(this), | 234 content::Source<PerformanceMonitor>(this), |
| 247 content::NotificationService::NoDetails()); | 235 content::NotificationService::NoDetails()); |
| 248 } | 236 } |
| 249 | 237 |
| 250 void PerformanceMonitor::GatherStatisticsOnBackgroundThread() { | 238 void PerformanceMonitor::GatherStatisticsOnBackgroundThread() { |
| 251 CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | 239 CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 252 | 240 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 351 |
| 364 void PerformanceMonitor::DoTimedCollections() { | 352 void PerformanceMonitor::DoTimedCollections() { |
| 365 UpdateLiveProfiles(); | 353 UpdateLiveProfiles(); |
| 366 } | 354 } |
| 367 | 355 |
| 368 void PerformanceMonitor::Observe(int type, | 356 void PerformanceMonitor::Observe(int type, |
| 369 const content::NotificationSource& source, | 357 const content::NotificationSource& source, |
| 370 const content::NotificationDetails& details) { | 358 const content::NotificationDetails& details) { |
| 371 switch (type) { | 359 switch (type) { |
| 372 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { | 360 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { |
| 373 const Extension* extension = content::Details<Extension>(details).ptr(); | 361 AddExtensionEvent(EVENT_EXTENSION_INSTALL, |
| 374 AddEvent(util::CreateExtensionInstallEvent(base::Time::Now(), | 362 content::Details<Extension>(details).ptr()); |
| 375 extension->id(), | |
| 376 extension->name(), | |
| 377 extension->url().spec(), | |
| 378 extension->location(), | |
| 379 extension->VersionString(), | |
| 380 extension->description())); | |
| 381 break; | 363 break; |
| 382 } | 364 } |
| 383 case chrome::NOTIFICATION_EXTENSION_ENABLED: { | 365 case chrome::NOTIFICATION_EXTENSION_ENABLED: { |
| 384 const Extension* extension = content::Details<Extension>(details).ptr(); | 366 AddExtensionEvent(EVENT_EXTENSION_ENABLE, |
| 385 AddEvent(util::CreateExtensionEnableEvent(base::Time::Now(), | 367 content::Details<Extension>(details).ptr()); |
| 386 extension->id(), | |
| 387 extension->name(), | |
| 388 extension->url().spec(), | |
| 389 extension->location(), | |
| 390 extension->VersionString(), | |
| 391 extension->description())); | |
| 392 break; | 368 break; |
| 393 } | 369 } |
| 394 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 370 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 395 const extensions::UnloadedExtensionInfo* info = | 371 const extensions::UnloadedExtensionInfo* info = |
| 396 content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); | 372 content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); |
| 397 const Extension* extension = info->extension; | 373 |
| 398 AddEvent(util::CreateExtensionUnloadEvent(base::Time::Now(), | 374 // Check if the extension was unloaded because it was disabled. |
| 399 extension->id(), | 375 if (info->reason == extension_misc::UNLOAD_REASON_DISABLE) { |
| 400 extension->name(), | 376 AddExtensionEvent(EVENT_EXTENSION_DISABLE, |
| 401 extension->url().spec(), | 377 info->extension); |
| 402 extension->location(), | 378 } |
| 403 extension->VersionString(), | |
| 404 extension->description(), | |
| 405 info->reason)); | |
| 406 break; | 379 break; |
| 407 } | 380 } |
| 408 case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { | 381 case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { |
| 409 const extensions::CrxInstaller* installer = | 382 const extensions::CrxInstaller* installer = |
| 410 content::Source<extensions::CrxInstaller>(source).ptr(); | 383 content::Source<extensions::CrxInstaller>(source).ptr(); |
| 411 | 384 |
| 412 // Check if the reason for the install was due to an extension update. | 385 // Check if the reason for the install was due to an extension update. |
| 413 if (installer->install_cause() != extension_misc::INSTALL_CAUSE_UPDATE) | 386 if (installer->install_cause() == extension_misc::INSTALL_CAUSE_UPDATE) { |
| 414 break; | 387 AddExtensionEvent(EVENT_EXTENSION_UPDATE, |
| 415 | 388 content::Details<Extension>(details).ptr()); |
| 416 const Extension* extension = content::Details<Extension>(details).ptr(); | 389 } |
| 417 AddEvent(util::CreateExtensionUpdateEvent(base::Time::Now(), | |
| 418 extension->id(), | |
| 419 extension->name(), | |
| 420 extension->url().spec(), | |
| 421 extension->location(), | |
| 422 extension->VersionString(), | |
| 423 extension->description())); | |
| 424 break; | 390 break; |
| 425 } | 391 } |
| 426 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: { | 392 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: { |
| 427 const Extension* extension = content::Details<Extension>(details).ptr(); | 393 AddExtensionEvent(EVENT_EXTENSION_UNINSTALL, |
| 428 AddEvent(util::CreateExtensionUninstallEvent(base::Time::Now(), | 394 content::Details<Extension>(details).ptr()); |
| 429 extension->id(), | |
| 430 extension->name(), | |
| 431 extension->url().spec(), | |
| 432 extension->location(), | |
| 433 extension->VersionString(), | |
| 434 extension->description())); | |
| 435 break; | 395 break; |
| 436 } | 396 } |
| 437 case content::NOTIFICATION_RENDERER_PROCESS_HANG: { | 397 case content::NOTIFICATION_RENDERER_PROCESS_HANG: { |
| 438 content::WebContents* contents = | 398 content::WebContents* contents = |
| 439 content::Source<content::WebContents>(source).ptr(); | 399 content::Source<content::WebContents>(source).ptr(); |
| 440 AddEvent(util::CreateRendererFreezeEvent(base::Time::Now(), | 400 AddEvent(util::CreateRendererFreezeEvent(base::Time::Now(), |
| 441 contents->GetURL().spec())); | 401 contents->GetURL().spec())); |
| 442 break; | 402 break; |
| 443 } | 403 } |
| 444 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 404 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
| 445 content::RenderProcessHost::RendererClosedDetails closed_details = | 405 AddCrashEvent(*content::Details< |
| 446 *content::Details<content::RenderProcessHost::RendererClosedDetails>( | 406 content::RenderProcessHost::RendererClosedDetails>(details).ptr()); |
| 447 details).ptr(); | |
| 448 | |
| 449 // We only care if this is an invalid termination. | |
| 450 if (closed_details.status == base::TERMINATION_STATUS_NORMAL_TERMINATION | |
| 451 || closed_details.status == base::TERMINATION_STATUS_STILL_RUNNING) | |
| 452 break; | |
| 453 | |
| 454 // Determine the type of crash. | |
| 455 EventType type = | |
| 456 closed_details.status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? | |
| 457 EVENT_KILLED_BY_OS_CRASH : EVENT_RENDERER_CRASH; | |
| 458 | |
| 459 AddEvent(util::CreateCrashEvent(base::Time::Now(), | |
| 460 type)); | |
| 461 break; | 407 break; |
| 462 } | 408 } |
| 463 case chrome::NOTIFICATION_PROFILE_ADDED: { | 409 case chrome::NOTIFICATION_PROFILE_ADDED: { |
| 464 Profile* profile = content::Source<Profile>(source).ptr(); | 410 Profile* profile = content::Source<Profile>(source).ptr(); |
| 465 if (!profile->DidLastSessionExitCleanly()) { | 411 if (!profile->DidLastSessionExitCleanly()) { |
| 466 BrowserThread::PostBlockingPoolSequencedTask( | 412 BrowserThread::PostBlockingPoolSequencedTask( |
| 467 Database::kDatabaseSequenceToken, | 413 Database::kDatabaseSequenceToken, |
| 468 FROM_HERE, | 414 FROM_HERE, |
| 469 base::Bind( | 415 base::Bind( |
| 470 &PerformanceMonitor::AddUncleanExitEventOnBackgroundThread, | 416 &PerformanceMonitor::AddUncleanExitEventOnBackgroundThread, |
| 471 base::Unretained(this), | 417 base::Unretained(this), |
| 472 profile->GetDebugName())); | 418 profile->GetDebugName())); |
| 473 } | 419 } |
| 474 break; | 420 break; |
| 475 } | 421 } |
| 476 default: { | 422 default: { |
| 477 NOTREACHED(); | 423 NOTREACHED(); |
| 478 break; | 424 break; |
| 479 } | 425 } |
| 480 } | 426 } |
| 481 } | 427 } |
| 482 | 428 |
| 429 void PerformanceMonitor::AddExtensionEvent(EventType type, |
| 430 const Extension* extension) { |
| 431 DCHECK(type == EVENT_EXTENSION_INSTALL || |
| 432 type == EVENT_EXTENSION_UNINSTALL || |
| 433 type == EVENT_EXTENSION_UPDATE || |
| 434 type == EVENT_EXTENSION_ENABLE || |
| 435 type == EVENT_EXTENSION_DISABLE); |
| 436 AddEvent(util::CreateExtensionEvent(type, |
| 437 base::Time::Now(), |
| 438 extension->id(), |
| 439 extension->name(), |
| 440 extension->url().spec(), |
| 441 extension->location(), |
| 442 extension->VersionString(), |
| 443 extension->description())); |
| 444 } |
| 445 |
| 446 void PerformanceMonitor::AddCrashEvent( |
| 447 const content::RenderProcessHost::RendererClosedDetails& details) { |
| 448 // We only care if this is an invalid termination. |
| 449 if (details.status == base::TERMINATION_STATUS_NORMAL_TERMINATION || |
| 450 details.status == base::TERMINATION_STATUS_STILL_RUNNING) |
| 451 return; |
| 452 |
| 453 // Determine the type of crash. |
| 454 EventType type = |
| 455 details.status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? |
| 456 EVENT_KILLED_BY_OS_CRASH : EVENT_RENDERER_CRASH; |
| 457 |
| 458 AddEvent(util::CreateCrashEvent(base::Time::Now(), type)); |
| 459 } |
| 460 |
| 483 } // namespace performance_monitor | 461 } // namespace performance_monitor |
| OLD | NEW |