Index: chrome/browser/metrics/metrics_service.cc |
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc |
index c691f70268c9ebff8018cb199862dd7ed64c8ed1..da8afb5377f99f97f66fb88dd771df3540e19055 100644 |
--- a/chrome/browser/metrics/metrics_service.cc |
+++ b/chrome/browser/metrics/metrics_service.cc |
@@ -89,11 +89,10 @@ |
// initial log. |
// |
// INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete. |
-// Typically about 30 seconds after startup, a task is sent to a second thread |
-// (the file thread) to perform deferred (lower priority and slower) |
-// initialization steps such as getting the list of plugins. That task will |
-// (when complete) make an async callback (via a Task) to indicate the |
-// completion. |
+// Typically about 30 seconds after startup, a task is posted to perform |
+// deferred (lower priority and slower) initialization steps such as getting the |
+// list of plugins. That task will (when complete) make an async callback (via |
+// a Task) to indicate the completion. |
// |
// INIT_TASK_DONE, // Waiting for timer to send initial log. |
// The callback has arrived, and it is now possible for an initial log to be |
@@ -199,7 +198,6 @@ |
#if defined(OS_CHROMEOS) |
#include "chrome/browser/chromeos/cros/cros_library.h" |
#include "chrome/browser/chromeos/external_metrics.h" |
-#include "chrome/browser/chromeos/system/statistics_provider.h" |
#endif |
using base::Time; |
@@ -222,6 +220,10 @@ bool IsSingleThreaded() { |
// initialization work. |
const int kInitializationDelaySeconds = 30; |
+// The timeout, in seconds, to resume initialization of the MetricsService if |
+// the initialization of the StatisticsProvider hasn't completed yet. |
+const int kStatisticsProviderTimeoutSeconds = 300; |
+ |
// This specifies the amount of time to wait for all renderers to send their |
// data. |
const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. |
@@ -243,6 +245,11 @@ const int kSaveStateIntervalMinutes = 5; |
// e.g., the server is down. |
const int kNoResponseCode = content::URLFetcher::RESPONSE_CODE_INVALID - 1; |
+// Used to indicate that a report was generated before the hardware_class |
+// property was available from the StatisticsProvider. This is used to identify |
+// faulty reports from Chrome OS clients. |
+const char kHardwareClassNotReady[] = "(not ready)"; |
+ |
} |
// static |
@@ -406,6 +413,9 @@ MetricsService::MetricsService() |
MetricsService::~MetricsService() { |
SetRecording(false); |
+#if defined(OS_CHROMEOS) |
+ chromeos::system::StatisticsProvider::GetInstance()->RemoveObserver(this); |
+#endif |
} |
void MetricsService::Start() { |
@@ -750,32 +760,65 @@ void MetricsService::InitializeMetricsState() { |
ScheduleNextStateSave(); |
} |
-// static |
-void MetricsService::InitTaskGetHardwareClass( |
- base::WeakPtr<MetricsService> self, |
- base::MessageLoopProxy* target_loop) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+void MetricsService::InitTaskGetHardwareClass() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
- std::string hardware_class; |
#if defined(OS_CHROMEOS) |
+ // Exactly one of these two callbacks will be invoked. |timeout_callback_| |
+ // is posted to UI with a certain delay; |on_ready_callback_| is invoked |
+ // once the StatisticsProvider() becomes ready. Execution of one of these |
+ // callbacks cancels the execution of the other. |
+ timeout_callback_.Reset( |
+ base::Bind(&MetricsService::OnStatisticsProviderTimeout, |
+ base::Unretained(this))); |
+ on_ready_callback_.Reset( |
+ base::Bind(&MetricsService::InitTaskGetPluginInfo, |
+ base::Unretained(this))); |
+ |
+ BrowserThread::PostDelayedTask( |
+ BrowserThread::UI, FROM_HERE, |
+ timeout_callback_.callback(), |
+ base::TimeDelta::FromSeconds(kStatisticsProviderTimeoutSeconds)); |
+ |
+ // The hardware class can only be retrieved once the StatisticsProvider is |
+ // ready. This usually happens early enough, but can take longer on some |
+ // faulty hardware. |
+ chromeos::system::StatisticsProvider::GetInstance()->AddObserver(this); |
+#else |
+ InitTaskGetPluginInfo(); |
+#endif |
Ilya Sherman
2012/05/16 01:01:17
nit: Please add " // #if defined(OS_CHROMEOS)"
Joao da Silva
2012/05/16 12:53:34
Done.
|
+} |
+ |
+#if defined(OS_CHROMEOS) |
+ |
+void MetricsService::OnMachineStatisticsReady() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic( |
- "hardware_class", &hardware_class); |
-#endif // OS_CHROMEOS |
+ "hardware_class", &hardware_class_); |
+ timeout_callback_.Cancel(); |
+ if (!on_ready_callback_.IsCancelled()) |
+ on_ready_callback_.callback().Run(); |
+} |
- target_loop->PostTask(FROM_HERE, |
- base::Bind(&MetricsService::OnInitTaskGotHardwareClass, |
- self, hardware_class)); |
+void MetricsService::OnStatisticsProviderTimeout() { |
Ilya Sherman
2012/05/16 01:01:17
nit: DCHECK to make sure we're still on the UI thr
Joao da Silva
2012/05/16 12:53:34
Done.
|
+ // Use an invalid hardware_class temporarily until the StatisticsProvider is |
+ // ready. |
+ hardware_class_ = kHardwareClassNotReady; |
+ on_ready_callback_.Cancel(); |
+ InitTaskGetPluginInfo(); |
} |
-void MetricsService::OnInitTaskGotHardwareClass( |
- const std::string& hardware_class) { |
+#endif |
Ilya Sherman
2012/05/16 01:01:17
nit: Ditto
Joao da Silva
2012/05/16 12:53:34
Done.
|
+ |
+void MetricsService::InitTaskGetPluginInfo() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
- hardware_class_ = hardware_class; |
// Start the next part of the init task: loading plugin information. |
PluginService::GetInstance()->GetPlugins( |
base::Bind(&MetricsService::OnInitTaskGotPluginInfo, |
- self_ptr_factory_.GetWeakPtr())); |
+ self_ptr_factory_.GetWeakPtr())); |
} |
void MetricsService::OnInitTaskGotPluginInfo( |
@@ -892,16 +935,12 @@ void MetricsService::StartRecording() { |
// We only need to schedule that run once. |
state_ = INIT_TASK_SCHEDULED; |
- // Schedules a task on the file thread for execution of slower |
- // initialization steps (such as plugin list generation) necessary |
- // for sending the initial log. This avoids blocking the main UI |
- // thread. |
- BrowserThread::PostDelayedTask( |
- BrowserThread::FILE, |
+ // Schedules a delayed task for execution of slower initialization steps |
+ // (such as plugin list generation) necessary for sending the initial log. |
+ MessageLoop::current()->PostDelayedTask( |
FROM_HERE, |
base::Bind(&MetricsService::InitTaskGetHardwareClass, |
- self_ptr_factory_.GetWeakPtr(), |
- MessageLoop::current()->message_loop_proxy()), |
+ self_ptr_factory_.GetWeakPtr()), |
base::TimeDelta::FromSeconds(kInitializationDelaySeconds)); |
} |
} |