| 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..3e2cfdbe31230c82673565221d8a31db1fa1eaac 100644
|
| --- a/chrome/browser/performance_monitor/performance_monitor.cc
|
| +++ b/chrome/browser/performance_monitor/performance_monitor.cc
|
| @@ -4,130 +4,30 @@
|
|
|
| #include "chrome/browser/performance_monitor/performance_monitor.h"
|
|
|
| -#include <set>
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/command_line.h"
|
| -#include "base/logging.h"
|
| #include "base/memory/singleton.h"
|
| #include "base/process/process_iterator.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/threading/worker_pool.h"
|
| #include "base/time/time.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#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"
|
| -#include "chrome/browser/ui/browser_iterator.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/chrome_version_info.h"
|
| #include "content/public/browser/browser_child_process_host.h"
|
| #include "content/public/browser/browser_child_process_host_iterator.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/child_process_data.h"
|
| -#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_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
|
| +#include "content/public/browser/render_process_host.h"
|
|
|
| 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);
|
| +// The default interval at which PerformanceMonitor performs its timed
|
| +// collections.
|
| +const int kGatherIntervalInSeconds = 120;
|
| }
|
| -#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) {
|
| -}
|
| +namespace performance_monitor {
|
|
|
| -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 +35,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();
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + repeating_timer_.Start(FROM_HERE,
|
| + base::TimeDelta::FromSeconds(kGatherIntervalInSeconds),
|
| + this,
|
| + &PerformanceMonitor::GatherMetricsMapOnUIThread);
|
| }
|
|
|
| void PerformanceMonitor::GatherMetricsMapOnUIThread() {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK_CURRENTLY_ON(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 +69,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,40 +88,9 @@ 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));
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
|
|
| // Find all child processes (does not include renderers), which has to be
|
| // done on the IO thread.
|
| @@ -471,29 +105,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 +119,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
|
|
|