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 |