Index: chrome/browser/performance_monitor/performance_monitor.cc |
diff --git a/chrome/browser/performance_monitor/performance_monitor.cc b/chrome/browser/performance_monitor/performance_monitor.cc |
index 87086d6833e8d2459d8a445df359f46b52727482..a7f9f6d02c519b20ffb75967d3123d2ea575e456 100644 |
--- a/chrome/browser/performance_monitor/performance_monitor.cc |
+++ b/chrome/browser/performance_monitor/performance_monitor.cc |
@@ -20,7 +20,6 @@ |
#include "chrome/browser/browser_shutdown.h" |
#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/performance_monitor/constants.h" |
-#include "chrome/browser/performance_monitor/performance_monitor_util.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/profiles/profile_manager.h" |
#include "chrome/browser/ui/browser.h" |
@@ -34,100 +33,21 @@ |
#include "content/public/browser/load_notification_details.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_types.h" |
+#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/render_widget_host.h" |
#include "content/public/browser/render_widget_host_iterator.h" |
#include "content/public/browser/web_contents.h" |
#include "net/url_request/url_request.h" |
-#if defined(ENABLE_EXTENSIONS) |
-#include "chrome/browser/extensions/crx_installer.h" |
-#include "chrome/common/extensions/extension_constants.h" |
-#include "extensions/common/extension.h" |
-#endif |
- |
using content::BrowserThread; |
-#if defined(ENABLE_EXTENSIONS) |
-using extensions::Extension; |
-using extensions::UnloadedExtensionInfo; |
-#endif |
- |
namespace performance_monitor { |
-namespace { |
- |
-#if !defined(OS_ANDROID) |
-std::string TimeToString(base::Time time) { |
- int64 time_int64 = time.ToInternalValue(); |
- return base::Int64ToString(time_int64); |
-} |
-#endif // !defined(OS_ANDROID) |
- |
-bool StringToTime(std::string time, base::Time* output) { |
- int64 time_int64 = 0; |
- if (!base::StringToInt64(time, &time_int64)) |
- return false; |
- *output = base::Time::FromInternalValue(time_int64); |
- return true; |
-} |
- |
-// Try to get the URL for the RenderViewHost if the host does not correspond to |
-// an incognito profile (we don't store URLs from incognito sessions). Returns |
-// true if url has been populated, and false otherwise. |
-bool MaybeGetURLFromRenderView(const content::RenderViewHost* view, |
- std::string* url) { |
- content::WebContents* web_contents = |
- content::WebContents::FromRenderViewHost(view); |
- |
- if (Profile::FromBrowserContext( |
- web_contents->GetBrowserContext())->IsOffTheRecord()) { |
- return false; |
- } |
- |
- *url = web_contents->GetURL().spec(); |
- return true; |
-} |
- |
-// Takes ownership of and deletes |database| on the background thread, to |
-// avoid destruction in the middle of an operation. |
-void DeleteDatabaseOnBackgroundThread(Database* database) { |
- delete database; |
-} |
- |
-} // namespace |
- |
-bool PerformanceMonitor::initialized_ = false; |
- |
-PerformanceMonitor::PerformanceDataForIOThread::PerformanceDataForIOThread() |
- : network_bytes_read(0) { |
-} |
- |
-PerformanceMonitor::PerformanceMonitor() |
- : gather_interval_in_seconds_(kDefaultGatherIntervalInSeconds), |
- database_logging_enabled_(false), |
- timer_(FROM_HERE, |
- base::TimeDelta::FromSeconds(kSampleIntervalInSeconds), |
- this, |
- &PerformanceMonitor::DoTimedCollections), |
- disable_timer_autostart_for_testing_(false) { |
+PerformanceMonitor::PerformanceMonitor() { |
} |
PerformanceMonitor::~PerformanceMonitor() { |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&DeleteDatabaseOnBackgroundThread, database_.release())); |
-} |
- |
-bool PerformanceMonitor::SetDatabasePath(const base::FilePath& path) { |
- if (!database_.get()) { |
- database_path_ = path; |
- return true; |
- } |
- |
- // PerformanceMonitor already initialized with another path. |
- return false; |
} |
// static |
@@ -135,252 +55,17 @@ PerformanceMonitor* PerformanceMonitor::GetInstance() { |
return Singleton<PerformanceMonitor>::get(); |
} |
-void PerformanceMonitor::Initialize() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kPerformanceMonitorGathering)) { |
- database_logging_enabled_ = true; |
- |
- std::string switch_value = CommandLine::ForCurrentProcess()-> |
- GetSwitchValueASCII(switches::kPerformanceMonitorGathering); |
- |
- if (!switch_value.empty()) { |
- int specified_interval = 0; |
- if (!base::StringToInt(switch_value, &specified_interval) || |
- specified_interval <= 0) { |
- LOG(ERROR) << "Invalid value for switch: '" |
- << switches::kPerformanceMonitorGathering |
- << "'; please use an integer greater than 0."; |
- } else { |
- gather_interval_in_seconds_ = std::max(specified_interval, |
- kSampleIntervalInSeconds); |
- } |
- } |
- } |
- |
- DCHECK(gather_interval_in_seconds_ >= kSampleIntervalInSeconds); |
- |
- next_collection_time_ = base::Time::Now() + |
- base::TimeDelta::FromSeconds(gather_interval_in_seconds_); |
- |
- util::PostTaskToDatabaseThreadAndReply( |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::InitOnBackgroundThread, |
- base::Unretained(this)), |
- base::Bind(&PerformanceMonitor::FinishInit, |
- base::Unretained(this))); |
-} |
- |
-void PerformanceMonitor::InitOnBackgroundThread() { |
- CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (database_logging_enabled_) { |
- if (!database_) |
- database_ = Database::Create(database_path_); |
- |
- if (!database_) { |
- LOG(ERROR) << "Could not initialize database; aborting initialization."; |
- database_logging_enabled_ = false; |
- return; |
- } |
- |
- // Initialize the io thread's performance data to the value in the database; |
- // if there isn't a recording in the database, the value stays at 0. |
- Metric metric; |
- if (database_->GetRecentStatsForActivityAndMetric(METRIC_NETWORK_BYTES_READ, |
- &metric)) { |
- performance_data_for_io_thread_.network_bytes_read = metric.value; |
- } |
- } |
-} |
- |
-void PerformanceMonitor::FinishInit() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- // Events and notifications are only useful if we're logging to the database. |
- if (database_logging_enabled_) { |
- RegisterForNotifications(); |
- CheckForUncleanExits(); |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::CheckForVersionUpdateOnBackgroundThread, |
- base::Unretained(this))); |
- } |
- |
- // Post a task to the background thread to a function which does nothing. |
- // This will force any tasks the database is performing to finish prior to |
- // the reply being sent, since they use the same thread. |
- // |
- // Important! Make sure that methods in FinishInit() only rely on posting |
- // to the background thread, and do not rely upon a reply from the background |
- // thread; this is necessary for this notification to be valid. |
- util::PostTaskToDatabaseThreadAndReply( |
- FROM_HERE, |
- base::Bind(&base::DoNothing), |
- base::Bind(&PerformanceMonitor::NotifyInitialized, |
- base::Unretained(this))); |
-} |
- |
void PerformanceMonitor::StartGatherCycle() { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- // Start our periodic gathering of metrics. |
- if (!disable_timer_autostart_for_testing_) |
- timer_.Reset(); |
-} |
- |
-void PerformanceMonitor::RegisterForNotifications() { |
- DCHECK(database_logging_enabled_); |
- |
- // Extensions |
- registrar_.Add( |
- this, |
- extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, |
- content::NotificationService::AllSources()); |
- registrar_.Add(this, |
- extensions::NOTIFICATION_EXTENSION_ENABLED, |
- content::NotificationService::AllSources()); |
- registrar_.Add(this, |
- extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
- content::NotificationService::AllSources()); |
- registrar_.Add(this, |
- extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
- content::NotificationService::AllSources()); |
- registrar_.Add(this, |
- extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
- content::NotificationService::AllSources()); |
- |
- // Crashes |
- registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG, |
- content::NotificationService::AllSources()); |
- registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
- content::NotificationService::AllSources()); |
- |
- // Profiles (for unclean exit) |
- registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, |
- content::NotificationService::AllSources()); |
- |
- // Page load times |
- registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, |
- content::NotificationService::AllSources()); |
-} |
- |
-// We check if profiles exited cleanly initialization time in case they were |
-// loaded prior to PerformanceMonitor's initialization. Later profiles will be |
-// checked through the PROFILE_ADDED notification. |
-void PerformanceMonitor::CheckForUncleanExits() { |
- DCHECK(database_logging_enabled_); |
- |
- std::vector<Profile*> profiles = |
- g_browser_process->profile_manager()->GetLoadedProfiles(); |
- |
- for (std::vector<Profile*>::const_iterator iter = profiles.begin(); |
- iter != profiles.end(); ++iter) { |
- if ((*iter)->GetLastSessionExitType() == Profile::EXIT_CRASHED) { |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::AddUncleanExitEventOnBackgroundThread, |
- base::Unretained(this), |
- (*iter)->GetDebugName())); |
- } |
- } |
-} |
- |
-void PerformanceMonitor::AddUncleanExitEventOnBackgroundThread( |
- const std::string& profile_name) { |
- DCHECK(database_logging_enabled_); |
- std::string database_key = kStateProfilePrefix + profile_name; |
- std::string last_active_string = database_->GetStateValue(database_key); |
- |
- // Check if there was no previous time; this should only happen if the profile |
- // was last used prior to PerformanceMonitor's integration. Do nothing in this |
- // case, since the event was prior to the beginning of our recording. |
- if (last_active_string.empty()) |
- return; |
- |
- base::Time last_active_time; |
- CHECK(StringToTime(last_active_string, &last_active_time)); |
- |
- scoped_ptr<Event> event = |
- util::CreateUncleanExitEvent(last_active_time, profile_name); |
- |
- database_->AddEvent(*event.get()); |
-} |
- |
-void PerformanceMonitor::CheckForVersionUpdateOnBackgroundThread() { |
- CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(database_logging_enabled_); |
- |
- chrome::VersionInfo version; |
- DCHECK(version.is_valid()); |
- std::string current_version = version.Version(); |
- |
- std::string previous_version = database_->GetStateValue(kStateChromeVersion); |
- |
- // We should never have a current_version which is older than the |
- // previous_version. |
- DCHECK(current_version >= previous_version); |
- |
- // If this is the first run, there will not be a stored value for Chrome |
- // version; we insert the current version and will insert an event for the |
- // next update of Chrome. If the previous version is older than the current |
- // version, update the state in the database and insert an event. |
- if (current_version > previous_version) { |
- database_->AddStateValue(kStateChromeVersion, current_version); |
- if (!previous_version.empty()) { |
- scoped_ptr<Event> event = util::CreateChromeUpdateEvent( |
- base::Time::Now(), previous_version, current_version); |
- database_->AddEvent(*event.get()); |
- } |
- } |
-} |
- |
-void PerformanceMonitor::AddEvent(scoped_ptr<Event> event) { |
- DCHECK(database_logging_enabled_); |
- |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::AddEventOnBackgroundThread, |
- base::Unretained(this), |
- base::Passed(&event))); |
-} |
- |
-void PerformanceMonitor::AddEventOnBackgroundThread(scoped_ptr<Event> event) { |
- database_->AddEvent(*event.get()); |
-} |
- |
-void PerformanceMonitor::AddMetricOnBackgroundThread(const Metric& metric) { |
- DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(database_logging_enabled_); |
- |
- database_->AddMetric(metric); |
-} |
- |
-void PerformanceMonitor::NotifyInitialized() { |
- content::NotificationService::current()->Notify( |
- chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED, |
- content::Source<PerformanceMonitor>(this), |
- content::NotificationService::NoDetails()); |
- |
- initialized_ = true; |
-} |
- |
-void PerformanceMonitor::DoTimedCollections() { |
-#if !defined(OS_ANDROID) |
- // The profile list is only useful for the logged events. |
- if (database_logging_enabled_) |
- UpdateLiveProfiles(); |
-#endif |
- |
- GatherMetricsMapOnUIThread(); |
+ repeating_timer_.Start(FROM_HERE, |
+ base::TimeDelta::FromSeconds(kGatherIntervalInSeconds), |
Devlin
2014/09/09 02:12:57
We can probably safely move this constant into thi
tonyg
2014/09/09 18:28:10
Done.
|
+ this, |
+ &PerformanceMonitor::GatherMetricsMapOnUIThread); |
} |
void PerformanceMonitor::GatherMetricsMapOnUIThread() { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
static int current_update_sequence = 0; |
// Even in the "somewhat" unlikely event this wraps around, |
// it doesn't matter. We just check it for inequality. |
@@ -404,8 +89,8 @@ void PerformanceMonitor::GatherMetricsMapOnUIThread() { |
} |
void PerformanceMonitor::MarkProcessAsAlive(const base::ProcessHandle& handle, |
- int process_type, |
- int current_update_sequence) { |
+ int process_type, |
+ int current_update_sequence) { |
if (handle == 0) { |
// Process may not be valid yet. |
return; |
@@ -423,37 +108,6 @@ void PerformanceMonitor::MarkProcessAsAlive(const base::ProcessHandle& handle, |
} |
} |
-#if !defined(OS_ANDROID) |
-void PerformanceMonitor::UpdateLiveProfiles() { |
- std::string time = TimeToString(base::Time::Now()); |
- scoped_ptr<std::set<std::string> > active_profiles( |
- new std::set<std::string>()); |
- |
- for (chrome::BrowserIterator it; !it.done(); it.Next()) |
- active_profiles->insert(it->profile()->GetDebugName()); |
- |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::UpdateLiveProfilesHelper, |
- base::Unretained(this), |
- base::Passed(&active_profiles), |
- time)); |
-} |
- |
-void PerformanceMonitor::UpdateLiveProfilesHelper( |
- scoped_ptr<std::set<std::string> > active_profiles, |
- std::string time) { |
- CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(database_logging_enabled_); |
- |
- for (std::set<std::string>::const_iterator iter = active_profiles->begin(); |
- iter != active_profiles->end(); ++iter) { |
- database_->AddStateValue(kStateProfilePrefix + *iter, time); |
- } |
-} |
-#endif |
- |
void PerformanceMonitor::GatherMetricsMapOnIOThread( |
int current_update_sequence) { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
@@ -471,29 +125,6 @@ void PerformanceMonitor::GatherMetricsMapOnIOThread( |
MarkProcessAsAlive(base::GetCurrentProcessHandle(), |
content::PROCESS_TYPE_BROWSER, current_update_sequence); |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::StoreMetricsOnBackgroundThread, |
- base::Unretained(this), current_update_sequence, |
- performance_data_for_io_thread_)); |
-} |
- |
-void PerformanceMonitor::StoreMetricsOnBackgroundThread( |
- int current_update_sequence, |
- const PerformanceDataForIOThread& performance_data_for_io_thread) { |
- CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- base::Time time_now = base::Time::Now(); |
- |
- // The timing can be off by kSampleIntervalInSeconds during any one particular |
- // run, but will be correct over time. |
- bool end_of_cycle = time_now >= next_collection_time_; |
- if (end_of_cycle) { |
- next_collection_time_ += |
- base::TimeDelta::FromSeconds(gather_interval_in_seconds_); |
- } |
- |
double cpu_usage = 0.0; |
size_t private_memory_sum = 0; |
size_t shared_memory_sum = 0; |
@@ -508,220 +139,20 @@ void PerformanceMonitor::StoreMetricsOnBackgroundThread( |
} else { |
process_metrics.SampleMetrics(); |
- if (end_of_cycle) { |
- // Gather averages of previously sampled metrics. |
- cpu_usage += process_metrics.GetAverageCPUUsage(); |
+ // Gather averages of previously sampled metrics. |
+ cpu_usage += process_metrics.GetAverageCPUUsage(); |
- size_t private_memory = 0; |
- size_t shared_memory = 0; |
- process_metrics.GetAverageMemoryBytes(&private_memory, &shared_memory); |
- private_memory_sum += private_memory; |
- shared_memory_sum += shared_memory; |
+ size_t private_memory = 0; |
+ size_t shared_memory = 0; |
+ process_metrics.GetAverageMemoryBytes(&private_memory, &shared_memory); |
+ private_memory_sum += private_memory; |
+ shared_memory_sum += shared_memory; |
- process_metrics.EndOfCycle(); |
- } |
+ process_metrics.EndOfCycle(); |
++iter; |
} |
} |
- |
- // Store previously-sampled metrics. |
- if (end_of_cycle && database_logging_enabled_) { |
- if (!metrics_map_.empty()) { |
- database_->AddMetric(Metric(METRIC_CPU_USAGE, time_now, cpu_usage)); |
- database_->AddMetric(Metric(METRIC_PRIVATE_MEMORY_USAGE, |
- time_now, |
- static_cast<double>(private_memory_sum))); |
- database_->AddMetric(Metric(METRIC_SHARED_MEMORY_USAGE, |
- time_now, |
- static_cast<double>(shared_memory_sum))); |
- } |
- |
- database_->AddMetric( |
- Metric(METRIC_NETWORK_BYTES_READ, |
- time_now, |
- static_cast<double>( |
- performance_data_for_io_thread.network_bytes_read))); |
- } |
- |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&PerformanceMonitor::StartGatherCycle, |
- base::Unretained(this))); |
-} |
- |
-void PerformanceMonitor::BytesReadOnIOThread(const net::URLRequest& request, |
- const int bytes_read) { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- if (initialized_ && !request.url().SchemeIsFile()) |
- performance_data_for_io_thread_.network_bytes_read += bytes_read; |
-} |
- |
-void PerformanceMonitor::Observe(int type, |
- const content::NotificationSource& source, |
- const content::NotificationDetails& details) { |
- DCHECK(database_logging_enabled_); |
- |
- switch (type) { |
-#if defined(ENABLE_EXTENSIONS) |
- case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: { |
- AddExtensionEvent( |
- EVENT_EXTENSION_INSTALL, |
- content::Details<const extensions::InstalledExtensionInfo>(details)-> |
- extension); |
- break; |
- } |
- case extensions::NOTIFICATION_EXTENSION_ENABLED: { |
- AddExtensionEvent(EVENT_EXTENSION_ENABLE, |
- content::Details<Extension>(details).ptr()); |
- break; |
- } |
- case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { |
- const UnloadedExtensionInfo* info = |
- content::Details<UnloadedExtensionInfo>(details).ptr(); |
- |
- // Check if the extension was unloaded because it was disabled. |
- if (info->reason == UnloadedExtensionInfo::REASON_DISABLE) { |
- AddExtensionEvent(EVENT_EXTENSION_DISABLE, |
- info->extension); |
- } |
- break; |
- } |
- case extensions::NOTIFICATION_CRX_INSTALLER_DONE: { |
- const extensions::CrxInstaller* installer = |
- content::Source<extensions::CrxInstaller>(source).ptr(); |
- const extensions::Extension* extension = |
- content::Details<Extension>(details).ptr(); |
- |
- // Check if the reason for the install was due to a successful |
- // extension update. |extension| is NULL in case of install failure. |
- if (extension && |
- installer->install_cause() == extension_misc::INSTALL_CAUSE_UPDATE) { |
- AddExtensionEvent(EVENT_EXTENSION_UPDATE, extension); |
- } |
- break; |
- } |
- case extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED: { |
- AddExtensionEvent(EVENT_EXTENSION_UNINSTALL, |
- content::Details<Extension>(details).ptr()); |
- break; |
- } |
-#endif // defined(ENABLE_EXTENSIONS) |
- case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG: { |
- std::string url; |
- content::RenderWidgetHost* widget = |
- content::Source<content::RenderWidgetHost>(source).ptr(); |
- if (widget->IsRenderView()) { |
- content::RenderViewHost* view = content::RenderViewHost::From(widget); |
- MaybeGetURLFromRenderView(view, &url); |
- } |
- AddEvent(util::CreateRendererFailureEvent(base::Time::Now(), |
- EVENT_RENDERER_HANG, |
- url)); |
- break; |
- } |
- case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
- AddRendererClosedEvent( |
- content::Source<content::RenderProcessHost>(source).ptr(), |
- *content::Details<content::RenderProcessHost::RendererClosedDetails>( |
- details).ptr()); |
- break; |
- } |
- case chrome::NOTIFICATION_PROFILE_ADDED: { |
- Profile* profile = content::Source<Profile>(source).ptr(); |
- if (profile->GetLastSessionExitType() == Profile::EXIT_CRASHED) { |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind( |
- &PerformanceMonitor::AddUncleanExitEventOnBackgroundThread, |
- base::Unretained(this), |
- profile->GetDebugName())); |
- } |
- break; |
- } |
- case content::NOTIFICATION_LOAD_STOP: { |
- const content::LoadNotificationDetails* load_details = |
- content::Details<content::LoadNotificationDetails>(details).ptr(); |
- if (!load_details) |
- break; |
- BrowserThread::PostBlockingPoolSequencedTask( |
- Database::kDatabaseSequenceToken, |
- FROM_HERE, |
- base::Bind( |
- &PerformanceMonitor::AddMetricOnBackgroundThread, |
- base::Unretained(this), |
- Metric(METRIC_PAGE_LOAD_TIME, |
- base::Time::Now(), |
- static_cast<double>( |
- load_details->load_time.ToInternalValue())))); |
- break; |
- } |
- default: { |
- NOTREACHED(); |
- break; |
- } |
- } |
-} |
- |
-#if defined(ENABLE_EXTENSIONS) |
-void PerformanceMonitor::AddExtensionEvent(EventType type, |
- const Extension* extension) { |
- DCHECK(type == EVENT_EXTENSION_INSTALL || |
- type == EVENT_EXTENSION_UNINSTALL || |
- type == EVENT_EXTENSION_UPDATE || |
- type == EVENT_EXTENSION_ENABLE || |
- type == EVENT_EXTENSION_DISABLE); |
- AddEvent(util::CreateExtensionEvent(type, |
- base::Time::Now(), |
- extension->id(), |
- extension->name(), |
- extension->url().spec(), |
- extension->location(), |
- extension->VersionString(), |
- extension->description())); |
-} |
-#endif // defined(ENABLE_EXTENSIONS) |
- |
-void PerformanceMonitor::AddRendererClosedEvent( |
- content::RenderProcessHost* host, |
- const content::RenderProcessHost::RendererClosedDetails& details) { |
- // We only care if this is an invalid termination. |
- if (details.status == base::TERMINATION_STATUS_NORMAL_TERMINATION || |
- details.status == base::TERMINATION_STATUS_STILL_RUNNING) |
- return; |
- |
- // Determine the type of crash. |
- EventType type = |
- details.status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? |
- EVENT_RENDERER_KILLED : EVENT_RENDERER_CRASH; |
- |
- // A RenderProcessHost may contain multiple render views - for each valid |
- // render view, extract the url, and append it to the string, comma-separating |
- // the entries. |
- std::string url_list; |
- scoped_ptr<content::RenderWidgetHostIterator> widgets( |
- content::RenderWidgetHost::GetRenderWidgetHosts()); |
- while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
- if (widget->GetProcess()->GetID() != host->GetID()) |
- continue; |
- if (!widget->IsRenderView()) |
- continue; |
- |
- content::RenderViewHost* view = content::RenderViewHost::From(widget); |
- std::string url; |
- if (!MaybeGetURLFromRenderView(view, &url)) |
- continue; |
- |
- if (!url_list.empty()) |
- url_list += ", "; |
- |
- url_list += url; |
- } |
- |
- AddEvent(util::CreateRendererFailureEvent(base::Time::Now(), type, url_list)); |
} |
} // namespace performance_monitor |