Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / settings_overrides / settings_overrides_api.cc
1 // Copyright 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/extensions/api/settings_overrides/settings_overrides_api.h"
6
7 #include "base/lazy_instance.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/api/preference/preference_api.h"
10 #include "chrome/browser/prefs/session_startup_pref.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/search_engines/template_url.h"
13 #include "chrome/browser/search_engines/template_url_service_factory.h"
14 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
15 #include "chrome/common/pref_names.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/browser/extension_prefs_factory.h"
18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/common/error_utils.h"
20 #include "extensions/common/manifest_constants.h"
21
22 namespace extensions {
23
24 namespace {
25
26 base::LazyInstance<BrowserContextKeyedAPIFactory<SettingsOverridesAPI> >
27     g_factory = LAZY_INSTANCE_INITIALIZER;
28
29 const char kManyStartupPagesWarning[] = "* specifies more than 1 startup URL. "
30     "All but the first will be ignored.";
31
32 using api::manifest_types::ChromeSettingsOverrides;
33
34 std::string SubstituteInstallParam(std::string str,
35                                    const std::string& install_parameter) {
36   ReplaceSubstringsAfterOffset(&str, 0, "__PARAM__", install_parameter);
37   return str;
38 }
39
40 TemplateURLData ConvertSearchProvider(
41     const ChromeSettingsOverrides::Search_provider& search_provider,
42     const std::string& install_parameter) {
43   TemplateURLData data;
44
45   data.short_name = base::UTF8ToUTF16(search_provider.name);
46   data.SetKeyword(base::UTF8ToUTF16(search_provider.keyword));
47   data.SetURL(
48       SubstituteInstallParam(search_provider.search_url, install_parameter));
49   if (search_provider.suggest_url) {
50     data.suggestions_url =
51         SubstituteInstallParam(*search_provider.suggest_url, install_parameter);
52   }
53   if (search_provider.instant_url) {
54     data.instant_url =
55         SubstituteInstallParam(*search_provider.instant_url, install_parameter);
56   }
57   if (search_provider.image_url) {
58     data.image_url =
59         SubstituteInstallParam(*search_provider.image_url, install_parameter);
60   }
61   if (search_provider.search_url_post_params)
62     data.search_url_post_params = *search_provider.search_url_post_params;
63   if (search_provider.suggest_url_post_params)
64     data.suggestions_url_post_params = *search_provider.suggest_url_post_params;
65   if (search_provider.instant_url_post_params)
66     data.instant_url_post_params = *search_provider.instant_url_post_params;
67   if (search_provider.image_url_post_params)
68     data.image_url_post_params = *search_provider.image_url_post_params;
69   data.favicon_url = GURL(
70       SubstituteInstallParam(search_provider.favicon_url, install_parameter));
71   data.safe_for_autoreplace = false;
72   data.input_encodings.push_back(search_provider.encoding);
73   data.date_created = base::Time();
74   data.last_modified = base::Time();
75   data.prepopulate_id = 0;
76   if (search_provider.alternate_urls) {
77     for (size_t i = 0; i < search_provider.alternate_urls->size(); ++i) {
78       if (!search_provider.alternate_urls->at(i).empty())
79         data.alternate_urls.push_back(SubstituteInstallParam(
80             search_provider.alternate_urls->at(i), install_parameter));
81     }
82   }
83   return data;
84 }
85
86 }  // namespace
87
88 SettingsOverridesAPI::SettingsOverridesAPI(content::BrowserContext* context)
89     : profile_(Profile::FromBrowserContext(context)),
90       url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
91       extension_registry_observer_(this) {
92   extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
93 }
94
95 SettingsOverridesAPI::~SettingsOverridesAPI() {
96 }
97
98 BrowserContextKeyedAPIFactory<SettingsOverridesAPI>*
99 SettingsOverridesAPI::GetFactoryInstance() {
100   return g_factory.Pointer();
101 }
102
103 void SettingsOverridesAPI::SetPref(const std::string& extension_id,
104                                    const std::string& pref_key,
105                                    base::Value* value) {
106   PreferenceAPI* prefs = PreferenceAPI::Get(profile_);
107   if (!prefs)
108     return;  // Expected in unit tests.
109   prefs->SetExtensionControlledPref(extension_id,
110                                     pref_key,
111                                     kExtensionPrefsScopeRegular,
112                                     value);
113 }
114
115 void SettingsOverridesAPI::UnsetPref(const std::string& extension_id,
116                                      const std::string& pref_key) {
117   PreferenceAPI* prefs = PreferenceAPI::Get(profile_);
118   if (!prefs)
119     return;  // Expected in unit tests.
120   prefs->RemoveExtensionControlledPref(
121       extension_id,
122       pref_key,
123       kExtensionPrefsScopeRegular);
124 }
125
126 void SettingsOverridesAPI::OnExtensionLoaded(
127     content::BrowserContext* browser_context,
128     const Extension* extension) {
129   const SettingsOverrides* settings = SettingsOverrides::Get(extension);
130   if (settings) {
131     std::string install_parameter =
132         ExtensionPrefs::Get(profile_)->GetInstallParam(extension->id());
133     if (settings->homepage) {
134       SetPref(extension->id(),
135               prefs::kHomePage,
136               new base::StringValue(SubstituteInstallParam(
137                   settings->homepage->spec(), install_parameter)));
138       SetPref(extension->id(),
139               prefs::kHomePageIsNewTabPage,
140               new base::FundamentalValue(false));
141     }
142     if (!settings->startup_pages.empty()) {
143       SetPref(extension->id(),
144               prefs::kRestoreOnStartup,
145               new base::FundamentalValue(SessionStartupPref::kPrefValueURLs));
146       if (settings->startup_pages.size() > 1) {
147         VLOG(1) << extensions::ErrorUtils::FormatErrorMessage(
148                        kManyStartupPagesWarning,
149                        manifest_keys::kSettingsOverride);
150       }
151       scoped_ptr<base::ListValue> url_list(new base::ListValue);
152       url_list->Append(new base::StringValue(SubstituteInstallParam(
153           settings->startup_pages[0].spec(), install_parameter)));
154       SetPref(
155           extension->id(), prefs::kURLsToRestoreOnStartup, url_list.release());
156     }
157     if (settings->search_engine) {
158       // Bring the preference to the correct state. Before this code set it
159       // to "true" for all search engines. Thus, we should overwrite it for
160       // all search engines.
161       if (settings->search_engine->is_default) {
162         SetPref(extension->id(),
163                 prefs::kDefaultSearchProviderEnabled,
164                 new base::FundamentalValue(true));
165       } else {
166         UnsetPref(extension->id(), prefs::kDefaultSearchProviderEnabled);
167       }
168       DCHECK(url_service_);
169       if (url_service_->loaded()) {
170         RegisterSearchProvider(extension);
171       } else {
172         if (!template_url_sub_) {
173           template_url_sub_ = url_service_->RegisterOnLoadedCallback(
174               base::Bind(&SettingsOverridesAPI::OnTemplateURLsLoaded,
175                          base::Unretained(this)));
176         }
177         url_service_->Load();
178         pending_extensions_.insert(extension);
179       }
180     }
181   }
182 }
183 void SettingsOverridesAPI::OnExtensionUnloaded(
184     content::BrowserContext* browser_context,
185     const Extension* extension,
186     UnloadedExtensionInfo::Reason reason) {
187   const SettingsOverrides* settings = SettingsOverrides::Get(extension);
188   if (settings) {
189     if (settings->homepage) {
190       UnsetPref(extension->id(), prefs::kHomePage);
191       UnsetPref(extension->id(), prefs::kHomePageIsNewTabPage);
192     }
193     if (!settings->startup_pages.empty()) {
194       UnsetPref(extension->id(), prefs::kRestoreOnStartup);
195       UnsetPref(extension->id(), prefs::kURLsToRestoreOnStartup);
196     }
197     if (settings->search_engine) {
198       DCHECK(url_service_);
199       if (url_service_->loaded())
200         url_service_->RemoveExtensionControlledTURL(extension->id());
201       else
202         pending_extensions_.erase(extension);
203     }
204   }
205 }
206
207 void SettingsOverridesAPI::Shutdown() {
208   template_url_sub_.reset();
209 }
210
211 void SettingsOverridesAPI::OnTemplateURLsLoaded() {
212   // Register search providers for pending extensions.
213   template_url_sub_.reset();
214   for (PendingExtensions::const_iterator i(pending_extensions_.begin());
215        i != pending_extensions_.end(); ++i) {
216     RegisterSearchProvider(*i);
217   }
218   pending_extensions_.clear();
219 }
220
221 void SettingsOverridesAPI::RegisterSearchProvider(
222     const Extension* extension) const {
223   DCHECK(url_service_);
224   DCHECK(extension);
225   const SettingsOverrides* settings = SettingsOverrides::Get(extension);
226   DCHECK(settings);
227   DCHECK(settings->search_engine);
228   scoped_ptr<AssociatedExtensionInfo> info(new AssociatedExtensionInfo);
229   info->extension_id = extension->id();
230   info->wants_to_be_default_engine = settings->search_engine->is_default;
231   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
232   info->install_time = prefs->GetInstallTime(extension->id());
233   std::string install_parameter = prefs->GetInstallParam(extension->id());
234   TemplateURLData data =
235       ConvertSearchProvider(*settings->search_engine, install_parameter);
236   data.show_in_default_list = info->wants_to_be_default_engine;
237   url_service_->AddExtensionControlledTURL(new TemplateURL(profile_, data),
238                                            info.Pass());
239 }
240
241 template <>
242 void BrowserContextKeyedAPIFactory<
243     SettingsOverridesAPI>::DeclareFactoryDependencies() {
244   DependsOn(ExtensionPrefsFactory::GetInstance());
245   DependsOn(PreferenceAPI::GetFactoryInstance());
246   DependsOn(TemplateURLServiceFactory::GetInstance());
247 }
248
249 }  // namespace extensions