Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: chrome/browser/metrics/metrics_service.cc

Issue 2735005: Merge 49197 - Submitting CL http://codereview.chromium.org/2324001 on behalf ... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/418/src/
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 5
6 6
7 //------------------------------------------------------------------------------ 7 //------------------------------------------------------------------------------
8 // Description of the life cycle of a instance of MetricsService. 8 // Description of the life cycle of a instance of MetricsService.
9 // 9 //
10 // OVERVIEW 10 // OVERVIEW
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // shutdown," involves the deliberate user termination of the process before 75 // shutdown," involves the deliberate user termination of the process before
76 // the initial log is even formed or transmitted. In that situation, no logging 76 // the initial log is even formed or transmitted. In that situation, no logging
77 // is done, but the historical crash statistics remain (unlogged) for inclusion 77 // is done, but the historical crash statistics remain (unlogged) for inclusion
78 // in a future run's initial log. (i.e., we don't lose crash stats). 78 // in a future run's initial log. (i.e., we don't lose crash stats).
79 // 79 //
80 // With the above overview, we can now describe the state machine's various 80 // With the above overview, we can now describe the state machine's various
81 // stats, based on the State enum specified in the state_ member. Those states 81 // stats, based on the State enum specified in the state_ member. Those states
82 // are: 82 // are:
83 // 83 //
84 // INITIALIZED, // Constructor was called. 84 // INITIALIZED, // Constructor was called.
85 // PLUGIN_LIST_REQUESTED, // Waiting for plugin list to be loaded. 85 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete.
86 // PLUGIN_LIST_ARRIVED, // Waiting for timer to send initial log. 86 // INIT_TASK_DONE, // Waiting for timer to send initial log.
87 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply. 87 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply.
88 // SEND_OLD_INITIAL_LOGS, // Sending unsent logs from previous session. 88 // SEND_OLD_INITIAL_LOGS, // Sending unsent logs from previous session.
89 // SENDING_OLD_LOGS, // Sending unsent logs from previous session. 89 // SENDING_OLD_LOGS, // Sending unsent logs from previous session.
90 // SENDING_CURRENT_LOGS, // Sending standard current logs as they accrue. 90 // SENDING_CURRENT_LOGS, // Sending standard current logs as they accrue.
91 // 91 //
92 // In more detail, we have: 92 // In more detail, we have:
93 // 93 //
94 // INITIALIZED, // Constructor was called. 94 // INITIALIZED, // Constructor was called.
95 // The MS has been constructed, but has taken no actions to compose the 95 // The MS has been constructed, but has taken no actions to compose the
96 // initial log. 96 // initial log.
97 // 97 //
98 // PLUGIN_LIST_REQUESTED, // Waiting for plugin list to be loaded. 98 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete.
99 // Typically about 30 seconds after startup, a task is sent to a second thread 99 // Typically about 30 seconds after startup, a task is sent to a second thread
100 // to get the list of plugins. That task will (when complete) make an async 100 // (the file thread) to perform deferred (lower priority and slower)
101 // callback (via a Task) to indicate the completion. 101 // initialization steps such as getting the list of plugins. That task will
102 // (when complete) make an async callback (via a Task) to indicate the
103 // completion.
102 // 104 //
103 // PLUGIN_LIST_ARRIVED, // Waiting for timer to send initial log. 105 // INIT_TASK_DONE, // Waiting for timer to send initial log.
104 // The callback has arrived, and it is now possible for an initial log to be 106 // The callback has arrived, and it is now possible for an initial log to be
105 // created. This callback typically arrives back less than one second after 107 // created. This callback typically arrives back less than one second after
106 // the task is dispatched. 108 // the deferred init task is dispatched.
107 // 109 //
108 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply. 110 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply.
109 // This state is entered only after an initial log has been composed, and 111 // This state is entered only after an initial log has been composed, and
110 // prepared for transmission. It is also the case that any previously unsent 112 // prepared for transmission. It is also the case that any previously unsent
111 // logs have been loaded into instance variables for possible transmission. 113 // logs have been loaded into instance variables for possible transmission.
112 // 114 //
113 // SEND_OLD_INITIAL_LOGS, // Sending unsent logs from previous session. 115 // SEND_OLD_INITIAL_LOGS, // Sending unsent logs from previous session.
114 // This state indicates that the initial log for this session has been 116 // This state indicates that the initial log for this session has been
115 // successfully sent and it is now time to send any "initial logs" that were 117 // successfully sent and it is now time to send any "initial logs" that were
116 // saved from previous sessions. Most commonly, there are none, but all old 118 // saved from previous sessions. Most commonly, there are none, but all old
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 #include "base/rand_util.h" 192 #include "base/rand_util.h"
191 #endif 193 #endif
192 194
193 // TODO(port): port browser_distribution.h. 195 // TODO(port): port browser_distribution.h.
194 #if !defined(OS_POSIX) 196 #if !defined(OS_POSIX)
195 #include "chrome/installer/util/browser_distribution.h" 197 #include "chrome/installer/util/browser_distribution.h"
196 #endif 198 #endif
197 199
198 #if defined(OS_CHROMEOS) 200 #if defined(OS_CHROMEOS)
199 #include "chrome/browser/chromeos/external_metrics.h" 201 #include "chrome/browser/chromeos/external_metrics.h"
202
203 static const char kHardwareClassTool[] = "/usr/bin/hardware_class";
204 static const char kUnknownHardwareClass[] = "unknown";
200 #endif 205 #endif
201 206
202 using base::Time; 207 using base::Time;
203 using base::TimeDelta; 208 using base::TimeDelta;
204 209
205 // Check to see that we're being called on only one thread. 210 // Check to see that we're being called on only one thread.
206 static bool IsSingleThreaded(); 211 static bool IsSingleThreaded();
207 212
208 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; 213 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2";
209 214
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 MessageLoop::current()->PostTask(FROM_HERE, completion_); 280 MessageLoop::current()->PostTask(FROM_HERE, completion_);
276 } 281 }
277 282
278 private: 283 private:
279 ~MetricsMemoryDetails() {} 284 ~MetricsMemoryDetails() {}
280 285
281 Task* completion_; 286 Task* completion_;
282 DISALLOW_EVIL_CONSTRUCTORS(MetricsMemoryDetails); 287 DISALLOW_EVIL_CONSTRUCTORS(MetricsMemoryDetails);
283 }; 288 };
284 289
285 class MetricsService::GetPluginListTaskComplete : public Task { 290 class MetricsService::InitTaskComplete : public Task {
286 public: 291 public:
287 explicit GetPluginListTaskComplete( 292 explicit InitTaskComplete(const std::string& hardware_class,
288 const std::vector<WebPluginInfo>& plugins) : plugins_(plugins) { } 293 const std::vector<WebPluginInfo>& plugins)
294 : hardware_class_(hardware_class), plugins_(plugins) {}
295
289 virtual void Run() { 296 virtual void Run() {
290 g_browser_process->metrics_service()->OnGetPluginListTaskComplete(plugins_); 297 g_browser_process->metrics_service()->OnInitTaskComplete(
298 hardware_class_, plugins_);
291 } 299 }
292 300
293 private: 301 private:
302 std::string hardware_class_;
294 std::vector<WebPluginInfo> plugins_; 303 std::vector<WebPluginInfo> plugins_;
295 }; 304 };
296 305
297 class MetricsService::GetPluginListTask : public Task { 306 class MetricsService::InitTask : public Task {
298 public: 307 public:
299 explicit GetPluginListTask(MessageLoop* callback_loop) 308 explicit InitTask(MessageLoop* callback_loop)
300 : callback_loop_(callback_loop) {} 309 : callback_loop_(callback_loop) {}
301 310
302 virtual void Run() { 311 virtual void Run() {
303 std::vector<WebPluginInfo> plugins; 312 std::vector<WebPluginInfo> plugins;
304 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); 313 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
305 314 std::string hardware_class; // Empty string by default.
306 callback_loop_->PostTask( 315 #if defined(OS_CHROMEOS)
307 FROM_HERE, new GetPluginListTaskComplete(plugins)); 316 hardware_class = MetricsService::GetHardwareClass();
317 #endif // OS_CHROMEOS
318 callback_loop_->PostTask(FROM_HERE, new InitTaskComplete(
319 hardware_class, plugins));
308 } 320 }
309 321
310 private: 322 private:
311 MessageLoop* callback_loop_; 323 MessageLoop* callback_loop_;
312 }; 324 };
313 325
314 // static 326 // static
315 void MetricsService::RegisterPrefs(PrefService* local_state) { 327 void MetricsService::RegisterPrefs(PrefService* local_state) {
316 DCHECK(IsSingleThreaded()); 328 DCHECK(IsSingleThreaded());
317 local_state->RegisterStringPref(prefs::kMetricsClientID, L""); 329 local_state->RegisterStringPref(prefs::kMetricsClientID, L"");
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", 750 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount",
739 command_line->GetSwitchCount()); 751 command_line->GetSwitchCount());
740 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount", 752 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
741 command_line->GetSwitchCount() - common_commands); 753 command_line->GetSwitchCount() - common_commands);
742 754
743 // Kick off the process of saving the state (so the uptime numbers keep 755 // Kick off the process of saving the state (so the uptime numbers keep
744 // getting updated) every n minutes. 756 // getting updated) every n minutes.
745 ScheduleNextStateSave(); 757 ScheduleNextStateSave();
746 } 758 }
747 759
748 void MetricsService::OnGetPluginListTaskComplete( 760 void MetricsService::OnInitTaskComplete(
761 const std::string& hardware_class,
749 const std::vector<WebPluginInfo>& plugins) { 762 const std::vector<WebPluginInfo>& plugins) {
750 DCHECK(state_ == PLUGIN_LIST_REQUESTED); 763 DCHECK(state_ == INIT_TASK_SCHEDULED);
764 hardware_class_ = hardware_class;
751 plugins_ = plugins; 765 plugins_ = plugins;
752 if (state_ == PLUGIN_LIST_REQUESTED) 766 if (state_ == INIT_TASK_SCHEDULED)
753 state_ = PLUGIN_LIST_ARRIVED; 767 state_ = INIT_TASK_DONE;
754 } 768 }
755 769
756 std::string MetricsService::GenerateClientID() { 770 std::string MetricsService::GenerateClientID() {
757 #if defined(OS_WIN) 771 #if defined(OS_WIN)
758 const int kGUIDSize = 39; 772 const int kGUIDSize = 39;
759 773
760 GUID guid; 774 GUID guid;
761 HRESULT guid_result = CoCreateGuid(&guid); 775 HRESULT guid_result = CoCreateGuid(&guid);
762 DCHECK(SUCCEEDED(guid_result)); 776 DCHECK(SUCCEEDED(guid_result));
763 777
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 //------------------------------------------------------------------------------ 829 //------------------------------------------------------------------------------
816 // Recording control methods 830 // Recording control methods
817 831
818 void MetricsService::StartRecording() { 832 void MetricsService::StartRecording() {
819 if (current_log_) 833 if (current_log_)
820 return; 834 return;
821 835
822 current_log_ = new MetricsLog(client_id_, session_id_); 836 current_log_ = new MetricsLog(client_id_, session_id_);
823 if (state_ == INITIALIZED) { 837 if (state_ == INITIALIZED) {
824 // We only need to schedule that run once. 838 // We only need to schedule that run once.
825 state_ = PLUGIN_LIST_REQUESTED; 839 state_ = INIT_TASK_SCHEDULED;
826 840
827 // Make sure the plugin list is loaded before the inital log is sent, so 841 // Schedules a task on the file thread for execution of slower
828 // that the main thread isn't blocked generating the list. 842 // initialization steps (such as plugin list generation) necessary
843 // for sending the initial log. This avoids blocking the main UI
844 // thread.
829 g_browser_process->file_thread()->message_loop()->PostDelayedTask(FROM_HERE, 845 g_browser_process->file_thread()->message_loop()->PostDelayedTask(FROM_HERE,
830 new GetPluginListTask(MessageLoop::current()), 846 new InitTask(MessageLoop::current()),
831 kInitialInterlogDuration * 1000 / 2); 847 kInitialInterlogDuration * 1000 / 2);
832 } 848 }
833 } 849 }
834 850
835 void MetricsService::StopRecording(MetricsLog** log) { 851 void MetricsService::StopRecording(MetricsLog** log) {
836 if (!current_log_) 852 if (!current_log_)
837 return; 853 return;
838 854
855 current_log_->set_hardware_class(hardware_class_); // Adds to ongoing logs.
856
839 // TODO(jar): Integrate bounds on log recording more consistently, so that we 857 // TODO(jar): Integrate bounds on log recording more consistently, so that we
840 // can stop recording logs that are too big much sooner. 858 // can stop recording logs that are too big much sooner.
841 if (current_log_->num_events() > log_event_limit_) { 859 if (current_log_->num_events() > log_event_limit_) {
842 UMA_HISTOGRAM_COUNTS("UMA.Discarded Log Events", 860 UMA_HISTOGRAM_COUNTS("UMA.Discarded Log Events",
843 current_log_->num_events()); 861 current_log_->num_events());
844 current_log_->CloseLog(); 862 current_log_->CloseLog();
845 delete current_log_; 863 delete current_log_;
846 current_log_ = NULL; 864 current_log_ = NULL;
847 StartRecording(); // Start trivial log to hold our histograms. 865 StartRecording(); // Start trivial log to hold our histograms.
848 } 866 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 HandleIdleSinceLastTransmission(true); 1061 HandleIdleSinceLastTransmission(true);
1044 } 1062 }
1045 1063
1046 1064
1047 void MetricsService::MakePendingLog() { 1065 void MetricsService::MakePendingLog() {
1048 if (pending_log()) 1066 if (pending_log())
1049 return; 1067 return;
1050 1068
1051 switch (state_) { 1069 switch (state_) {
1052 case INITIALIZED: 1070 case INITIALIZED:
1053 case PLUGIN_LIST_REQUESTED: // We should be further along by now. 1071 case INIT_TASK_SCHEDULED: // We should be further along by now.
1054 DCHECK(false); 1072 DCHECK(false);
1055 return; 1073 return;
1056 1074
1057 case PLUGIN_LIST_ARRIVED: 1075 case INIT_TASK_DONE:
1058 // We need to wait for the initial log to be ready before sending 1076 // We need to wait for the initial log to be ready before sending
1059 // anything, because the server will tell us whether it wants to hear 1077 // anything, because the server will tell us whether it wants to hear
1060 // from us. 1078 // from us.
1061 PrepareInitialLog(); 1079 PrepareInitialLog();
1062 DCHECK(state_ == PLUGIN_LIST_ARRIVED); 1080 DCHECK(state_ == INIT_TASK_DONE);
1063 RecallUnsentLogs(); 1081 RecallUnsentLogs();
1064 state_ = INITIAL_LOG_READY; 1082 state_ = INITIAL_LOG_READY;
1065 break; 1083 break;
1066 1084
1067 case SEND_OLD_INITIAL_LOGS: 1085 case SEND_OLD_INITIAL_LOGS:
1068 if (!unsent_initial_logs_.empty()) { 1086 if (!unsent_initial_logs_.empty()) {
1069 pending_log_text_ = unsent_initial_logs_.back(); 1087 pending_log_text_ = unsent_initial_logs_.back();
1070 break; 1088 break;
1071 } 1089 }
1072 state_ = SENDING_OLD_LOGS; 1090 state_ = SENDING_OLD_LOGS;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 case SENDING_OLD_LOGS: 1127 case SENDING_OLD_LOGS:
1110 return true; 1128 return true;
1111 1129
1112 case SENDING_CURRENT_LOGS: 1130 case SENDING_CURRENT_LOGS:
1113 default: 1131 default:
1114 return false; 1132 return false;
1115 } 1133 }
1116 } 1134 }
1117 1135
1118 void MetricsService::PrepareInitialLog() { 1136 void MetricsService::PrepareInitialLog() {
1119 DCHECK(state_ == PLUGIN_LIST_ARRIVED); 1137 DCHECK(state_ == INIT_TASK_DONE);
1120 1138
1121 MetricsLog* log = new MetricsLog(client_id_, session_id_); 1139 MetricsLog* log = new MetricsLog(client_id_, session_id_);
1140 log->set_hardware_class(hardware_class_); // Adds to initial log.
1122 log->RecordEnvironment(plugins_, profile_dictionary_.get()); 1141 log->RecordEnvironment(plugins_, profile_dictionary_.get());
1123 1142
1124 // Histograms only get written to current_log_, so setup for the write. 1143 // Histograms only get written to current_log_, so setup for the write.
1125 MetricsLog* save_log = current_log_; 1144 MetricsLog* save_log = current_log_;
1126 current_log_ = log; 1145 current_log_ = log;
1127 RecordCurrentHistograms(); // Into current_log_... which is really log. 1146 RecordCurrentHistograms(); // Into current_log_... which is really log.
1128 current_log_ = save_log; 1147 current_log_ = save_log;
1129 1148
1130 log->CloseLog(); 1149 log->CloseLog();
1131 DCHECK(!pending_log()); 1150 DCHECK(!pending_log());
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 } 1922 }
1904 1923
1905 static bool IsSingleThreaded() { 1924 static bool IsSingleThreaded() {
1906 static PlatformThreadId thread_id = 0; 1925 static PlatformThreadId thread_id = 0;
1907 if (!thread_id) 1926 if (!thread_id)
1908 thread_id = PlatformThread::CurrentId(); 1927 thread_id = PlatformThread::CurrentId();
1909 return PlatformThread::CurrentId() == thread_id; 1928 return PlatformThread::CurrentId() == thread_id;
1910 } 1929 }
1911 1930
1912 #if defined(OS_CHROMEOS) 1931 #if defined(OS_CHROMEOS)
1932 // static
1933 std::string MetricsService::GetHardwareClass() {
1934 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI));
1935 std::string hardware_class;
1936 FilePath tool(kHardwareClassTool);
1937 CommandLine command(tool);
1938 if (base::GetAppOutput(command, &hardware_class)) {
1939 TrimWhitespaceASCII(hardware_class, TRIM_ALL, &hardware_class);
1940 } else {
1941 hardware_class = kUnknownHardwareClass;
1942 }
1943 return hardware_class;
1944 }
1945
1913 void MetricsService::StartExternalMetrics() { 1946 void MetricsService::StartExternalMetrics() {
1914 external_metrics_ = new chromeos::ExternalMetrics; 1947 external_metrics_ = new chromeos::ExternalMetrics;
1915 external_metrics_->Start(); 1948 external_metrics_->Start();
1916 } 1949 }
1917 #endif 1950 #endif
OLDNEW
« no previous file with comments | « chrome/browser/metrics/metrics_service.h ('k') | chrome/browser/metrics/metrics_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698