blob: 054272711e854a0cc203bf34b48ff8331c094a12 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
#include "base/json/json_writer.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/feedback/feedback_data.h"
#include "chrome/browser/feedback/feedback_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/common/pref_names.h"
namespace {
// Feedback bucket label.
const char kProfileResetFeedbackBucket[] = "ProfileResetReport";
// Dictionary keys for feedback report.
const char kDefaultSearchEnginePath[] = "default_search_engine";
const char kEnabledExtensions[] = "enabled_extensions";
const char kHomepageIsNewTabPage[] = "homepage_is_ntp";
const char kHomepagePath[] = "homepage";
const char kStartupTypePath[] = "startup_type";
const char kStartupURLPath[] = "startup_urls";
} // namespace
ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile)
: startup_(SessionStartupPref::GetStartupPref(profile)) {
// URLs are always stored sorted.
std::sort(startup_.urls.begin(), startup_.urls.end());
PrefService* prefs = profile->GetPrefs();
DCHECK(prefs);
homepage_ = prefs->GetString(prefs::kHomePage);
homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage);
TemplateURLService* service =
TemplateURLServiceFactory::GetForProfile(profile);
DCHECK(service);
TemplateURL* dse = service->GetDefaultSearchProvider();
if (dse)
dse_url_ = dse->url();
ExtensionService* extension_service = profile->GetExtensionService();
DCHECK(extension_service);
const ExtensionSet* enabled_ext = extension_service->extensions();
enabled_extensions_.reserve(enabled_ext->size());
for (ExtensionSet::const_iterator it = enabled_ext->begin();
it != enabled_ext->end(); ++it)
enabled_extensions_.push_back((*it)->id());
// ExtensionSet is sorted but it seems to be an implementation detail.
std::sort(enabled_extensions_.begin(), enabled_extensions_.end());
}
ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {}
void ResettableSettingsSnapshot::Subtract(
const ResettableSettingsSnapshot& snapshot) {
std::vector<GURL> urls;
std::set_difference(startup_.urls.begin(), startup_.urls.end(),
snapshot.startup_.urls.begin(),
snapshot.startup_.urls.end(),
std::back_inserter(urls));
startup_.urls.swap(urls);
std::vector<std::string> extensions;
std::set_difference(enabled_extensions_.begin(), enabled_extensions_.end(),
snapshot.enabled_extensions_.begin(),
snapshot.enabled_extensions_.end(),
std::back_inserter(extensions));
enabled_extensions_.swap(extensions);
}
int ResettableSettingsSnapshot::FindDifferentFields(
const ResettableSettingsSnapshot& snapshot) const {
int bit_mask = 0;
if (startup_.urls != snapshot.startup_.urls) {
bit_mask |= STARTUP_URLS;
}
if (startup_.type != snapshot.startup_.type)
bit_mask |= STARTUP_TYPE;
if (homepage_ != snapshot.homepage_)
bit_mask |= HOMEPAGE;
if (homepage_is_ntp_ != snapshot.homepage_is_ntp_)
bit_mask |= HOMEPAGE_IS_NTP;
if (dse_url_ != snapshot.dse_url_)
bit_mask |= DSE_URL;
if (enabled_extensions_ != snapshot.enabled_extensions_)
bit_mask |= EXTENSIONS;
COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
add_new_field_here);
return bit_mask;
}
std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
int field_mask) {
DictionaryValue dict;
if (field_mask & ResettableSettingsSnapshot::STARTUP_URLS) {
ListValue* list = new ListValue;
const std::vector<GURL>& urls = snapshot.startup_urls();
for (std::vector<GURL>::const_iterator i = urls.begin();
i != urls.end(); ++i)
list->AppendString(i->spec());
dict.Set(kStartupURLPath, list);
}
if (field_mask & ResettableSettingsSnapshot::STARTUP_TYPE)
dict.SetInteger(kStartupTypePath, snapshot.startup_type());
if (field_mask & ResettableSettingsSnapshot::HOMEPAGE)
dict.SetString(kHomepagePath, snapshot.homepage());
if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP)
dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp());
if (field_mask & ResettableSettingsSnapshot::DSE_URL)
dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url());
if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) {
ListValue* list = new ListValue;
const std::vector<std::string>& extensions = snapshot.enabled_extensions();
for (std::vector<std::string>::const_iterator i = extensions.begin();
i != extensions.end(); ++i)
list->AppendString(*i);
dict.Set(kEnabledExtensions, list);
}
COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
serialize_new_field_here);
std::string json;
base::JSONWriter::Write(&dict, &json);
return json;
}
void SendSettingsFeedback(const std::string& report, Profile* profile) {
scoped_refptr<FeedbackData> feedback_data = new FeedbackData();
feedback_data->set_category_tag(kProfileResetFeedbackBucket);
feedback_data->set_description(report);
feedback_data->set_image(ScreenshotDataPtr());
feedback_data->set_profile(profile);
feedback_data->set_page_url("");
feedback_data->set_user_email("");
FeedbackUtil::SendReport(feedback_data);
}