Home | History | Annotate | Download | only in profile_resetter
      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.
      4 
      5 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
      6 
      7 #include "base/json/json_writer.h"
      8 #include "base/prefs/pref_service.h"
      9 #include "chrome/browser/extensions/extension_service.h"
     10 #include "chrome/browser/feedback/feedback_data.h"
     11 #include "chrome/browser/feedback/feedback_util.h"
     12 #include "chrome/browser/profiles/profile.h"
     13 #include "chrome/browser/search_engines/template_url_service.h"
     14 #include "chrome/browser/search_engines/template_url_service_factory.h"
     15 #include "chrome/common/pref_names.h"
     16 
     17 namespace {
     18 
     19 // Feedback bucket label.
     20 const char kProfileResetFeedbackBucket[] = "ProfileResetReport";
     21 
     22 // Dictionary keys for feedback report.
     23 const char kDefaultSearchEnginePath[] = "default_search_engine";
     24 const char kEnabledExtensions[] = "enabled_extensions";
     25 const char kHomepageIsNewTabPage[] = "homepage_is_ntp";
     26 const char kHomepagePath[] = "homepage";
     27 const char kStartupTypePath[] = "startup_type";
     28 const char kStartupURLPath[] = "startup_urls";
     29 
     30 }  // namespace
     31 
     32 ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile)
     33     : startup_(SessionStartupPref::GetStartupPref(profile)) {
     34   // URLs are always stored sorted.
     35   std::sort(startup_.urls.begin(), startup_.urls.end());
     36 
     37   PrefService* prefs = profile->GetPrefs();
     38   DCHECK(prefs);
     39   homepage_ = prefs->GetString(prefs::kHomePage);
     40   homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage);
     41 
     42   TemplateURLService* service =
     43       TemplateURLServiceFactory::GetForProfile(profile);
     44   DCHECK(service);
     45   TemplateURL* dse = service->GetDefaultSearchProvider();
     46   if (dse)
     47     dse_url_ = dse->url();
     48 
     49   ExtensionService* extension_service = profile->GetExtensionService();
     50   DCHECK(extension_service);
     51   const ExtensionSet* enabled_ext = extension_service->extensions();
     52   enabled_extensions_.reserve(enabled_ext->size());
     53 
     54   for (ExtensionSet::const_iterator it = enabled_ext->begin();
     55        it != enabled_ext->end(); ++it)
     56     enabled_extensions_.push_back((*it)->id());
     57 
     58   // ExtensionSet is sorted but it seems to be an implementation detail.
     59   std::sort(enabled_extensions_.begin(), enabled_extensions_.end());
     60 }
     61 
     62 ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {}
     63 
     64 void ResettableSettingsSnapshot::Subtract(
     65     const ResettableSettingsSnapshot& snapshot) {
     66   std::vector<GURL> urls;
     67   std::set_difference(startup_.urls.begin(), startup_.urls.end(),
     68                       snapshot.startup_.urls.begin(),
     69                       snapshot.startup_.urls.end(),
     70                       std::back_inserter(urls));
     71   startup_.urls.swap(urls);
     72 
     73   std::vector<std::string> extensions;
     74   std::set_difference(enabled_extensions_.begin(), enabled_extensions_.end(),
     75                       snapshot.enabled_extensions_.begin(),
     76                       snapshot.enabled_extensions_.end(),
     77                       std::back_inserter(extensions));
     78   enabled_extensions_.swap(extensions);
     79 }
     80 
     81 int ResettableSettingsSnapshot::FindDifferentFields(
     82     const ResettableSettingsSnapshot& snapshot) const {
     83   int bit_mask = 0;
     84 
     85   if (startup_.urls != snapshot.startup_.urls) {
     86     bit_mask |= STARTUP_URLS;
     87   }
     88 
     89   if (startup_.type != snapshot.startup_.type)
     90     bit_mask |= STARTUP_TYPE;
     91 
     92   if (homepage_ != snapshot.homepage_)
     93     bit_mask |= HOMEPAGE;
     94 
     95   if (homepage_is_ntp_ != snapshot.homepage_is_ntp_)
     96     bit_mask |= HOMEPAGE_IS_NTP;
     97 
     98   if (dse_url_ != snapshot.dse_url_)
     99     bit_mask |= DSE_URL;
    100 
    101   if (enabled_extensions_ != snapshot.enabled_extensions_)
    102     bit_mask |= EXTENSIONS;
    103 
    104   COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
    105                  add_new_field_here);
    106 
    107   return bit_mask;
    108 }
    109 
    110 std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
    111                                     int field_mask) {
    112   DictionaryValue dict;
    113 
    114   if (field_mask & ResettableSettingsSnapshot::STARTUP_URLS) {
    115     ListValue* list = new ListValue;
    116     const std::vector<GURL>& urls = snapshot.startup_urls();
    117     for (std::vector<GURL>::const_iterator i = urls.begin();
    118          i != urls.end(); ++i)
    119       list->AppendString(i->spec());
    120     dict.Set(kStartupURLPath, list);
    121   }
    122 
    123   if (field_mask & ResettableSettingsSnapshot::STARTUP_TYPE)
    124     dict.SetInteger(kStartupTypePath, snapshot.startup_type());
    125 
    126   if (field_mask & ResettableSettingsSnapshot::HOMEPAGE)
    127     dict.SetString(kHomepagePath, snapshot.homepage());
    128 
    129   if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP)
    130     dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp());
    131 
    132   if (field_mask & ResettableSettingsSnapshot::DSE_URL)
    133     dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url());
    134 
    135   if (field_mask & ResettableSettingsSnapshot::EXTENSIONS) {
    136     ListValue* list = new ListValue;
    137     const std::vector<std::string>& extensions = snapshot.enabled_extensions();
    138     for (std::vector<std::string>::const_iterator i = extensions.begin();
    139          i != extensions.end(); ++i)
    140       list->AppendString(*i);
    141     dict.Set(kEnabledExtensions, list);
    142   }
    143 
    144   COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
    145                  serialize_new_field_here);
    146 
    147   std::string json;
    148   base::JSONWriter::Write(&dict, &json);
    149   return json;
    150 }
    151 
    152 void SendSettingsFeedback(const std::string& report, Profile* profile) {
    153   scoped_refptr<FeedbackData> feedback_data = new FeedbackData();
    154   feedback_data->set_category_tag(kProfileResetFeedbackBucket);
    155   feedback_data->set_description(report);
    156 
    157   feedback_data->set_image(ScreenshotDataPtr());
    158   feedback_data->set_profile(profile);
    159 
    160   feedback_data->set_page_url("");
    161   feedback_data->set_user_email("");
    162 
    163   FeedbackUtil::SendReport(feedback_data);
    164 }
    165