| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/metrics_log.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/base64.h" | 11 #include "base/base64.h" |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/cpu.h" | 14 #include "base/cpu.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/prefs/pref_registry_simple.h" | 17 #include "base/prefs/pref_registry_simple.h" |
| 18 #include "base/prefs/pref_service.h" | 18 #include "base/prefs/pref_service.h" |
| 19 #include "base/profiler/alternate_timer.h" | 19 #include "base/profiler/alternate_timer.h" |
| 20 #include "base/sha1.h" | 20 #include "base/sha1.h" |
| 21 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
| 24 #include "base/sys_info.h" | 24 #include "base/sys_info.h" |
| 25 #include "base/third_party/nspr/prtime.h" | 25 #include "base/third_party/nspr/prtime.h" |
| 26 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| 27 #include "base/tracked_objects.h" | 27 #include "base/tracked_objects.h" |
| 28 #include "chrome/browser/autocomplete/autocomplete_input.h" | |
| 29 #include "chrome/browser/autocomplete/autocomplete_match.h" | |
| 30 #include "chrome/browser/autocomplete/autocomplete_provider.h" | |
| 31 #include "chrome/browser/autocomplete/autocomplete_result.h" | |
| 32 #include "chrome/browser/browser_process.h" | 28 #include "chrome/browser/browser_process.h" |
| 33 #include "chrome/browser/google/google_util.h" | 29 #include "chrome/browser/google/google_util.h" |
| 34 #include "chrome/browser/metrics/extension_metrics.h" | 30 #include "chrome/browser/metrics/extension_metrics.h" |
| 35 #include "chrome/browser/omnibox/omnibox_log.h" | |
| 36 #include "chrome/browser/plugins/plugin_prefs.h" | 31 #include "chrome/browser/plugins/plugin_prefs.h" |
| 37 #include "chrome/browser/profiles/profile_manager.h" | 32 #include "chrome/browser/profiles/profile_manager.h" |
| 38 #include "chrome/common/chrome_version_info.h" | 33 #include "chrome/common/chrome_version_info.h" |
| 39 #include "chrome/common/pref_names.h" | 34 #include "chrome/common/pref_names.h" |
| 40 #include "chrome/installer/util/google_update_settings.h" | 35 #include "chrome/installer/util/google_update_settings.h" |
| 41 #include "components/metrics/metrics_provider.h" | 36 #include "components/metrics/metrics_provider.h" |
| 42 #include "components/metrics/proto/omnibox_event.pb.h" | |
| 43 #include "components/metrics/proto/profiler_event.pb.h" | 37 #include "components/metrics/proto/profiler_event.pb.h" |
| 44 #include "components/metrics/proto/system_profile.pb.h" | 38 #include "components/metrics/proto/system_profile.pb.h" |
| 45 #include "components/nacl/common/nacl_process_type.h" | 39 #include "components/nacl/common/nacl_process_type.h" |
| 46 #include "components/variations/active_field_trials.h" | 40 #include "components/variations/active_field_trials.h" |
| 47 #include "content/public/browser/gpu_data_manager.h" | 41 #include "content/public/browser/gpu_data_manager.h" |
| 48 #include "content/public/common/content_client.h" | 42 #include "content/public/common/content_client.h" |
| 49 #include "content/public/common/webplugininfo.h" | 43 #include "content/public/common/webplugininfo.h" |
| 50 #include "gpu/config/gpu_info.h" | 44 #include "gpu/config/gpu_info.h" |
| 51 #include "ui/gfx/screen.h" | 45 #include "ui/gfx/screen.h" |
| 52 #include "url/gurl.h" | 46 #include "url/gurl.h" |
| 53 | 47 |
| 54 #if defined(OS_ANDROID) | 48 #if defined(OS_ANDROID) |
| 55 #include "base/android/build_info.h" | 49 #include "base/android/build_info.h" |
| 56 #endif | 50 #endif |
| 57 | 51 |
| 58 #if defined(OS_WIN) | 52 #if defined(OS_WIN) |
| 59 #include "base/win/metro.h" | 53 #include "base/win/metro.h" |
| 60 | 54 |
| 61 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | 55 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx |
| 62 extern "C" IMAGE_DOS_HEADER __ImageBase; | 56 extern "C" IMAGE_DOS_HEADER __ImageBase; |
| 63 #endif | 57 #endif |
| 64 | 58 |
| 65 #if defined(OS_CHROMEOS) | 59 #if defined(OS_CHROMEOS) |
| 66 #include "chrome/browser/metrics/metrics_log_chromeos.h" | 60 #include "chrome/browser/metrics/metrics_log_chromeos.h" |
| 67 #endif // OS_CHROMEOS | 61 #endif // OS_CHROMEOS |
| 68 | 62 |
| 69 using content::GpuDataManager; | 63 using content::GpuDataManager; |
| 70 using metrics::MetricsLogBase; | 64 using metrics::MetricsLogBase; |
| 71 using metrics::OmniboxEventProto; | |
| 72 using metrics::ProfilerEventProto; | 65 using metrics::ProfilerEventProto; |
| 73 using metrics::SystemProfileProto; | 66 using metrics::SystemProfileProto; |
| 74 using tracked_objects::ProcessDataSnapshot; | 67 using tracked_objects::ProcessDataSnapshot; |
| 75 typedef variations::ActiveGroupId ActiveGroupId; | 68 typedef variations::ActiveGroupId ActiveGroupId; |
| 76 typedef SystemProfileProto::GoogleUpdate::ProductInfo ProductInfo; | 69 typedef SystemProfileProto::GoogleUpdate::ProductInfo ProductInfo; |
| 77 | 70 |
| 78 namespace { | 71 namespace { |
| 79 | 72 |
| 80 // Returns the date at which the current metrics client ID was created as | 73 // Returns the date at which the current metrics client ID was created as |
| 81 // a string containing seconds since the epoch, or "0" if none was found. | 74 // a string containing seconds since the epoch, or "0" if none was found. |
| 82 std::string GetMetricsEnabledDate(PrefService* pref) { | 75 std::string GetMetricsEnabledDate(PrefService* pref) { |
| 83 if (!pref) { | 76 if (!pref) { |
| 84 NOTREACHED(); | 77 NOTREACHED(); |
| 85 return "0"; | 78 return "0"; |
| 86 } | 79 } |
| 87 | 80 |
| 88 return pref->GetString(prefs::kMetricsReportingEnabledTimestamp); | 81 return pref->GetString(prefs::kMetricsReportingEnabledTimestamp); |
| 89 } | 82 } |
| 90 | 83 |
| 91 OmniboxEventProto::InputType AsOmniboxEventInputType( | |
| 92 AutocompleteInput::Type type) { | |
| 93 switch (type) { | |
| 94 case AutocompleteInput::INVALID: | |
| 95 return OmniboxEventProto::INVALID; | |
| 96 case AutocompleteInput::UNKNOWN: | |
| 97 return OmniboxEventProto::UNKNOWN; | |
| 98 case AutocompleteInput::URL: | |
| 99 return OmniboxEventProto::URL; | |
| 100 case AutocompleteInput::QUERY: | |
| 101 return OmniboxEventProto::QUERY; | |
| 102 case AutocompleteInput::FORCED_QUERY: | |
| 103 return OmniboxEventProto::FORCED_QUERY; | |
| 104 default: | |
| 105 NOTREACHED(); | |
| 106 return OmniboxEventProto::INVALID; | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 OmniboxEventProto::Suggestion::ResultType AsOmniboxEventResultType( | |
| 111 AutocompleteMatch::Type type) { | |
| 112 switch (type) { | |
| 113 case AutocompleteMatchType::URL_WHAT_YOU_TYPED: | |
| 114 return OmniboxEventProto::Suggestion::URL_WHAT_YOU_TYPED; | |
| 115 case AutocompleteMatchType::HISTORY_URL: | |
| 116 return OmniboxEventProto::Suggestion::HISTORY_URL; | |
| 117 case AutocompleteMatchType::HISTORY_TITLE: | |
| 118 return OmniboxEventProto::Suggestion::HISTORY_TITLE; | |
| 119 case AutocompleteMatchType::HISTORY_BODY: | |
| 120 return OmniboxEventProto::Suggestion::HISTORY_BODY; | |
| 121 case AutocompleteMatchType::HISTORY_KEYWORD: | |
| 122 return OmniboxEventProto::Suggestion::HISTORY_KEYWORD; | |
| 123 case AutocompleteMatchType::NAVSUGGEST: | |
| 124 return OmniboxEventProto::Suggestion::NAVSUGGEST; | |
| 125 case AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED: | |
| 126 return OmniboxEventProto::Suggestion::SEARCH_WHAT_YOU_TYPED; | |
| 127 case AutocompleteMatchType::SEARCH_HISTORY: | |
| 128 return OmniboxEventProto::Suggestion::SEARCH_HISTORY; | |
| 129 case AutocompleteMatchType::SEARCH_SUGGEST: | |
| 130 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST; | |
| 131 case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY: | |
| 132 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_ENTITY; | |
| 133 case AutocompleteMatchType::SEARCH_SUGGEST_INFINITE: | |
| 134 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_INFINITE; | |
| 135 case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED: | |
| 136 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PERSONALIZED; | |
| 137 case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE: | |
| 138 return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PROFILE; | |
| 139 case AutocompleteMatchType::SEARCH_OTHER_ENGINE: | |
| 140 return OmniboxEventProto::Suggestion::SEARCH_OTHER_ENGINE; | |
| 141 case AutocompleteMatchType::EXTENSION_APP: | |
| 142 return OmniboxEventProto::Suggestion::EXTENSION_APP; | |
| 143 case AutocompleteMatchType::BOOKMARK_TITLE: | |
| 144 return OmniboxEventProto::Suggestion::BOOKMARK_TITLE; | |
| 145 case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED: | |
| 146 return OmniboxEventProto::Suggestion::NAVSUGGEST_PERSONALIZED; | |
| 147 default: | |
| 148 NOTREACHED(); | |
| 149 return OmniboxEventProto::Suggestion::UNKNOWN_RESULT_TYPE; | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 OmniboxEventProto::PageClassification AsOmniboxEventPageClassification( | |
| 154 AutocompleteInput::PageClassification page_classification) { | |
| 155 switch (page_classification) { | |
| 156 case AutocompleteInput::INVALID_SPEC: | |
| 157 return OmniboxEventProto::INVALID_SPEC; | |
| 158 case AutocompleteInput::NTP: | |
| 159 return OmniboxEventProto::NTP; | |
| 160 case AutocompleteInput::BLANK: | |
| 161 return OmniboxEventProto::BLANK; | |
| 162 case AutocompleteInput::HOME_PAGE: | |
| 163 return OmniboxEventProto::HOME_PAGE; | |
| 164 case AutocompleteInput::OTHER: | |
| 165 return OmniboxEventProto::OTHER; | |
| 166 case AutocompleteInput::SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT: | |
| 167 return OmniboxEventProto:: | |
| 168 SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT; | |
| 169 case AutocompleteInput::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS: | |
| 170 return OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS; | |
| 171 case AutocompleteInput::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS: | |
| 172 return OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS; | |
| 173 case AutocompleteInput::SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT: | |
| 174 return OmniboxEventProto:: | |
| 175 SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT; | |
| 176 } | |
| 177 return OmniboxEventProto::INVALID_SPEC; | |
| 178 } | |
| 179 | |
| 180 ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType( | 84 ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType( |
| 181 int process_type) { | 85 int process_type) { |
| 182 switch (process_type) { | 86 switch (process_type) { |
| 183 case content::PROCESS_TYPE_BROWSER: | 87 case content::PROCESS_TYPE_BROWSER: |
| 184 return ProfilerEventProto::TrackedObject::BROWSER; | 88 return ProfilerEventProto::TrackedObject::BROWSER; |
| 185 case content::PROCESS_TYPE_RENDERER: | 89 case content::PROCESS_TYPE_RENDERER: |
| 186 return ProfilerEventProto::TrackedObject::RENDERER; | 90 return ProfilerEventProto::TrackedObject::RENDERER; |
| 187 case content::PROCESS_TYPE_PLUGIN: | 91 case content::PROCESS_TYPE_PLUGIN: |
| 188 return ProfilerEventProto::TrackedObject::PLUGIN; | 92 return ProfilerEventProto::TrackedObject::PLUGIN; |
| 189 case content::PROCESS_TYPE_WORKER: | 93 case content::PROCESS_TYPE_WORKER: |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 profile->set_profile_type(ProfilerEventProto::STARTUP_PROFILE); | 764 profile->set_profile_type(ProfilerEventProto::STARTUP_PROFILE); |
| 861 profile->set_time_source(ProfilerEventProto::WALL_CLOCK_TIME); | 765 profile->set_time_source(ProfilerEventProto::WALL_CLOCK_TIME); |
| 862 } else { | 766 } else { |
| 863 // For the remaining calls, re-use the existing field. | 767 // For the remaining calls, re-use the existing field. |
| 864 profile = uma_proto()->mutable_profiler_event(0); | 768 profile = uma_proto()->mutable_profiler_event(0); |
| 865 } | 769 } |
| 866 | 770 |
| 867 WriteProfilerData(process_data, process_type, profile); | 771 WriteProfilerData(process_data, process_type, profile); |
| 868 } | 772 } |
| 869 | 773 |
| 870 void MetricsLog::RecordOmniboxOpenedURL(const OmniboxLog& log) { | |
| 871 DCHECK(!locked()); | |
| 872 | |
| 873 std::vector<base::string16> terms; | |
| 874 const int num_terms = | |
| 875 static_cast<int>(Tokenize(log.text, base::kWhitespaceUTF16, &terms)); | |
| 876 | |
| 877 OmniboxEventProto* omnibox_event = uma_proto()->add_omnibox_event(); | |
| 878 omnibox_event->set_time(MetricsLogBase::GetCurrentTime()); | |
| 879 if (log.tab_id != -1) { | |
| 880 // If we know what tab the autocomplete URL was opened in, log it. | |
| 881 omnibox_event->set_tab_id(log.tab_id); | |
| 882 } | |
| 883 omnibox_event->set_typed_length(log.text.length()); | |
| 884 omnibox_event->set_just_deleted_text(log.just_deleted_text); | |
| 885 omnibox_event->set_num_typed_terms(num_terms); | |
| 886 omnibox_event->set_selected_index(log.selected_index); | |
| 887 if (log.completed_length != base::string16::npos) | |
| 888 omnibox_event->set_completed_length(log.completed_length); | |
| 889 const base::TimeDelta default_time_delta = | |
| 890 base::TimeDelta::FromMilliseconds(-1); | |
| 891 if (log.elapsed_time_since_user_first_modified_omnibox != | |
| 892 default_time_delta) { | |
| 893 // Only upload the typing duration if it is set/valid. | |
| 894 omnibox_event->set_typing_duration_ms( | |
| 895 log.elapsed_time_since_user_first_modified_omnibox.InMilliseconds()); | |
| 896 } | |
| 897 if (log.elapsed_time_since_last_change_to_default_match != | |
| 898 default_time_delta) { | |
| 899 omnibox_event->set_duration_since_last_default_match_update_ms( | |
| 900 log.elapsed_time_since_last_change_to_default_match.InMilliseconds()); | |
| 901 } | |
| 902 omnibox_event->set_current_page_classification( | |
| 903 AsOmniboxEventPageClassification(log.current_page_classification)); | |
| 904 omnibox_event->set_input_type(AsOmniboxEventInputType(log.input_type)); | |
| 905 // We consider a paste-and-search/paste-and-go action to have a closed popup | |
| 906 // (as explained in omnibox_event.proto) even if it was not, because such | |
| 907 // actions ignore the contents of the popup so it doesn't matter that it was | |
| 908 // open. | |
| 909 const bool consider_popup_open = log.is_popup_open && !log.is_paste_and_go; | |
| 910 omnibox_event->set_is_popup_open(consider_popup_open); | |
| 911 omnibox_event->set_is_paste_and_go(log.is_paste_and_go); | |
| 912 if (consider_popup_open) { | |
| 913 omnibox_event->set_is_top_result_hidden_in_dropdown( | |
| 914 log.result.ShouldHideTopMatch()); | |
| 915 } | |
| 916 | |
| 917 for (AutocompleteResult::const_iterator i(log.result.begin()); | |
| 918 i != log.result.end(); ++i) { | |
| 919 OmniboxEventProto::Suggestion* suggestion = omnibox_event->add_suggestion(); | |
| 920 suggestion->set_provider(i->provider->AsOmniboxEventProviderType()); | |
| 921 suggestion->set_result_type(AsOmniboxEventResultType(i->type)); | |
| 922 suggestion->set_relevance(i->relevance); | |
| 923 if (i->typed_count != -1) | |
| 924 suggestion->set_typed_count(i->typed_count); | |
| 925 suggestion->set_is_starred(i->starred); | |
| 926 } | |
| 927 for (ProvidersInfo::const_iterator i(log.providers_info.begin()); | |
| 928 i != log.providers_info.end(); ++i) { | |
| 929 OmniboxEventProto::ProviderInfo* provider_info = | |
| 930 omnibox_event->add_provider_info(); | |
| 931 provider_info->CopyFrom(*i); | |
| 932 } | |
| 933 } | |
| 934 | |
| 935 void MetricsLog::WriteGoogleUpdateProto( | 774 void MetricsLog::WriteGoogleUpdateProto( |
| 936 const GoogleUpdateMetrics& google_update_metrics) { | 775 const GoogleUpdateMetrics& google_update_metrics) { |
| 937 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) | 776 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) |
| 938 SystemProfileProto::GoogleUpdate* google_update = | 777 SystemProfileProto::GoogleUpdate* google_update = |
| 939 uma_proto()->mutable_system_profile()->mutable_google_update(); | 778 uma_proto()->mutable_system_profile()->mutable_google_update(); |
| 940 | 779 |
| 941 google_update->set_is_system_install(google_update_metrics.is_system_install); | 780 google_update->set_is_system_install(google_update_metrics.is_system_install); |
| 942 | 781 |
| 943 if (!google_update_metrics.last_started_au.is_null()) { | 782 if (!google_update_metrics.last_started_au.is_null()) { |
| 944 google_update->set_last_automatic_start_timestamp( | 783 google_update->set_last_automatic_start_timestamp( |
| 945 google_update_metrics.last_started_au.ToTimeT()); | 784 google_update_metrics.last_started_au.ToTimeT()); |
| 946 } | 785 } |
| 947 | 786 |
| 948 if (!google_update_metrics.last_checked.is_null()) { | 787 if (!google_update_metrics.last_checked.is_null()) { |
| 949 google_update->set_last_update_check_timestamp( | 788 google_update->set_last_update_check_timestamp( |
| 950 google_update_metrics.last_checked.ToTimeT()); | 789 google_update_metrics.last_checked.ToTimeT()); |
| 951 } | 790 } |
| 952 | 791 |
| 953 if (!google_update_metrics.google_update_data.version.empty()) { | 792 if (!google_update_metrics.google_update_data.version.empty()) { |
| 954 ProductDataToProto(google_update_metrics.google_update_data, | 793 ProductDataToProto(google_update_metrics.google_update_data, |
| 955 google_update->mutable_google_update_status()); | 794 google_update->mutable_google_update_status()); |
| 956 } | 795 } |
| 957 | 796 |
| 958 if (!google_update_metrics.product_data.version.empty()) { | 797 if (!google_update_metrics.product_data.version.empty()) { |
| 959 ProductDataToProto(google_update_metrics.product_data, | 798 ProductDataToProto(google_update_metrics.product_data, |
| 960 google_update->mutable_client_status()); | 799 google_update->mutable_client_status()); |
| 961 } | 800 } |
| 962 #endif // defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) | 801 #endif // defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) |
| 963 } | 802 } |
| OLD | NEW |