OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/profile_resetter/resettable_settings_snapshot.h" | 5 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
| 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/values.h" |
| 11 #include "chrome/browser/browser_process.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/feedback/feedback_data.h" | 13 #include "chrome/browser/feedback/feedback_data.h" |
11 #include "chrome/browser/feedback/feedback_util.h" | 14 #include "chrome/browser/feedback/feedback_util.h" |
12 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/browser/search_engines/template_url_service.h" | 16 #include "chrome/browser/search_engines/template_url_service.h" |
14 #include "chrome/browser/search_engines/template_url_service_factory.h" | 17 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 18 #include "chrome/common/chrome_version_info.h" |
15 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 20 #include "grit/generated_resources.h" |
| 21 #include "grit/google_chrome_strings.h" |
| 22 #include "ui/base/l10n/l10n_util.h" |
16 | 23 |
17 namespace { | 24 namespace { |
18 | 25 |
19 // Feedback bucket label. | 26 // Feedback bucket label. |
20 const char kProfileResetFeedbackBucket[] = "ProfileResetReport"; | 27 const char kProfileResetFeedbackBucket[] = "ProfileResetReport"; |
21 | 28 |
22 // Dictionary keys for feedback report. | 29 // Dictionary keys for feedback report. |
23 const char kDefaultSearchEnginePath[] = "default_search_engine"; | 30 const char kDefaultSearchEnginePath[] = "default_search_engine"; |
24 const char kEnabledExtensions[] = "enabled_extensions"; | 31 const char kEnabledExtensions[] = "enabled_extensions"; |
25 const char kHomepageIsNewTabPage[] = "homepage_is_ntp"; | 32 const char kHomepageIsNewTabPage[] = "homepage_is_ntp"; |
26 const char kHomepagePath[] = "homepage"; | 33 const char kHomepagePath[] = "homepage"; |
27 const char kStartupTypePath[] = "startup_type"; | 34 const char kStartupTypePath[] = "startup_type"; |
28 const char kStartupURLPath[] = "startup_urls"; | 35 const char kStartupURLPath[] = "startup_urls"; |
29 | 36 |
| 37 void AddPair(ListValue* list, const string16& key, const string16& value) { |
| 38 DictionaryValue* results = new DictionaryValue(); |
| 39 results->SetString("key", key); |
| 40 results->SetString("value", value); |
| 41 list->Append(results); |
| 42 } |
| 43 |
30 } // namespace | 44 } // namespace |
31 | 45 |
32 ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile) | 46 ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile) |
33 : startup_(SessionStartupPref::GetStartupPref(profile)) { | 47 : startup_(SessionStartupPref::GetStartupPref(profile)) { |
34 // URLs are always stored sorted. | 48 // URLs are always stored sorted. |
35 std::sort(startup_.urls.begin(), startup_.urls.end()); | 49 std::sort(startup_.urls.begin(), startup_.urls.end()); |
36 | 50 |
37 PrefService* prefs = profile->GetPrefs(); | 51 PrefService* prefs = profile->GetPrefs(); |
38 DCHECK(prefs); | 52 DCHECK(prefs); |
39 homepage_ = prefs->GetString(prefs::kHomePage); | 53 homepage_ = prefs->GetString(prefs::kHomePage); |
40 homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage); | 54 homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage); |
41 | 55 |
42 TemplateURLService* service = | 56 TemplateURLService* service = |
43 TemplateURLServiceFactory::GetForProfile(profile); | 57 TemplateURLServiceFactory::GetForProfile(profile); |
44 DCHECK(service); | 58 DCHECK(service); |
45 TemplateURL* dse = service->GetDefaultSearchProvider(); | 59 TemplateURL* dse = service->GetDefaultSearchProvider(); |
46 if (dse) | 60 if (dse) |
47 dse_url_ = dse->url(); | 61 dse_url_ = dse->url(); |
48 | 62 |
49 ExtensionService* extension_service = profile->GetExtensionService(); | 63 ExtensionService* extension_service = profile->GetExtensionService(); |
50 DCHECK(extension_service); | 64 DCHECK(extension_service); |
51 const ExtensionSet* enabled_ext = extension_service->extensions(); | 65 const ExtensionSet* enabled_ext = extension_service->extensions(); |
52 enabled_extensions_.reserve(enabled_ext->size()); | 66 enabled_extensions_.reserve(enabled_ext->size()); |
53 | 67 |
54 for (ExtensionSet::const_iterator it = enabled_ext->begin(); | 68 for (ExtensionSet::const_iterator it = enabled_ext->begin(); |
55 it != enabled_ext->end(); ++it) | 69 it != enabled_ext->end(); ++it) |
56 enabled_extensions_.push_back((*it)->id()); | 70 enabled_extensions_.push_back(std::make_pair((*it)->id(), (*it)->name())); |
57 | 71 |
58 // ExtensionSet is sorted but it seems to be an implementation detail. | 72 // ExtensionSet is sorted but it seems to be an implementation detail. |
59 std::sort(enabled_extensions_.begin(), enabled_extensions_.end()); | 73 std::sort(enabled_extensions_.begin(), enabled_extensions_.end()); |
60 } | 74 } |
61 | 75 |
62 ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {} | 76 ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {} |
63 | 77 |
64 void ResettableSettingsSnapshot::Subtract( | 78 void ResettableSettingsSnapshot::Subtract( |
65 const ResettableSettingsSnapshot& snapshot) { | 79 const ResettableSettingsSnapshot& snapshot) { |
66 std::vector<GURL> urls; | 80 std::vector<GURL> urls; |
67 std::set_difference(startup_.urls.begin(), startup_.urls.end(), | 81 std::set_difference(startup_.urls.begin(), startup_.urls.end(), |
68 snapshot.startup_.urls.begin(), | 82 snapshot.startup_.urls.begin(), |
69 snapshot.startup_.urls.end(), | 83 snapshot.startup_.urls.end(), |
70 std::back_inserter(urls)); | 84 std::back_inserter(urls)); |
71 startup_.urls.swap(urls); | 85 startup_.urls.swap(urls); |
72 | 86 |
73 std::vector<std::string> extensions; | 87 ExtensionList extensions; |
74 std::set_difference(enabled_extensions_.begin(), enabled_extensions_.end(), | 88 std::set_difference(enabled_extensions_.begin(), enabled_extensions_.end(), |
75 snapshot.enabled_extensions_.begin(), | 89 snapshot.enabled_extensions_.begin(), |
76 snapshot.enabled_extensions_.end(), | 90 snapshot.enabled_extensions_.end(), |
77 std::back_inserter(extensions)); | 91 std::back_inserter(extensions)); |
78 enabled_extensions_.swap(extensions); | 92 enabled_extensions_.swap(extensions); |
79 } | 93 } |
80 | 94 |
81 int ResettableSettingsSnapshot::FindDifferentFields( | 95 int ResettableSettingsSnapshot::FindDifferentFields( |
82 const ResettableSettingsSnapshot& snapshot) const { | 96 const ResettableSettingsSnapshot& snapshot) const { |
83 int bit_mask = 0; | 97 int bit_mask = 0; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 dict.SetString(kHomepagePath, snapshot.homepage()); | 141 dict.SetString(kHomepagePath, snapshot.homepage()); |
128 | 142 |
129 if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP) | 143 if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP) |
130 dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp()); | 144 dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp()); |
131 | 145 |
132 if (field_mask & ResettableSettingsSnapshot::DSE_URL) | 146 if (field_mask & ResettableSettingsSnapshot::DSE_URL) |
133 dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url()); | 147 dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url()); |
134 | 148 |
135 if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) { | 149 if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) { |
136 ListValue* list = new ListValue; | 150 ListValue* list = new ListValue; |
137 const std::vector<std::string>& extensions = snapshot.enabled_extensions(); | 151 const ResettableSettingsSnapshot::ExtensionList& extensions = |
138 for (std::vector<std::string>::const_iterator i = extensions.begin(); | 152 snapshot.enabled_extensions(); |
139 i != extensions.end(); ++i) | 153 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i = |
140 list->AppendString(*i); | 154 extensions.begin(); i != extensions.end(); ++i) { |
| 155 // Replace "\"" to simplify server-side analysis. |
| 156 std::string ext_name; |
| 157 ReplaceChars(i->second, "\"", "\'", &ext_name); |
| 158 list->AppendString(i->first + ";" + ext_name); |
| 159 } |
141 dict.Set(kEnabledExtensions, list); | 160 dict.Set(kEnabledExtensions, list); |
142 } | 161 } |
143 | 162 |
144 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63, | 163 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63, |
145 serialize_new_field_here); | 164 serialize_new_field_here); |
146 | 165 |
147 std::string json; | 166 std::string json; |
148 base::JSONWriter::Write(&dict, &json); | 167 base::JSONWriter::Write(&dict, &json); |
149 return json; | 168 return json; |
150 } | 169 } |
151 | 170 |
152 void SendSettingsFeedback(const std::string& report, Profile* profile) { | 171 void SendSettingsFeedback(const std::string& report, Profile* profile) { |
153 scoped_refptr<FeedbackData> feedback_data = new FeedbackData(); | 172 scoped_refptr<FeedbackData> feedback_data = new FeedbackData(); |
154 feedback_data->set_category_tag(kProfileResetFeedbackBucket); | 173 feedback_data->set_category_tag(kProfileResetFeedbackBucket); |
155 feedback_data->set_description(report); | 174 feedback_data->set_description(report); |
156 | 175 |
157 feedback_data->set_image(scoped_ptr<std::string>(new std::string)); | 176 feedback_data->set_image(scoped_ptr<std::string>(new std::string)); |
158 feedback_data->set_profile(profile); | 177 feedback_data->set_profile(profile); |
159 | 178 |
160 feedback_data->set_page_url(""); | 179 feedback_data->set_page_url(""); |
161 feedback_data->set_user_email(""); | 180 feedback_data->set_user_email(""); |
162 | 181 |
163 feedback_util::SendReport(feedback_data); | 182 feedback_util::SendReport(feedback_data); |
164 } | 183 } |
| 184 |
| 185 ListValue* GetReadableFeedback(Profile* profile) { |
| 186 DCHECK(profile); |
| 187 ListValue* list = new ListValue; |
| 188 AddPair(list, l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_LOCALE), |
| 189 ASCIIToUTF16(g_browser_process->GetApplicationLocale())); |
| 190 AddPair(list, |
| 191 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_USER_AGENT), |
| 192 ASCIIToUTF16(content::GetUserAgent(GURL()))); |
| 193 chrome::VersionInfo version_info; |
| 194 std::string version = version_info.Version(); |
| 195 version += chrome::VersionInfo::GetVersionStringModifier(); |
| 196 AddPair(list, |
| 197 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 198 ASCIIToUTF16(version)); |
| 199 |
| 200 // Add snapshot data. |
| 201 ResettableSettingsSnapshot snapshot(profile); |
| 202 const std::vector<GURL>& urls = snapshot.startup_urls(); |
| 203 std::string startup_urls; |
| 204 for (std::vector<GURL>::const_iterator i = urls.begin(); |
| 205 i != urls.end(); ++i) { |
| 206 (startup_urls += i->host()) += ' '; |
| 207 } |
| 208 if (!startup_urls.empty()) { |
| 209 startup_urls.erase(startup_urls.end() - 1); |
| 210 AddPair(list, |
| 211 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_URLS), |
| 212 ASCIIToUTF16(startup_urls)); |
| 213 } |
| 214 |
| 215 string16 startup_type; |
| 216 switch (snapshot.startup_type()) { |
| 217 case SessionStartupPref::DEFAULT: |
| 218 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_NEWTAB); |
| 219 break; |
| 220 case SessionStartupPref::LAST: |
| 221 startup_type = l10n_util::GetStringUTF16( |
| 222 IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION); |
| 223 break; |
| 224 case SessionStartupPref::URLS: |
| 225 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_PAGES); |
| 226 break; |
| 227 default: |
| 228 break; |
| 229 } |
| 230 AddPair(list, |
| 231 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_TYPE), |
| 232 startup_type); |
| 233 |
| 234 if (!snapshot.homepage().empty()) { |
| 235 AddPair(list, |
| 236 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE), |
| 237 ASCIIToUTF16(snapshot.homepage())); |
| 238 } |
| 239 |
| 240 int is_ntp_message_id = snapshot.homepage_is_ntp() ? |
| 241 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_TRUE : |
| 242 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_FALSE; |
| 243 AddPair(list, |
| 244 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP), |
| 245 l10n_util::GetStringUTF16(is_ntp_message_id)); |
| 246 |
| 247 TemplateURLService* service = |
| 248 TemplateURLServiceFactory::GetForProfile(profile); |
| 249 DCHECK(service); |
| 250 TemplateURL* dse = service->GetDefaultSearchProvider(); |
| 251 if (dse) { |
| 252 AddPair(list, |
| 253 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_DSE), |
| 254 ASCIIToUTF16(TemplateURLService::GenerateSearchURL(dse).host())); |
| 255 } |
| 256 |
| 257 const ResettableSettingsSnapshot::ExtensionList& extensions = |
| 258 snapshot.enabled_extensions(); |
| 259 std::string extension_ids; |
| 260 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i = |
| 261 extensions.begin(); i != extensions.end(); ++i) { |
| 262 (extension_ids += i->second) += '\n'; |
| 263 } |
| 264 if (!extension_ids.empty()) { |
| 265 extension_ids.erase(extension_ids.end() - 1); |
| 266 AddPair(list, |
| 267 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_EXTENSIONS), |
| 268 ASCIIToUTF16(extension_ids)); |
| 269 } |
| 270 return list; |
| 271 } |
OLD | NEW |