Remove the dependency of PasswordStore on BrowserContextKeyedService
[chromium-blink-merge.git] / chrome / browser / profile_resetter / resettable_settings_snapshot.cc
blobeace6bd79f9c561d75e9850d6e8422ac2b1393b6
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/synchronization/cancellation_flag.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/feedback/feedback_data.h"
15 #include "chrome/browser/feedback/feedback_util.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/search_engines/template_url_service.h"
18 #include "chrome/browser/search_engines/template_url_service_factory.h"
19 #include "chrome/common/chrome_version_info.h"
20 #include "chrome/common/pref_names.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "grit/generated_resources.h"
23 #include "grit/google_chrome_strings.h"
24 #include "ui/base/l10n/l10n_util.h"
26 namespace {
28 // Feedback bucket labels.
29 const char kProfileResetPromptBucket[] = "SamplingOfSettingsResetPrompt";
30 const char kProfileResetWebUIBucket[] = "ProfileResetReport";
32 // Dictionary keys for feedback report.
33 const char kDefaultSearchEnginePath[] = "default_search_engine";
34 const char kEnabledExtensions[] = "enabled_extensions";
35 const char kHomepageIsNewTabPage[] = "homepage_is_ntp";
36 const char kHomepagePath[] = "homepage";
37 const char kShortcuts[] = "shortcuts";
38 const char kStartupTypePath[] = "startup_type";
39 const char kStartupURLPath[] = "startup_urls";
41 template <class StringType>
42 void AddPair(base::ListValue* list,
43 const base::string16& key,
44 const StringType& value) {
45 base::DictionaryValue* results = new base::DictionaryValue();
46 results->SetString("key", key);
47 results->SetString("value", value);
48 list->Append(results);
51 } // namespace
53 ResettableSettingsSnapshot::ResettableSettingsSnapshot(
54 Profile* profile)
55 : startup_(SessionStartupPref::GetStartupPref(profile)),
56 shortcuts_determined_(false),
57 weak_ptr_factory_(this) {
58 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
59 // URLs are always stored sorted.
60 std::sort(startup_.urls.begin(), startup_.urls.end());
62 PrefService* prefs = profile->GetPrefs();
63 DCHECK(prefs);
64 homepage_ = prefs->GetString(prefs::kHomePage);
65 homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage);
67 TemplateURLService* service =
68 TemplateURLServiceFactory::GetForProfile(profile);
69 DCHECK(service);
70 TemplateURL* dse = service->GetDefaultSearchProvider();
71 if (dse)
72 dse_url_ = dse->url();
74 ExtensionService* extension_service = profile->GetExtensionService();
75 DCHECK(extension_service);
76 const extensions::ExtensionSet* enabled_ext = extension_service->extensions();
77 enabled_extensions_.reserve(enabled_ext->size());
79 for (extensions::ExtensionSet::const_iterator it = enabled_ext->begin();
80 it != enabled_ext->end(); ++it)
81 enabled_extensions_.push_back(std::make_pair((*it)->id(), (*it)->name()));
83 // ExtensionSet is sorted but it seems to be an implementation detail.
84 std::sort(enabled_extensions_.begin(), enabled_extensions_.end());
87 ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {
88 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
89 if (cancellation_flag_)
90 cancellation_flag_->data.Set();
93 void ResettableSettingsSnapshot::Subtract(
94 const ResettableSettingsSnapshot& snapshot) {
95 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
96 ExtensionList extensions = base::STLSetDifference<ExtensionList>(
97 enabled_extensions_, snapshot.enabled_extensions_);
98 enabled_extensions_.swap(extensions);
101 int ResettableSettingsSnapshot::FindDifferentFields(
102 const ResettableSettingsSnapshot& snapshot) const {
103 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
104 int bit_mask = 0;
106 if (startup_.type != snapshot.startup_.type ||
107 startup_.urls != snapshot.startup_.urls)
108 bit_mask |= STARTUP_MODE;
110 if (homepage_is_ntp_ != snapshot.homepage_is_ntp_ ||
111 homepage_ != snapshot.homepage_)
112 bit_mask |= HOMEPAGE;
114 if (dse_url_ != snapshot.dse_url_)
115 bit_mask |= DSE_URL;
117 if (enabled_extensions_ != snapshot.enabled_extensions_)
118 bit_mask |= EXTENSIONS;
120 if (shortcuts_ != snapshot.shortcuts_)
121 bit_mask |= SHORTCUTS;
123 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31,
124 add_new_field_here);
126 return bit_mask;
129 void ResettableSettingsSnapshot::RequestShortcuts(
130 const base::Closure& callback) {
131 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
132 DCHECK(!cancellation_flag_ && !shortcuts_determined());
134 cancellation_flag_ = new SharedCancellationFlag;
135 content::BrowserThread::PostTaskAndReplyWithResult(
136 content::BrowserThread::FILE,
137 FROM_HERE,
138 base::Bind(&GetChromeLaunchShortcuts, cancellation_flag_),
139 base::Bind(&ResettableSettingsSnapshot::SetShortcutsAndReport,
140 weak_ptr_factory_.GetWeakPtr(),
141 callback));
144 void ResettableSettingsSnapshot::SetShortcutsAndReport(
145 const base::Closure& callback,
146 const std::vector<ShortcutCommand>& shortcuts) {
147 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
148 shortcuts_ = shortcuts;
149 shortcuts_determined_ = true;
150 cancellation_flag_ = NULL;
152 if (!callback.is_null())
153 callback.Run();
156 std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
157 int field_mask) {
158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
159 base::DictionaryValue dict;
161 if (field_mask & ResettableSettingsSnapshot::STARTUP_MODE) {
162 base::ListValue* list = new base::ListValue;
163 const std::vector<GURL>& urls = snapshot.startup_urls();
164 for (std::vector<GURL>::const_iterator i = urls.begin();
165 i != urls.end(); ++i)
166 list->AppendString(i->spec());
167 dict.Set(kStartupURLPath, list);
168 dict.SetInteger(kStartupTypePath, snapshot.startup_type());
171 if (field_mask & ResettableSettingsSnapshot::HOMEPAGE) {
172 dict.SetString(kHomepagePath, snapshot.homepage());
173 dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp());
176 if (field_mask & ResettableSettingsSnapshot::DSE_URL)
177 dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url());
179 if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) {
180 base::ListValue* list = new base::ListValue;
181 const ResettableSettingsSnapshot::ExtensionList& extensions =
182 snapshot.enabled_extensions();
183 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i =
184 extensions.begin(); i != extensions.end(); ++i) {
185 // Replace "\"" to simplify server-side analysis.
186 std::string ext_name;
187 base::ReplaceChars(i->second, "\"", "\'", &ext_name);
188 list->AppendString(i->first + ";" + ext_name);
190 dict.Set(kEnabledExtensions, list);
193 if (field_mask & ResettableSettingsSnapshot::SHORTCUTS) {
194 base::ListValue* list = new base::ListValue;
195 const std::vector<ShortcutCommand>& shortcuts = snapshot.shortcuts();
196 for (std::vector<ShortcutCommand>::const_iterator i = shortcuts.begin();
197 i != shortcuts.end(); ++i) {
198 base::string16 arguments;
199 // Replace "\"" to simplify server-side analysis.
200 base::ReplaceChars(i->second, base::ASCIIToUTF16("\"").c_str(),
201 base::ASCIIToUTF16("\'"), &arguments);
202 list->AppendString(arguments);
204 dict.Set(kShortcuts, list);
207 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31,
208 serialize_new_field_here);
210 std::string json;
211 base::JSONWriter::Write(&dict, &json);
212 return json;
215 void SendSettingsFeedback(const std::string& report,
216 Profile* profile,
217 SnapshotCaller caller) {
218 scoped_refptr<FeedbackData> feedback_data = new FeedbackData();
219 std::string bucket;
220 switch (caller) {
221 case PROFILE_RESET_WEBUI:
222 bucket = kProfileResetWebUIBucket;
223 break;
224 case PROFILE_RESET_PROMPT:
225 bucket = kProfileResetPromptBucket;
226 break;
228 feedback_data->set_category_tag(bucket);
229 feedback_data->set_description(report);
231 feedback_data->set_image(make_scoped_ptr(new std::string));
232 feedback_data->set_profile(profile);
234 feedback_data->set_page_url("");
235 feedback_data->set_user_email("");
237 feedback_util::SendReport(feedback_data);
240 scoped_ptr<base::ListValue> GetReadableFeedbackForSnapshot(
241 Profile* profile,
242 const ResettableSettingsSnapshot& snapshot) {
243 DCHECK(profile);
244 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
245 scoped_ptr<base::ListValue> list(new base::ListValue);
246 AddPair(list.get(),
247 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_LOCALE),
248 g_browser_process->GetApplicationLocale());
249 AddPair(list.get(),
250 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_USER_AGENT),
251 content::GetUserAgent(GURL()));
252 chrome::VersionInfo version_info;
253 std::string version = version_info.Version();
254 version += chrome::VersionInfo::GetVersionStringModifier();
255 AddPair(list.get(),
256 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
257 version);
259 // Add snapshot data.
260 const std::vector<GURL>& urls = snapshot.startup_urls();
261 std::string startup_urls;
262 for (std::vector<GURL>::const_iterator i = urls.begin();
263 i != urls.end(); ++i) {
264 if (!startup_urls.empty())
265 startup_urls += ' ';
266 startup_urls += i->host();
268 if (!startup_urls.empty()) {
269 AddPair(list.get(),
270 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_URLS),
271 startup_urls);
274 base::string16 startup_type;
275 switch (snapshot.startup_type()) {
276 case SessionStartupPref::DEFAULT:
277 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_NEWTAB);
278 break;
279 case SessionStartupPref::LAST:
280 startup_type = l10n_util::GetStringUTF16(
281 IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION);
282 break;
283 case SessionStartupPref::URLS:
284 startup_type = l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_PAGES);
285 break;
286 default:
287 break;
289 AddPair(list.get(),
290 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_STARTUP_TYPE),
291 startup_type);
293 if (!snapshot.homepage().empty()) {
294 AddPair(list.get(),
295 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE),
296 snapshot.homepage());
299 int is_ntp_message_id = snapshot.homepage_is_ntp() ?
300 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_TRUE :
301 IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP_FALSE;
302 AddPair(list.get(),
303 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_HOMEPAGE_IS_NTP),
304 l10n_util::GetStringUTF16(is_ntp_message_id));
306 TemplateURLService* service =
307 TemplateURLServiceFactory::GetForProfile(profile);
308 DCHECK(service);
309 TemplateURL* dse = service->GetDefaultSearchProvider();
310 if (dse) {
311 AddPair(list.get(),
312 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_DSE),
313 TemplateURLService::GenerateSearchURL(dse).host());
316 if (snapshot.shortcuts_determined()) {
317 base::string16 shortcut_targets;
318 const std::vector<ShortcutCommand>& shortcuts = snapshot.shortcuts();
319 for (std::vector<ShortcutCommand>::const_iterator i =
320 shortcuts.begin(); i != shortcuts.end(); ++i) {
321 if (!shortcut_targets.empty())
322 shortcut_targets += base::ASCIIToUTF16("\n");
323 shortcut_targets += base::ASCIIToUTF16("chrome.exe ");
324 shortcut_targets += i->second;
326 if (!shortcut_targets.empty()) {
327 AddPair(list.get(),
328 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_SHORTCUTS),
329 shortcut_targets);
331 } else {
332 AddPair(list.get(),
333 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_SHORTCUTS),
334 l10n_util::GetStringUTF16(
335 IDS_RESET_PROFILE_SETTINGS_PROCESSING_SHORTCUTS));
338 const ResettableSettingsSnapshot::ExtensionList& extensions =
339 snapshot.enabled_extensions();
340 std::string extension_names;
341 for (ResettableSettingsSnapshot::ExtensionList::const_iterator i =
342 extensions.begin(); i != extensions.end(); ++i) {
343 if (!extension_names.empty())
344 extension_names += '\n';
345 extension_names += i->second;
347 if (!extension_names.empty()) {
348 AddPair(list.get(),
349 l10n_util::GetStringUTF16(IDS_RESET_PROFILE_SETTINGS_EXTENSIONS),
350 extension_names);
352 return list.Pass();