Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/metrics/metrics_log.h" | 5 #include "chrome/browser/metrics/omnibox_metrics_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 #include <string> | |
| 9 #include <vector> | 7 #include <vector> |
| 10 | 8 |
| 11 #include "base/base64.h" | 9 #include "base/logging.h" |
| 12 #include "base/basictypes.h" | 10 #include "base/strings/string16.h" |
| 13 #include "base/bind.h" | |
| 14 #include "base/cpu.h" | |
| 15 #include "base/lazy_instance.h" | |
| 16 #include "base/memory/scoped_ptr.h" | |
| 17 #include "base/prefs/pref_registry_simple.h" | |
| 18 #include "base/prefs/pref_service.h" | |
| 19 #include "base/profiler/alternate_timer.h" | |
| 20 #include "base/sha1.h" | |
| 21 #include "base/strings/string_number_conversions.h" | |
| 22 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 23 #include "base/strings/utf_string_conversions.h" | |
| 24 #include "base/sys_info.h" | |
| 25 #include "base/third_party/nspr/prtime.h" | |
| 26 #include "base/time/time.h" | |
| 27 #include "base/tracked_objects.h" | |
| 28 #include "chrome/browser/autocomplete/autocomplete_input.h" | 12 #include "chrome/browser/autocomplete/autocomplete_input.h" |
| 29 #include "chrome/browser/autocomplete/autocomplete_match.h" | 13 #include "chrome/browser/autocomplete/autocomplete_match.h" |
| 30 #include "chrome/browser/autocomplete/autocomplete_provider.h" | 14 #include "chrome/browser/autocomplete/autocomplete_provider.h" |
| 31 #include "chrome/browser/autocomplete/autocomplete_result.h" | 15 #include "chrome/browser/autocomplete/autocomplete_result.h" |
| 32 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
| 33 #include "chrome/browser/google/google_util.h" | |
| 34 #include "chrome/browser/metrics/extension_metrics.h" | |
| 35 #include "chrome/browser/omnibox/omnibox_log.h" | 17 #include "chrome/browser/omnibox/omnibox_log.h" |
| 36 #include "chrome/browser/plugins/plugin_prefs.h" | 18 #include "components/metrics/metrics_log_base.h" |
| 37 #include "chrome/browser/profiles/profile_manager.h" | 19 #include "content/public/browser/notification_service.h" |
| 38 #include "chrome/common/chrome_version_info.h" | |
| 39 #include "chrome/common/pref_names.h" | |
| 40 #include "chrome/installer/util/google_update_settings.h" | |
| 41 #include "components/metrics/proto/omnibox_event.pb.h" | |
| 42 #include "components/metrics/proto/profiler_event.pb.h" | |
| 43 #include "components/metrics/proto/system_profile.pb.h" | |
| 44 #include "components/nacl/common/nacl_process_type.h" | |
| 45 #include "components/variations/active_field_trials.h" | |
| 46 #include "content/public/browser/gpu_data_manager.h" | |
| 47 #include "content/public/common/content_client.h" | |
| 48 #include "content/public/common/webplugininfo.h" | |
| 49 #include "gpu/config/gpu_info.h" | |
| 50 #include "ui/gfx/screen.h" | |
| 51 #include "url/gurl.h" | |
| 52 | 20 |
| 53 #if defined(OS_ANDROID) | |
| 54 #include "base/android/build_info.h" | |
| 55 #endif | |
| 56 | |
| 57 #if defined(OS_WIN) | |
| 58 #include "base/win/metro.h" | |
| 59 | |
| 60 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | |
| 61 extern "C" IMAGE_DOS_HEADER __ImageBase; | |
| 62 #endif | |
| 63 | |
| 64 #if defined(OS_CHROMEOS) | |
| 65 #include "chrome/browser/metrics/metrics_log_chromeos.h" | |
| 66 #endif // OS_CHROMEOS | |
| 67 | |
| 68 using content::GpuDataManager; | |
| 69 using metrics::MetricsLogBase; | |
| 70 using metrics::OmniboxEventProto; | 21 using metrics::OmniboxEventProto; |
| 71 using metrics::ProfilerEventProto; | |
| 72 using metrics::SystemProfileProto; | |
| 73 using tracked_objects::ProcessDataSnapshot; | |
| 74 typedef variations::ActiveGroupId ActiveGroupId; | |
| 75 typedef SystemProfileProto::GoogleUpdate::ProductInfo ProductInfo; | |
| 76 | 22 |
| 77 namespace { | 23 namespace { |
| 78 | 24 |
| 79 // Returns the date at which the current metrics client ID was created as | |
| 80 // a string containing seconds since the epoch, or "0" if none was found. | |
| 81 std::string GetMetricsEnabledDate(PrefService* pref) { | |
| 82 if (!pref) { | |
| 83 NOTREACHED(); | |
| 84 return "0"; | |
| 85 } | |
| 86 | |
| 87 return pref->GetString(prefs::kMetricsReportingEnabledTimestamp); | |
| 88 } | |
| 89 | |
| 90 OmniboxEventProto::InputType AsOmniboxEventInputType( | 25 OmniboxEventProto::InputType AsOmniboxEventInputType( |
| 91 AutocompleteInput::Type type) { | 26 AutocompleteInput::Type type) { |
| 92 switch (type) { | 27 switch (type) { |
| 93 case AutocompleteInput::INVALID: | 28 case AutocompleteInput::INVALID: |
| 94 return OmniboxEventProto::INVALID; | 29 return OmniboxEventProto::INVALID; |
| 95 case AutocompleteInput::UNKNOWN: | 30 case AutocompleteInput::UNKNOWN: |
| 96 return OmniboxEventProto::UNKNOWN; | 31 return OmniboxEventProto::UNKNOWN; |
| 97 case AutocompleteInput::URL: | 32 case AutocompleteInput::URL: |
| 98 return OmniboxEventProto::URL; | 33 return OmniboxEventProto::URL; |
| 99 case AutocompleteInput::QUERY: | 34 case AutocompleteInput::QUERY: |
| 100 return OmniboxEventProto::QUERY; | 35 return OmniboxEventProto::QUERY; |
| 101 case AutocompleteInput::FORCED_QUERY: | 36 case AutocompleteInput::FORCED_QUERY: |
| 102 return OmniboxEventProto::FORCED_QUERY; | 37 return OmniboxEventProto::FORCED_QUERY; |
| 103 default: | |
| 104 NOTREACHED(); | |
| 105 return OmniboxEventProto::INVALID; | |
| 106 } | 38 } |
| 39 NOTREACHED(); | |
| 40 return OmniboxEventProto::INVALID; | |
| 107 } | 41 } |
| 108 | 42 |
| 109 OmniboxEventProto::Suggestion::ResultType AsOmniboxEventResultType( | 43 OmniboxEventProto::Suggestion::ResultType AsOmniboxEventResultType( |
| 110 AutocompleteMatch::Type type) { | 44 AutocompleteMatch::Type type) { |
| 111 switch (type) { | 45 switch (type) { |
| 112 case AutocompleteMatchType::URL_WHAT_YOU_TYPED: | 46 case AutocompleteMatchType::URL_WHAT_YOU_TYPED: |
| 113 return OmniboxEventProto::Suggestion::URL_WHAT_YOU_TYPED; | 47 return OmniboxEventProto::Suggestion::URL_WHAT_YOU_TYPED; |
| 114 case AutocompleteMatchType::HISTORY_URL: | 48 case AutocompleteMatchType::HISTORY_URL: |
| 115 return OmniboxEventProto::Suggestion::HISTORY_URL; | 49 return OmniboxEventProto::Suggestion::HISTORY_URL; |
| 116 case AutocompleteMatchType::HISTORY_TITLE: | 50 case AutocompleteMatchType::HISTORY_TITLE: |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 137 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PROFILE; | 71 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PROFILE; |
| 138 case AutocompleteMatchType::SEARCH_OTHER_ENGINE: | 72 case AutocompleteMatchType::SEARCH_OTHER_ENGINE: |
| 139 return OmniboxEventProto::Suggestion::SEARCH_OTHER_ENGINE; | 73 return OmniboxEventProto::Suggestion::SEARCH_OTHER_ENGINE; |
| 140 case AutocompleteMatchType::EXTENSION_APP: | 74 case AutocompleteMatchType::EXTENSION_APP: |
| 141 return OmniboxEventProto::Suggestion::EXTENSION_APP; | 75 return OmniboxEventProto::Suggestion::EXTENSION_APP; |
| 142 case AutocompleteMatchType::BOOKMARK_TITLE: | 76 case AutocompleteMatchType::BOOKMARK_TITLE: |
| 143 return OmniboxEventProto::Suggestion::BOOKMARK_TITLE; | 77 return OmniboxEventProto::Suggestion::BOOKMARK_TITLE; |
| 144 case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED: | 78 case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED: |
| 145 return OmniboxEventProto::Suggestion::NAVSUGGEST_PERSONALIZED; | 79 return OmniboxEventProto::Suggestion::NAVSUGGEST_PERSONALIZED; |
| 146 default: | 80 default: |
| 81 // Note: Default case necessary due to NUM_TYPES enum entry. | |
|
Ilya Sherman
2014/05/20 15:26:49
Please instead have a "case NUM_TYPES: NOTREACHED(
Alexei Svitkine (slow)
2014/05/20 15:49:26
Done.
| |
| 147 NOTREACHED(); | 82 NOTREACHED(); |
| 148 return OmniboxEventProto::Suggestion::UNKNOWN_RESULT_TYPE; | 83 return OmniboxEventProto::Suggestion::UNKNOWN_RESULT_TYPE; |
| 149 } | 84 } |
| 150 } | 85 } |
| 151 | 86 |
| 152 OmniboxEventProto::PageClassification AsOmniboxEventPageClassification( | 87 OmniboxEventProto::PageClassification AsOmniboxEventPageClassification( |
| 153 AutocompleteInput::PageClassification page_classification) { | 88 AutocompleteInput::PageClassification page_classification) { |
| 154 switch (page_classification) { | 89 switch (page_classification) { |
| 155 case AutocompleteInput::INVALID_SPEC: | 90 case AutocompleteInput::INVALID_SPEC: |
| 156 return OmniboxEventProto::INVALID_SPEC; | 91 return OmniboxEventProto::INVALID_SPEC; |
| 157 case AutocompleteInput::NTP: | 92 case AutocompleteInput::NTP: |
| 158 return OmniboxEventProto::NTP; | 93 return OmniboxEventProto::NTP; |
| 159 case AutocompleteInput::BLANK: | 94 case AutocompleteInput::BLANK: |
| 160 return OmniboxEventProto::BLANK; | 95 return OmniboxEventProto::BLANK; |
| 161 case AutocompleteInput::HOME_PAGE: | 96 case AutocompleteInput::HOME_PAGE: |
| 162 return OmniboxEventProto::HOME_PAGE; | 97 return OmniboxEventProto::HOME_PAGE; |
| 163 case AutocompleteInput::OTHER: | 98 case AutocompleteInput::OTHER: |
| 164 return OmniboxEventProto::OTHER; | 99 return OmniboxEventProto::OTHER; |
| 165 case AutocompleteInput::SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT: | 100 case AutocompleteInput::SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT: |
| 166 return OmniboxEventProto:: | 101 return OmniboxEventProto:: |
| 167 SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT; | 102 SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT; |
| 168 case AutocompleteInput::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS: | 103 case AutocompleteInput::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS: |
| 169 return OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS; | 104 return OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS; |
| 170 case AutocompleteInput::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS: | 105 case AutocompleteInput::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS: |
| 171 return OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS; | 106 return OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS; |
| 172 case AutocompleteInput::SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT: | 107 case AutocompleteInput::SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT: |
| 173 return OmniboxEventProto:: | 108 return OmniboxEventProto:: |
| 174 SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT; | 109 SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT; |
| 175 } | 110 } |
| 111 NOTREACHED(); | |
| 176 return OmniboxEventProto::INVALID_SPEC; | 112 return OmniboxEventProto::INVALID_SPEC; |
| 177 } | 113 } |
| 178 | 114 |
| 179 ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType( | |
| 180 int process_type) { | |
| 181 switch (process_type) { | |
| 182 case content::PROCESS_TYPE_BROWSER: | |
| 183 return ProfilerEventProto::TrackedObject::BROWSER; | |
| 184 case content::PROCESS_TYPE_RENDERER: | |
| 185 return ProfilerEventProto::TrackedObject::RENDERER; | |
| 186 case content::PROCESS_TYPE_PLUGIN: | |
| 187 return ProfilerEventProto::TrackedObject::PLUGIN; | |
| 188 case content::PROCESS_TYPE_WORKER: | |
| 189 return ProfilerEventProto::TrackedObject::WORKER; | |
| 190 case content::PROCESS_TYPE_UTILITY: | |
| 191 return ProfilerEventProto::TrackedObject::UTILITY; | |
| 192 case content::PROCESS_TYPE_ZYGOTE: | |
| 193 return ProfilerEventProto::TrackedObject::ZYGOTE; | |
| 194 case content::PROCESS_TYPE_SANDBOX_HELPER: | |
| 195 return ProfilerEventProto::TrackedObject::SANDBOX_HELPER; | |
| 196 case content::PROCESS_TYPE_GPU: | |
| 197 return ProfilerEventProto::TrackedObject::GPU; | |
| 198 case content::PROCESS_TYPE_PPAPI_PLUGIN: | |
| 199 return ProfilerEventProto::TrackedObject::PPAPI_PLUGIN; | |
| 200 case content::PROCESS_TYPE_PPAPI_BROKER: | |
| 201 return ProfilerEventProto::TrackedObject::PPAPI_BROKER; | |
| 202 case PROCESS_TYPE_NACL_LOADER: | |
| 203 return ProfilerEventProto::TrackedObject::NACL_LOADER; | |
| 204 case PROCESS_TYPE_NACL_BROKER: | |
| 205 return ProfilerEventProto::TrackedObject::NACL_BROKER; | |
| 206 default: | |
| 207 NOTREACHED(); | |
| 208 return ProfilerEventProto::TrackedObject::UNKNOWN; | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 SystemProfileProto::Channel AsProtobufChannel( | |
| 213 chrome::VersionInfo::Channel channel) { | |
| 214 switch (channel) { | |
| 215 case chrome::VersionInfo::CHANNEL_UNKNOWN: | |
| 216 return SystemProfileProto::CHANNEL_UNKNOWN; | |
| 217 case chrome::VersionInfo::CHANNEL_CANARY: | |
| 218 return SystemProfileProto::CHANNEL_CANARY; | |
| 219 case chrome::VersionInfo::CHANNEL_DEV: | |
| 220 return SystemProfileProto::CHANNEL_DEV; | |
| 221 case chrome::VersionInfo::CHANNEL_BETA: | |
| 222 return SystemProfileProto::CHANNEL_BETA; | |
| 223 case chrome::VersionInfo::CHANNEL_STABLE: | |
| 224 return SystemProfileProto::CHANNEL_STABLE; | |
| 225 default: | |
| 226 NOTREACHED(); | |
| 227 return SystemProfileProto::CHANNEL_UNKNOWN; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 // Computes a SHA-1 hash of |data| and returns it as a hex string. | |
| 232 std::string ComputeSHA1(const std::string& data) { | |
| 233 const std::string sha1 = base::SHA1HashString(data); | |
| 234 return base::HexEncode(sha1.data(), sha1.size()); | |
| 235 } | |
| 236 | |
| 237 #if defined(ENABLE_PLUGINS) | |
| 238 // Returns the plugin preferences corresponding for this user, if available. | |
| 239 // If multiple user profiles are loaded, returns the preferences corresponding | |
| 240 // to an arbitrary one of the profiles. | |
| 241 PluginPrefs* GetPluginPrefs() { | |
| 242 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 243 | |
| 244 if (!profile_manager) { | |
| 245 // The profile manager can be NULL when testing. | |
| 246 return NULL; | |
| 247 } | |
| 248 | |
| 249 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); | |
| 250 if (profiles.empty()) | |
| 251 return NULL; | |
| 252 | |
| 253 return PluginPrefs::GetForProfile(profiles.front()).get(); | |
| 254 } | |
| 255 | |
| 256 // Fills |plugin| with the info contained in |plugin_info| and |plugin_prefs|. | |
| 257 void SetPluginInfo(const content::WebPluginInfo& plugin_info, | |
| 258 const PluginPrefs* plugin_prefs, | |
| 259 SystemProfileProto::Plugin* plugin) { | |
| 260 plugin->set_name(base::UTF16ToUTF8(plugin_info.name)); | |
| 261 plugin->set_filename(plugin_info.path.BaseName().AsUTF8Unsafe()); | |
| 262 plugin->set_version(base::UTF16ToUTF8(plugin_info.version)); | |
| 263 plugin->set_is_pepper(plugin_info.is_pepper_plugin()); | |
| 264 if (plugin_prefs) | |
| 265 plugin->set_is_disabled(!plugin_prefs->IsPluginEnabled(plugin_info)); | |
| 266 } | |
| 267 #endif // defined(ENABLE_PLUGINS) | |
| 268 | |
| 269 void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, | |
| 270 SystemProfileProto* system_profile) { | |
| 271 for (std::vector<ActiveGroupId>::const_iterator it = | |
| 272 field_trial_ids.begin(); it != field_trial_ids.end(); ++it) { | |
| 273 SystemProfileProto::FieldTrial* field_trial = | |
| 274 system_profile->add_field_trial(); | |
| 275 field_trial->set_name_id(it->name); | |
| 276 field_trial->set_group_id(it->group); | |
| 277 } | |
| 278 } | |
| 279 | |
| 280 // Maps a thread name by replacing trailing sequence of digits with "*". | |
| 281 // Examples: | |
| 282 // 1. "BrowserBlockingWorker1/23857" => "BrowserBlockingWorker1/*" | |
| 283 // 2. "Chrome_IOThread" => "Chrome_IOThread" | |
| 284 std::string MapThreadName(const std::string& thread_name) { | |
| 285 size_t i = thread_name.length(); | |
| 286 | |
| 287 while (i > 0 && isdigit(thread_name[i - 1])) { | |
| 288 --i; | |
| 289 } | |
| 290 | |
| 291 if (i == thread_name.length()) | |
| 292 return thread_name; | |
| 293 | |
| 294 return thread_name.substr(0, i) + '*'; | |
| 295 } | |
| 296 | |
| 297 // Normalizes a source filename (which is platform- and build-method-dependent) | |
| 298 // by extracting the last component of the full file name. | |
| 299 // Example: "c:\b\build\slave\win\build\src\chrome\app\chrome_main.cc" => | |
| 300 // "chrome_main.cc". | |
| 301 std::string NormalizeFileName(const std::string& file_name) { | |
| 302 const size_t offset = file_name.find_last_of("\\/"); | |
| 303 return offset != std::string::npos ? file_name.substr(offset + 1) : file_name; | |
| 304 } | |
| 305 | |
| 306 void WriteProfilerData(const ProcessDataSnapshot& profiler_data, | |
| 307 int process_type, | |
| 308 ProfilerEventProto* performance_profile) { | |
| 309 for (std::vector<tracked_objects::TaskSnapshot>::const_iterator it = | |
| 310 profiler_data.tasks.begin(); | |
| 311 it != profiler_data.tasks.end(); ++it) { | |
| 312 const tracked_objects::DeathDataSnapshot& death_data = it->death_data; | |
| 313 ProfilerEventProto::TrackedObject* tracked_object = | |
| 314 performance_profile->add_tracked_object(); | |
| 315 tracked_object->set_birth_thread_name_hash( | |
| 316 MetricsLogBase::Hash(MapThreadName(it->birth.thread_name))); | |
| 317 tracked_object->set_exec_thread_name_hash( | |
| 318 MetricsLogBase::Hash(MapThreadName(it->death_thread_name))); | |
| 319 tracked_object->set_source_file_name_hash( | |
| 320 MetricsLogBase::Hash(NormalizeFileName(it->birth.location.file_name))); | |
| 321 tracked_object->set_source_function_name_hash( | |
| 322 MetricsLogBase::Hash(it->birth.location.function_name)); | |
| 323 tracked_object->set_source_line_number(it->birth.location.line_number); | |
| 324 tracked_object->set_exec_count(death_data.count); | |
| 325 tracked_object->set_exec_time_total(death_data.run_duration_sum); | |
| 326 tracked_object->set_exec_time_sampled(death_data.run_duration_sample); | |
| 327 tracked_object->set_queue_time_total(death_data.queue_duration_sum); | |
| 328 tracked_object->set_queue_time_sampled(death_data.queue_duration_sample); | |
| 329 tracked_object->set_process_type(AsProtobufProcessType(process_type)); | |
| 330 tracked_object->set_process_id(profiler_data.process_id); | |
| 331 } | |
| 332 } | |
| 333 | |
| 334 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) | |
| 335 void ProductDataToProto(const GoogleUpdateSettings::ProductData& product_data, | |
| 336 ProductInfo* product_info) { | |
| 337 product_info->set_version(product_data.version); | |
| 338 product_info->set_last_update_success_timestamp( | |
| 339 product_data.last_success.ToTimeT()); | |
| 340 product_info->set_last_error(product_data.last_error_code); | |
| 341 product_info->set_last_extra_error(product_data.last_extra_code); | |
| 342 if (ProductInfo::InstallResult_IsValid(product_data.last_result)) { | |
| 343 product_info->set_last_result( | |
| 344 static_cast<ProductInfo::InstallResult>(product_data.last_result)); | |
| 345 } | |
| 346 } | |
| 347 #endif | |
| 348 | |
| 349 #if defined(OS_WIN) | |
| 350 struct ScreenDPIInformation { | |
| 351 double max_dpi_x; | |
| 352 double max_dpi_y; | |
| 353 }; | |
| 354 | |
| 355 // Called once for each connected monitor. | |
| 356 BOOL CALLBACK GetMonitorDPICallback(HMONITOR, HDC hdc, LPRECT, LPARAM dwData) { | |
| 357 const double kMillimetersPerInch = 25.4; | |
| 358 ScreenDPIInformation* screen_info = | |
| 359 reinterpret_cast<ScreenDPIInformation*>(dwData); | |
| 360 // Size of screen, in mm. | |
| 361 DWORD size_x = GetDeviceCaps(hdc, HORZSIZE); | |
| 362 DWORD size_y = GetDeviceCaps(hdc, VERTSIZE); | |
| 363 double dpi_x = (size_x > 0) ? | |
| 364 GetDeviceCaps(hdc, HORZRES) / (size_x / kMillimetersPerInch) : 0; | |
| 365 double dpi_y = (size_y > 0) ? | |
| 366 GetDeviceCaps(hdc, VERTRES) / (size_y / kMillimetersPerInch) : 0; | |
| 367 screen_info->max_dpi_x = std::max(dpi_x, screen_info->max_dpi_x); | |
| 368 screen_info->max_dpi_y = std::max(dpi_y, screen_info->max_dpi_y); | |
| 369 return TRUE; | |
| 370 } | |
| 371 | |
| 372 void WriteScreenDPIInformationProto(SystemProfileProto::Hardware* hardware) { | |
| 373 HDC desktop_dc = GetDC(NULL); | |
| 374 if (desktop_dc) { | |
| 375 ScreenDPIInformation si = {0, 0}; | |
| 376 if (EnumDisplayMonitors(desktop_dc, NULL, GetMonitorDPICallback, | |
| 377 reinterpret_cast<LPARAM>(&si))) { | |
| 378 hardware->set_max_dpi_x(si.max_dpi_x); | |
| 379 hardware->set_max_dpi_y(si.max_dpi_y); | |
| 380 } | |
| 381 ReleaseDC(GetDesktopWindow(), desktop_dc); | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 #endif // defined(OS_WIN) | |
| 386 | |
| 387 // Round a timestamp measured in seconds since epoch to one with a granularity | |
| 388 // of an hour. This can be used before uploaded potentially sensitive | |
| 389 // timestamps. | |
| 390 int64 RoundSecondsToHour(int64 time_in_seconds) { | |
| 391 return 3600 * (time_in_seconds / 3600); | |
| 392 } | |
| 393 | |
| 394 } // namespace | 115 } // namespace |
| 395 | 116 |
| 396 GoogleUpdateMetrics::GoogleUpdateMetrics() : is_system_install(false) {} | 117 OmniboxMetricsProvider::OmniboxMetricsProvider() { |
| 397 | |
| 398 GoogleUpdateMetrics::~GoogleUpdateMetrics() {} | |
| 399 | |
| 400 static base::LazyInstance<std::string>::Leaky | |
| 401 g_version_extension = LAZY_INSTANCE_INITIALIZER; | |
| 402 | |
| 403 MetricsLog::MetricsLog(const std::string& client_id, | |
| 404 int session_id, | |
| 405 LogType log_type) | |
| 406 : MetricsLogBase(client_id, session_id, log_type, | |
| 407 MetricsLog::GetVersionString()), | |
| 408 creation_time_(base::TimeTicks::Now()), | |
| 409 extension_metrics_(uma_proto()->client_id()) { | |
| 410 uma_proto()->mutable_system_profile()->set_channel( | |
| 411 AsProtobufChannel(chrome::VersionInfo::GetChannel())); | |
| 412 | |
| 413 #if defined(OS_CHROMEOS) | |
| 414 metrics_log_chromeos_.reset(new MetricsLogChromeOS(uma_proto())); | |
| 415 #endif // OS_CHROMEOS | |
| 416 } | 118 } |
| 417 | 119 |
| 418 MetricsLog::~MetricsLog() {} | 120 OmniboxMetricsProvider::~OmniboxMetricsProvider() { |
| 419 | |
| 420 // static | |
| 421 void MetricsLog::RegisterPrefs(PrefRegistrySimple* registry) { | |
| 422 registry->RegisterListPref(prefs::kStabilityPluginStats); | |
| 423 } | 121 } |
| 424 | 122 |
| 425 // static | 123 void OmniboxMetricsProvider::OnRecordingEnabled() { |
| 426 std::string MetricsLog::GetVersionString() { | 124 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
| 427 chrome::VersionInfo version_info; | 125 content::NotificationService::AllSources()); |
| 428 if (!version_info.is_valid()) { | |
| 429 NOTREACHED() << "Unable to retrieve version info."; | |
| 430 return std::string(); | |
| 431 } | |
| 432 | |
| 433 std::string version = version_info.Version(); | |
| 434 if (!version_extension().empty()) | |
| 435 version += version_extension(); | |
| 436 if (!version_info.IsOfficialBuild()) | |
| 437 version.append("-devel"); | |
| 438 return version; | |
| 439 } | 126 } |
| 440 | 127 |
| 441 // static | 128 void OmniboxMetricsProvider::OnRecordingDisabled() { |
| 442 void MetricsLog::set_version_extension(const std::string& extension) { | 129 registrar_.RemoveAll(); |
| 443 g_version_extension.Get() = extension; | |
| 444 } | 130 } |
| 445 | 131 |
| 446 // static | 132 void OmniboxMetricsProvider::ProvideGeneralMetrics( |
| 447 const std::string& MetricsLog::version_extension() { | 133 metrics::ChromeUserMetricsExtension* uma_proto) { |
| 448 return g_version_extension.Get(); | 134 uma_proto->mutable_omnibox_event()->Swap( |
| 135 omnibox_events_cache.mutable_omnibox_event()); | |
| 449 } | 136 } |
| 450 | 137 |
| 451 void MetricsLog::RecordStabilityMetrics(base::TimeDelta incremental_uptime, | 138 void OmniboxMetricsProvider::Observe( |
| 452 base::TimeDelta uptime) { | 139 int type, |
| 453 DCHECK(!locked()); | 140 const content::NotificationSource& source, |
| 454 DCHECK(HasEnvironment()); | 141 const content::NotificationDetails& details) { |
| 455 DCHECK(!HasStabilityMetrics()); | 142 DCHECK_EQ(chrome::NOTIFICATION_OMNIBOX_OPENED_URL, type); |
| 456 | 143 RecordOmniboxOpenedURL(*content::Details<OmniboxLog>(details).ptr()); |
|
Ilya Sherman
2014/05/20 15:26:49
nit: It's probably reasonable to just inline this
Alexei Svitkine (slow)
2014/05/20 15:49:26
I find having the separate method cleaner (i.e. it
| |
| 457 PrefService* pref = GetPrefService(); | |
| 458 DCHECK(pref); | |
| 459 | |
| 460 // Get stability attributes out of Local State, zeroing out stored values. | |
| 461 // NOTE: This could lead to some data loss if this report isn't successfully | |
| 462 // sent, but that's true for all the metrics. | |
| 463 | |
| 464 WriteRequiredStabilityAttributes(pref); | |
| 465 WritePluginStabilityElements(pref); | |
| 466 | |
| 467 // Record recent delta for critical stability metrics. We can't wait for a | |
| 468 // restart to gather these, as that delay biases our observation away from | |
| 469 // users that run happily for a looooong time. We send increments with each | |
| 470 // uma log upload, just as we send histogram data. | |
| 471 WriteRealtimeStabilityAttributes(pref, incremental_uptime, uptime); | |
| 472 | |
| 473 // Omit some stats unless this is the initial stability log. | |
| 474 if (log_type() != INITIAL_STABILITY_LOG) | |
| 475 return; | |
| 476 | |
| 477 int incomplete_shutdown_count = | |
| 478 pref->GetInteger(prefs::kStabilityIncompleteSessionEndCount); | |
| 479 pref->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); | |
| 480 int breakpad_registration_success_count = | |
| 481 pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess); | |
| 482 pref->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); | |
| 483 int breakpad_registration_failure_count = | |
| 484 pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail); | |
| 485 pref->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); | |
| 486 int debugger_present_count = | |
| 487 pref->GetInteger(prefs::kStabilityDebuggerPresent); | |
| 488 pref->SetInteger(prefs::kStabilityDebuggerPresent, 0); | |
| 489 int debugger_not_present_count = | |
| 490 pref->GetInteger(prefs::kStabilityDebuggerNotPresent); | |
| 491 pref->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); | |
| 492 | |
| 493 // TODO(jar): The following are all optional, so we *could* optimize them for | |
| 494 // values of zero (and not include them). | |
| 495 SystemProfileProto::Stability* stability = | |
| 496 uma_proto()->mutable_system_profile()->mutable_stability(); | |
| 497 stability->set_incomplete_shutdown_count(incomplete_shutdown_count); | |
| 498 stability->set_breakpad_registration_success_count( | |
| 499 breakpad_registration_success_count); | |
| 500 stability->set_breakpad_registration_failure_count( | |
| 501 breakpad_registration_failure_count); | |
| 502 stability->set_debugger_present_count(debugger_present_count); | |
| 503 stability->set_debugger_not_present_count(debugger_not_present_count); | |
| 504 } | 144 } |
| 505 | 145 |
| 506 PrefService* MetricsLog::GetPrefService() { | 146 void OmniboxMetricsProvider::RecordOmniboxOpenedURL(const OmniboxLog& log) { |
| 507 return g_browser_process->local_state(); | |
| 508 } | |
| 509 | |
| 510 gfx::Size MetricsLog::GetScreenSize() const { | |
| 511 return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel(); | |
| 512 } | |
| 513 | |
| 514 float MetricsLog::GetScreenDeviceScaleFactor() const { | |
| 515 return gfx::Screen::GetNativeScreen()-> | |
| 516 GetPrimaryDisplay().device_scale_factor(); | |
| 517 } | |
| 518 | |
| 519 int MetricsLog::GetScreenCount() const { | |
| 520 // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312 | |
| 521 return gfx::Screen::GetNativeScreen()->GetNumDisplays(); | |
| 522 } | |
| 523 | |
| 524 void MetricsLog::GetFieldTrialIds( | |
| 525 std::vector<ActiveGroupId>* field_trial_ids) const { | |
| 526 variations::GetFieldTrialActiveGroupIds(field_trial_ids); | |
| 527 } | |
| 528 | |
| 529 bool MetricsLog::HasEnvironment() const { | |
| 530 return uma_proto()->system_profile().has_uma_enabled_date(); | |
| 531 } | |
| 532 | |
| 533 bool MetricsLog::HasStabilityMetrics() const { | |
| 534 return uma_proto()->system_profile().stability().has_launch_count(); | |
| 535 } | |
| 536 | |
| 537 void MetricsLog::WritePluginStabilityElements(PrefService* pref) { | |
| 538 // Now log plugin stability info. | |
| 539 const base::ListValue* plugin_stats_list = pref->GetList( | |
| 540 prefs::kStabilityPluginStats); | |
| 541 if (!plugin_stats_list) | |
| 542 return; | |
| 543 | |
| 544 #if defined(ENABLE_PLUGINS) | |
| 545 SystemProfileProto::Stability* stability = | |
| 546 uma_proto()->mutable_system_profile()->mutable_stability(); | |
| 547 for (base::ListValue::const_iterator iter = plugin_stats_list->begin(); | |
| 548 iter != plugin_stats_list->end(); ++iter) { | |
| 549 if (!(*iter)->IsType(base::Value::TYPE_DICTIONARY)) { | |
| 550 NOTREACHED(); | |
| 551 continue; | |
| 552 } | |
| 553 base::DictionaryValue* plugin_dict = | |
| 554 static_cast<base::DictionaryValue*>(*iter); | |
| 555 | |
| 556 // Note that this search is potentially a quadratic operation, but given the | |
| 557 // low number of plugins installed on a "reasonable" setup, this should be | |
| 558 // fine. | |
| 559 // TODO(isherman): Verify that this does not show up as a hotspot in | |
| 560 // profiler runs. | |
| 561 const SystemProfileProto::Plugin* system_profile_plugin = NULL; | |
| 562 std::string plugin_name; | |
| 563 plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name); | |
| 564 const SystemProfileProto& system_profile = uma_proto()->system_profile(); | |
| 565 for (int i = 0; i < system_profile.plugin_size(); ++i) { | |
| 566 if (system_profile.plugin(i).name() == plugin_name) { | |
| 567 system_profile_plugin = &system_profile.plugin(i); | |
| 568 break; | |
| 569 } | |
| 570 } | |
| 571 | |
| 572 if (!system_profile_plugin) { | |
| 573 NOTREACHED(); | |
| 574 continue; | |
| 575 } | |
| 576 | |
| 577 SystemProfileProto::Stability::PluginStability* plugin_stability = | |
| 578 stability->add_plugin_stability(); | |
| 579 *plugin_stability->mutable_plugin() = *system_profile_plugin; | |
| 580 | |
| 581 int launches = 0; | |
| 582 plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches); | |
| 583 if (launches > 0) | |
| 584 plugin_stability->set_launch_count(launches); | |
| 585 | |
| 586 int instances = 0; | |
| 587 plugin_dict->GetInteger(prefs::kStabilityPluginInstances, &instances); | |
| 588 if (instances > 0) | |
| 589 plugin_stability->set_instance_count(instances); | |
| 590 | |
| 591 int crashes = 0; | |
| 592 plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes); | |
| 593 if (crashes > 0) | |
| 594 plugin_stability->set_crash_count(crashes); | |
| 595 | |
| 596 int loading_errors = 0; | |
| 597 plugin_dict->GetInteger(prefs::kStabilityPluginLoadingErrors, | |
| 598 &loading_errors); | |
| 599 if (loading_errors > 0) | |
| 600 plugin_stability->set_loading_error_count(loading_errors); | |
| 601 } | |
| 602 #endif // defined(ENABLE_PLUGINS) | |
| 603 | |
| 604 pref->ClearPref(prefs::kStabilityPluginStats); | |
| 605 } | |
| 606 | |
| 607 // The server refuses data that doesn't have certain values. crashcount and | |
| 608 // launchcount are currently "required" in the "stability" group. | |
| 609 // TODO(isherman): Stop writing these attributes specially once the migration to | |
| 610 // protobufs is complete. | |
| 611 void MetricsLog::WriteRequiredStabilityAttributes(PrefService* pref) { | |
| 612 int launch_count = pref->GetInteger(prefs::kStabilityLaunchCount); | |
| 613 pref->SetInteger(prefs::kStabilityLaunchCount, 0); | |
| 614 int crash_count = pref->GetInteger(prefs::kStabilityCrashCount); | |
| 615 pref->SetInteger(prefs::kStabilityCrashCount, 0); | |
| 616 | |
| 617 SystemProfileProto::Stability* stability = | |
| 618 uma_proto()->mutable_system_profile()->mutable_stability(); | |
| 619 stability->set_launch_count(launch_count); | |
| 620 stability->set_crash_count(crash_count); | |
| 621 } | |
| 622 | |
| 623 void MetricsLog::WriteRealtimeStabilityAttributes( | |
| 624 PrefService* pref, | |
| 625 base::TimeDelta incremental_uptime, | |
| 626 base::TimeDelta uptime) { | |
| 627 // Update the stats which are critical for real-time stability monitoring. | |
| 628 // Since these are "optional," only list ones that are non-zero, as the counts | |
| 629 // are aggregated (summed) server side. | |
| 630 | |
| 631 SystemProfileProto::Stability* stability = | |
| 632 uma_proto()->mutable_system_profile()->mutable_stability(); | |
| 633 int count = pref->GetInteger(prefs::kStabilityPageLoadCount); | |
| 634 if (count) { | |
| 635 stability->set_page_load_count(count); | |
| 636 pref->SetInteger(prefs::kStabilityPageLoadCount, 0); | |
| 637 } | |
| 638 | |
| 639 count = pref->GetInteger(prefs::kStabilityRendererCrashCount); | |
| 640 if (count) { | |
| 641 stability->set_renderer_crash_count(count); | |
| 642 pref->SetInteger(prefs::kStabilityRendererCrashCount, 0); | |
| 643 } | |
| 644 | |
| 645 count = pref->GetInteger(prefs::kStabilityExtensionRendererCrashCount); | |
| 646 if (count) { | |
| 647 stability->set_extension_renderer_crash_count(count); | |
| 648 pref->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0); | |
| 649 } | |
| 650 | |
| 651 count = pref->GetInteger(prefs::kStabilityRendererHangCount); | |
| 652 if (count) { | |
| 653 stability->set_renderer_hang_count(count); | |
| 654 pref->SetInteger(prefs::kStabilityRendererHangCount, 0); | |
| 655 } | |
| 656 | |
| 657 count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount); | |
| 658 if (count) { | |
| 659 stability->set_child_process_crash_count(count); | |
| 660 pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0); | |
| 661 } | |
| 662 | |
| 663 #if defined(OS_CHROMEOS) | |
| 664 metrics_log_chromeos_->WriteRealtimeStabilityAttributes(pref); | |
| 665 #endif // OS_CHROMEOS | |
| 666 | |
| 667 const uint64 incremental_uptime_sec = incremental_uptime.InSeconds(); | |
| 668 if (incremental_uptime_sec) | |
| 669 stability->set_incremental_uptime_sec(incremental_uptime_sec); | |
| 670 const uint64 uptime_sec = uptime.InSeconds(); | |
| 671 if (uptime_sec) | |
| 672 stability->set_uptime_sec(uptime_sec); | |
| 673 } | |
| 674 | |
| 675 void MetricsLog::WritePluginList( | |
| 676 const std::vector<content::WebPluginInfo>& plugin_list) { | |
| 677 DCHECK(!locked()); | |
| 678 | |
| 679 #if defined(ENABLE_PLUGINS) | |
| 680 PluginPrefs* plugin_prefs = GetPluginPrefs(); | |
| 681 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); | |
| 682 for (std::vector<content::WebPluginInfo>::const_iterator iter = | |
| 683 plugin_list.begin(); | |
| 684 iter != plugin_list.end(); ++iter) { | |
| 685 SystemProfileProto::Plugin* plugin = system_profile->add_plugin(); | |
| 686 SetPluginInfo(*iter, plugin_prefs, plugin); | |
| 687 } | |
| 688 #endif // defined(ENABLE_PLUGINS) | |
| 689 } | |
| 690 | |
| 691 void MetricsLog::RecordEnvironment( | |
| 692 const std::vector<content::WebPluginInfo>& plugin_list, | |
| 693 const GoogleUpdateMetrics& google_update_metrics, | |
| 694 const std::vector<variations::ActiveGroupId>& synthetic_trials) { | |
| 695 DCHECK(!HasEnvironment()); | |
| 696 | |
| 697 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); | |
| 698 | |
| 699 std::string brand_code; | |
| 700 if (google_util::GetBrand(&brand_code)) | |
| 701 system_profile->set_brand_code(brand_code); | |
| 702 | |
| 703 int enabled_date; | |
| 704 bool success = base::StringToInt(GetMetricsEnabledDate(GetPrefService()), | |
| 705 &enabled_date); | |
| 706 DCHECK(success); | |
| 707 | |
| 708 // Reduce granularity of the enabled_date field to nearest hour. | |
| 709 system_profile->set_uma_enabled_date(RoundSecondsToHour(enabled_date)); | |
| 710 | |
| 711 int64 install_date = GetPrefService()->GetInt64(prefs::kInstallDate); | |
| 712 | |
| 713 // Reduce granularity of the install_date field to nearest hour. | |
| 714 system_profile->set_install_date(RoundSecondsToHour(install_date)); | |
| 715 | |
| 716 system_profile->set_application_locale( | |
| 717 g_browser_process->GetApplicationLocale()); | |
| 718 | |
| 719 SystemProfileProto::Hardware* hardware = system_profile->mutable_hardware(); | |
| 720 hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture()); | |
| 721 hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB()); | |
| 722 #if defined(OS_WIN) | |
| 723 hardware->set_dll_base(reinterpret_cast<uint64>(&__ImageBase)); | |
| 724 #endif | |
| 725 | |
| 726 SystemProfileProto::Network* network = system_profile->mutable_network(); | |
| 727 network->set_connection_type_is_ambiguous( | |
| 728 network_observer_.connection_type_is_ambiguous()); | |
| 729 network->set_connection_type(network_observer_.connection_type()); | |
| 730 network->set_wifi_phy_layer_protocol_is_ambiguous( | |
| 731 network_observer_.wifi_phy_layer_protocol_is_ambiguous()); | |
| 732 network->set_wifi_phy_layer_protocol( | |
| 733 network_observer_.wifi_phy_layer_protocol()); | |
| 734 network_observer_.Reset(); | |
| 735 | |
| 736 SystemProfileProto::OS* os = system_profile->mutable_os(); | |
| 737 std::string os_name = base::SysInfo::OperatingSystemName(); | |
| 738 #if defined(OS_WIN) | |
| 739 // TODO(mad): This only checks whether the main process is a Metro process at | |
| 740 // upload time; not whether the collected metrics were all gathered from | |
| 741 // Metro. This is ok as an approximation for now, since users will rarely be | |
| 742 // switching from Metro to Desktop mode; but we should re-evaluate whether we | |
| 743 // can distinguish metrics more cleanly in the future: http://crbug.com/140568 | |
| 744 if (base::win::IsMetroProcess()) | |
| 745 os_name += " (Metro)"; | |
| 746 #endif | |
| 747 os->set_name(os_name); | |
| 748 os->set_version(base::SysInfo::OperatingSystemVersion()); | |
| 749 #if defined(OS_ANDROID) | |
| 750 os->set_fingerprint( | |
| 751 base::android::BuildInfo::GetInstance()->android_build_fp()); | |
| 752 #endif | |
| 753 | |
| 754 base::CPU cpu_info; | |
| 755 SystemProfileProto::Hardware::CPU* cpu = hardware->mutable_cpu(); | |
| 756 cpu->set_vendor_name(cpu_info.vendor_name()); | |
| 757 cpu->set_signature(cpu_info.signature()); | |
| 758 | |
| 759 const gpu::GPUInfo& gpu_info = | |
| 760 GpuDataManager::GetInstance()->GetGPUInfo(); | |
| 761 SystemProfileProto::Hardware::Graphics* gpu = hardware->mutable_gpu(); | |
| 762 gpu->set_vendor_id(gpu_info.gpu.vendor_id); | |
| 763 gpu->set_device_id(gpu_info.gpu.device_id); | |
| 764 gpu->set_driver_version(gpu_info.driver_version); | |
| 765 gpu->set_driver_date(gpu_info.driver_date); | |
| 766 SystemProfileProto::Hardware::Graphics::PerformanceStatistics* | |
| 767 gpu_performance = gpu->mutable_performance_statistics(); | |
| 768 gpu_performance->set_graphics_score(gpu_info.performance_stats.graphics); | |
| 769 gpu_performance->set_gaming_score(gpu_info.performance_stats.gaming); | |
| 770 gpu_performance->set_overall_score(gpu_info.performance_stats.overall); | |
| 771 gpu->set_gl_vendor(gpu_info.gl_vendor); | |
| 772 gpu->set_gl_renderer(gpu_info.gl_renderer); | |
| 773 | |
| 774 const gfx::Size display_size = GetScreenSize(); | |
| 775 hardware->set_primary_screen_width(display_size.width()); | |
| 776 hardware->set_primary_screen_height(display_size.height()); | |
| 777 hardware->set_primary_screen_scale_factor(GetScreenDeviceScaleFactor()); | |
| 778 hardware->set_screen_count(GetScreenCount()); | |
| 779 | |
| 780 #if defined(OS_WIN) | |
| 781 WriteScreenDPIInformationProto(hardware); | |
| 782 #endif | |
| 783 | |
| 784 WriteGoogleUpdateProto(google_update_metrics); | |
| 785 | |
| 786 WritePluginList(plugin_list); | |
| 787 extension_metrics_.WriteExtensionList(uma_proto()->mutable_system_profile()); | |
| 788 | |
| 789 std::vector<ActiveGroupId> field_trial_ids; | |
| 790 GetFieldTrialIds(&field_trial_ids); | |
| 791 WriteFieldTrials(field_trial_ids, system_profile); | |
| 792 WriteFieldTrials(synthetic_trials, system_profile); | |
| 793 | |
| 794 #if defined(OS_CHROMEOS) | |
| 795 metrics_log_chromeos_->LogChromeOSMetrics(); | |
| 796 #endif // OS_CHROMEOS | |
| 797 | |
| 798 std::string serialied_system_profile; | |
| 799 std::string base64_system_profile; | |
| 800 if (system_profile->SerializeToString(&serialied_system_profile)) { | |
| 801 base::Base64Encode(serialied_system_profile, &base64_system_profile); | |
| 802 PrefService* local_state = GetPrefService(); | |
| 803 local_state->SetString(prefs::kStabilitySavedSystemProfile, | |
| 804 base64_system_profile); | |
| 805 local_state->SetString(prefs::kStabilitySavedSystemProfileHash, | |
| 806 ComputeSHA1(serialied_system_profile)); | |
| 807 } | |
| 808 } | |
| 809 | |
| 810 bool MetricsLog::LoadSavedEnvironmentFromPrefs() { | |
| 811 PrefService* local_state = GetPrefService(); | |
| 812 const std::string base64_system_profile = | |
| 813 local_state->GetString(prefs::kStabilitySavedSystemProfile); | |
| 814 if (base64_system_profile.empty()) | |
| 815 return false; | |
| 816 | |
| 817 const std::string system_profile_hash = | |
| 818 local_state->GetString(prefs::kStabilitySavedSystemProfileHash); | |
| 819 local_state->ClearPref(prefs::kStabilitySavedSystemProfile); | |
| 820 local_state->ClearPref(prefs::kStabilitySavedSystemProfileHash); | |
| 821 | |
| 822 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); | |
| 823 std::string serialied_system_profile; | |
| 824 return base::Base64Decode(base64_system_profile, &serialied_system_profile) && | |
| 825 ComputeSHA1(serialied_system_profile) == system_profile_hash && | |
| 826 system_profile->ParseFromString(serialied_system_profile); | |
| 827 } | |
| 828 | |
| 829 void MetricsLog::RecordProfilerData( | |
| 830 const tracked_objects::ProcessDataSnapshot& process_data, | |
| 831 int process_type) { | |
| 832 DCHECK(!locked()); | |
| 833 | |
| 834 if (tracked_objects::GetTimeSourceType() != | |
| 835 tracked_objects::TIME_SOURCE_TYPE_WALL_TIME) { | |
| 836 // We currently only support the default time source, wall clock time. | |
| 837 return; | |
| 838 } | |
| 839 | |
| 840 ProfilerEventProto* profile; | |
| 841 if (!uma_proto()->profiler_event_size()) { | |
| 842 // For the first process's data, add a new field to the protocol buffer. | |
| 843 profile = uma_proto()->add_profiler_event(); | |
| 844 profile->set_profile_type(ProfilerEventProto::STARTUP_PROFILE); | |
| 845 profile->set_time_source(ProfilerEventProto::WALL_CLOCK_TIME); | |
| 846 } else { | |
| 847 // For the remaining calls, re-use the existing field. | |
| 848 profile = uma_proto()->mutable_profiler_event(0); | |
| 849 } | |
| 850 | |
| 851 WriteProfilerData(process_data, process_type, profile); | |
| 852 } | |
| 853 | |
| 854 void MetricsLog::RecordOmniboxOpenedURL(const OmniboxLog& log) { | |
| 855 DCHECK(!locked()); | |
| 856 | |
| 857 std::vector<base::string16> terms; | 147 std::vector<base::string16> terms; |
| 858 const int num_terms = | 148 const int num_terms = |
| 859 static_cast<int>(Tokenize(log.text, base::kWhitespaceUTF16, &terms)); | 149 static_cast<int>(Tokenize(log.text, base::kWhitespaceUTF16, &terms)); |
| 860 | 150 |
| 861 OmniboxEventProto* omnibox_event = uma_proto()->add_omnibox_event(); | 151 OmniboxEventProto* omnibox_event = omnibox_events_cache.add_omnibox_event(); |
| 862 omnibox_event->set_time(MetricsLogBase::GetCurrentTime()); | 152 omnibox_event->set_time(metrics::MetricsLogBase::GetCurrentTime()); |
| 863 if (log.tab_id != -1) { | 153 if (log.tab_id != -1) { |
| 864 // If we know what tab the autocomplete URL was opened in, log it. | 154 // If we know what tab the autocomplete URL was opened in, log it. |
| 865 omnibox_event->set_tab_id(log.tab_id); | 155 omnibox_event->set_tab_id(log.tab_id); |
| 866 } | 156 } |
| 867 omnibox_event->set_typed_length(log.text.length()); | 157 omnibox_event->set_typed_length(log.text.length()); |
| 868 omnibox_event->set_just_deleted_text(log.just_deleted_text); | 158 omnibox_event->set_just_deleted_text(log.just_deleted_text); |
| 869 omnibox_event->set_num_typed_terms(num_terms); | 159 omnibox_event->set_num_typed_terms(num_terms); |
| 870 omnibox_event->set_selected_index(log.selected_index); | 160 omnibox_event->set_selected_index(log.selected_index); |
| 871 if (log.completed_length != base::string16::npos) | 161 if (log.completed_length != base::string16::npos) |
| 872 omnibox_event->set_completed_length(log.completed_length); | 162 omnibox_event->set_completed_length(log.completed_length); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 907 if (i->typed_count != -1) | 197 if (i->typed_count != -1) |
| 908 suggestion->set_typed_count(i->typed_count); | 198 suggestion->set_typed_count(i->typed_count); |
| 909 suggestion->set_is_starred(i->starred); | 199 suggestion->set_is_starred(i->starred); |
| 910 } | 200 } |
| 911 for (ProvidersInfo::const_iterator i(log.providers_info.begin()); | 201 for (ProvidersInfo::const_iterator i(log.providers_info.begin()); |
| 912 i != log.providers_info.end(); ++i) { | 202 i != log.providers_info.end(); ++i) { |
| 913 OmniboxEventProto::ProviderInfo* provider_info = | 203 OmniboxEventProto::ProviderInfo* provider_info = |
| 914 omnibox_event->add_provider_info(); | 204 omnibox_event->add_provider_info(); |
| 915 provider_info->CopyFrom(*i); | 205 provider_info->CopyFrom(*i); |
| 916 } | 206 } |
| 917 | |
| 918 ++num_events_; | |
| 919 } | 207 } |
| 920 | |
| 921 void MetricsLog::WriteGoogleUpdateProto( | |
| 922 const GoogleUpdateMetrics& google_update_metrics) { | |
| 923 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) | |
| 924 SystemProfileProto::GoogleUpdate* google_update = | |
| 925 uma_proto()->mutable_system_profile()->mutable_google_update(); | |
| 926 | |
| 927 google_update->set_is_system_install(google_update_metrics.is_system_install); | |
| 928 | |
| 929 if (!google_update_metrics.last_started_au.is_null()) { | |
| 930 google_update->set_last_automatic_start_timestamp( | |
| 931 google_update_metrics.last_started_au.ToTimeT()); | |
| 932 } | |
| 933 | |
| 934 if (!google_update_metrics.last_checked.is_null()) { | |
| 935 google_update->set_last_update_check_timestamp( | |
| 936 google_update_metrics.last_checked.ToTimeT()); | |
| 937 } | |
| 938 | |
| 939 if (!google_update_metrics.google_update_data.version.empty()) { | |
| 940 ProductDataToProto(google_update_metrics.google_update_data, | |
| 941 google_update->mutable_google_update_status()); | |
| 942 } | |
| 943 | |
| 944 if (!google_update_metrics.product_data.version.empty()) { | |
| 945 ProductDataToProto(google_update_metrics.product_data, | |
| 946 google_update->mutable_client_status()); | |
| 947 } | |
| 948 #endif // defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) | |
| 949 } | |
| OLD | NEW |