Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / profile_resetter / resettable_settings_snapshot.cc
blob741bf826531dd4adc3adfb4277a03ae632d77371
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
3 // found in the LICENSE file.
5 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
7 #include "base/json/json_writer.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"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/feedback/feedback_data.h"
14 #include "chrome/browser/feedback/feedback_util.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/search_engines/template_url_service.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
18 #include "chrome/common/chrome_version_info.h"
19 #include "chrome/common/pref_names.h"
20 #include "extensions/common/extension_set.h"
21 #include "grit/generated_resources.h"
22 #include "grit/google_chrome_strings.h"
23 #include "ui/base/l10n/l10n_util.h"
25 namespace {
27 // Feedback bucket labels.
28 const char kProfileResetPromptBucket[] = "SamplingOfSettingsResetPrompt";
29 const char kProfileResetWebUIBucket[] = "ProfileResetReport";
31 // Dictionary keys for feedback report.
32 const char kDefaultSearchEnginePath[] = "default_search_engine";
33 const char kEnabledExtensions[] = "enabled_extensions";
34 const char kHomepageIsNewTabPage[] = "homepage_is_ntp";
35 const char kHomepagePath[] = "homepage";
36 const char kStartupTypePath[] = "startup_type";
37 const char kStartupURLPath[] = "startup_urls";
39 template <class StringType>
40 void AddPair(base::ListValue* list,
41 const base::string16& key,
42 const StringType& value) {
43 base::DictionaryValue* results = new base::DictionaryValue();
44 results->SetString("key", key);
45 results->SetString("value", value);
46 list->Append(results);
49 } // namespace
51 ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile)
52 : startup_(SessionStartupPref::GetStartupPref(profile)) {
53 // URLs are always stored sorted.
54 std::sort(startup_.urls.begin(), startup_.urls.end());
56 PrefService* prefs = profile->GetPrefs();
57 DCHECK(prefs);
58 homepage_ = prefs->GetString(prefs::kHomePage);
59 homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage);
61 TemplateURLService* service =
62 TemplateURLServiceFactory::GetForProfile(profile);
63 DCHECK(service);
64 TemplateURL* dse = service->GetDefaultSearchProvider();
65 if (dse)
66 dse_url_ = dse->url();
68 ExtensionService* extension_service = profile->GetExtensionService();
69 DCHECK(extension_service);
70 const extensions::ExtensionSet* enabled_ext = extension_service->extensions();
71 enabled_extensions_.reserve(enabled_ext->size());
73 for (extensions::ExtensionSet::const_iterator it = enabled_ext->begin();
74 it != enabled_ext->end(); ++it)
75 enabled_extensions_.push_back(std::make_pair((*it)->id(), (*it)->name()));
77 // ExtensionSet is sorted but it seems to be an implementation detail.
78 std::sort(enabled_extensions_.begin(), enabled_extensions_.end());
81 ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {}
83 void ResettableSettingsSnapshot::Subtract(
84 const ResettableSettingsSnapshot& snapshot) {
85 ExtensionList extensions = base::STLSetDifference<ExtensionList>(
86 enabled_extensions_, snapshot.enabled_extensions_);
87 enabled_extensions_.swap(extensions);
90 int ResettableSettingsSnapshot::FindDifferentFields(
91 const ResettableSettingsSnapshot& snapshot) const {
92 int bit_mask = 0;
94 if (startup_.type != snapshot.startup_.type ||
95 startup_.urls != snapshot.startup_.urls)
96 bit_mask |= STARTUP_MODE;
98 if (homepage_is_ntp_ != snapshot.homepage_is_ntp_ ||
99 homepage_ != snapshot.homepage_)
100 bit_mask |= HOMEPAGE;
102 if (dse_url_ != snapshot.dse_url_)
103 bit_mask |= DSE_URL;
105 if (enabled_extensions_ != snapshot.enabled_extensions_)
106 bit_mask |= EXTENSIONS;
108 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
109 add_new_field_here);
111 return bit_mask;
114 std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
115 int field_mask) {
116 base::DictionaryValue dict;
118 if (field_mask & ResettableSettingsSnapshot::STARTUP_MODE) {
119 base::ListValue* list = new base::ListValue;
120 const std::vector<GURL>& urls = snapshot.startup_urls();
121 for (std::vector<GURL>::const_iterator i = urls.begin();
122 i != urls.end(); ++i)
123 list->AppendString(i->spec());
124 dict.Set(kStartupURLPath, list);
125 dict.SetInteger(kStartupTypePath, snapshot.startup_type());
128 if (field_mask & ResettableSettingsSnapshot::HOMEPAGE) {
129 dict.SetString(kHomepagePath, snapshot.homepage());
130 dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp());
133 if (field_mask & ResettableSettingsSnapshot::DSE_URL)
134 dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url());
136 if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) {
137 base::ListValue* list = new base::ListValue;
138 const ResettableSettingsSnapshot::ExtensionList& extensions =
139 snapshot.enabled_extensions();
140 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i =
141 extensions.begin(); i != extensions.end(); ++i) {
142 // Replace "\"" to simplify server-side analysis.
143 std::string ext_name;
144 base::ReplaceChars(i->second, "\"", "\'", &ext_name);
145 list->AppendString(i->first + ";" + ext_name);
147 dict.Set(kEnabledExtensions, list);
150 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
151 serialize_new_field_here);
153 std::string json;
154 base::JSONWriter::Write(&dict, &json);
155 return json;
158 void SendSettingsFeedback(const std::string& report,
159 Profile* profile,
160 SnapshotCaller caller) {
161 scoped_refptr<FeedbackData> feedback_data = new FeedbackData();
162 std::string bucket;
163 switch (caller) {
164 case PROFILE_RESET_WEBUI:
165 bucket = kProfileResetWebUIBucket;
166 break;
167 case PROFILE_RESET_PROMPT:
168 bucket = kProfileResetPromptBucket;
169 break;
171 feedback_data->set_category_tag(bucket);
172 feedback_data->set_description(report);
174 feedback_data->set_image(scoped_ptr<std::string>(new std::string));
175 feedback_data->set_profile(profile);
177 feedback_data->set_page_url("");
178 feedback_data->set_user_email("");
180 feedback_util::SendReport(feedback_data);
183 base::ListValue* GetReadableFeedback(Profile* profile) {
184 DCHECK(profile);
185 base::ListValue* list = new base::ListValue;
186 AddPair(list, l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_LOCALE),
187 g_browser_process->GetApplicationLocale());
188 AddPair(list,
189 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_USER_AGENT),
190 content::GetUserAgent(GURL()));
191 chrome::VersionInfo version_info;
192 std::string version = version_info.Version();
193 version += chrome::VersionInfo::GetVersionStringModifier();
194 AddPair(list,
195 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
196 version);
198 // Add snapshot data.
199 ResettableSettingsSnapshot snapshot(profile);
200 const std::vector<GURL>& urls = snapshot.startup_urls();
201 std::string startup_urls;
202 for (std::vector<GURL>::const_iterator i = urls.begin();
203 i != urls.end(); ++i) {
204 (startup_urls += i->host()) += ' ';
206 if (!startup_urls.empty()) {
207 startup_urls.erase(startup_urls.end() - 1);
208 AddPair(list,
209 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_URLS),
210 startup_urls);
213 base::string16 startup_type;
214 switch (snapshot.startup_type()) {
215 case SessionStartupPref::DEFAULT:
216 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_NEWTAB);
217 break;
218 case SessionStartupPref::LAST:
219 startup_type = l10n_util::GetStringUTF16(
220 IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION);
221 break;
222 case SessionStartupPref::URLS:
223 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_PAGES);
224 break;
225 default:
226 break;
228 AddPair(list,
229 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_TYPE),
230 startup_type);
232 if (!snapshot.homepage().empty()) {
233 AddPair(list,
234 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE),
235 snapshot.homepage());
238 int is_ntp_message_id = snapshot.homepage_is_ntp() ?
239 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_TRUE :
240 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_FALSE;
241 AddPair(list,
242 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP),
243 l10n_util::GetStringUTF16(is_ntp_message_id));
245 TemplateURLService* service =
246 TemplateURLServiceFactory::GetForProfile(profile);
247 DCHECK(service);
248 TemplateURL* dse = service->GetDefaultSearchProvider();
249 if (dse) {
250 AddPair(list,
251 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_DSE),
252 TemplateURLService::GenerateSearchURL(dse).host());
255 const ResettableSettingsSnapshot::ExtensionList& extensions =
256 snapshot.enabled_extensions();
257 std::string extension_names;
258 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i =
259 extensions.begin(); i != extensions.end(); ++i) {
260 (extension_names += i->second) += '\n';
262 if (!extension_names.empty()) {
263 extension_names.erase(extension_names.end() - 1);
264 AddPair(list,
265 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_EXTENSIONS),
266 extension_names);
268 return list;