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 |