Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Side by Side Diff: chrome/browser/protector/default_search_provider_change.cc

Issue 11493003: Remove the protector service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix implicit ExtensionSystem -> TemplateURLService dependency Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 <algorithm>
6
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/protector/base_setting_change.h"
14 #include "chrome/browser/protector/histograms.h"
15 #include "chrome/browser/protector/protector_service.h"
16 #include "chrome/browser/protector/protector_service_factory.h"
17 #include "chrome/browser/search_engines/template_url.h"
18 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
19 #include "chrome/browser/search_engines/template_url_service.h"
20 #include "chrome/browser/search_engines/template_url_service_factory.h"
21 #include "chrome/browser/search_engines/template_url_service_observer.h"
22 #include "chrome/browser/webdata/keyword_table.h"
23 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/url_constants.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_service.h"
28 #include "googleurl/src/gurl.h"
29 #include "grit/chromium_strings.h"
30 #include "grit/generated_resources.h"
31 #include "grit/theme_resources.h"
32 #include "ui/base/l10n/l10n_util.h"
33
34 namespace protector {
35
36 namespace {
37
38 // Maximum length of the search engine name to be displayed.
39 const size_t kMaxDisplayedNameLength = 16;
40
41 // Matches TemplateURL with all fields set from the prepopulated data equal
42 // to fields in another TemplateURL.
43 class TemplateURLIsSame {
44 public:
45 // Creates a matcher based on |other|.
46 explicit TemplateURLIsSame(const TemplateURL* other) : other_(other) {
47 }
48
49 // Returns true if both |other| and |url| are NULL or have same field values.
50 bool operator()(const TemplateURL* url) {
51 if (url == other_ )
52 return true;
53 if (!url || !other_)
54 return false;
55 return url->short_name() == other_->short_name() &&
56 url->HasSameKeywordAs(*other_) &&
57 url->url() == other_->url() &&
58 url->suggestions_url() == other_->suggestions_url() &&
59 url->instant_url() == other_->instant_url() &&
60 url->safe_for_autoreplace() == other_->safe_for_autoreplace() &&
61 url->favicon_url() == other_->favicon_url() &&
62 url->show_in_default_list() == other_->show_in_default_list() &&
63 url->input_encodings() == other_->input_encodings() &&
64 url->prepopulate_id() == other_->prepopulate_id();
65 }
66
67 private:
68 const TemplateURL* other_;
69 };
70
71 } // namespace
72
73 // Default search engine change tracked by Protector.
74 class DefaultSearchProviderChange : public BaseSettingChange,
75 public TemplateURLServiceObserver,
76 public content::NotificationObserver {
77 public:
78 DefaultSearchProviderChange(TemplateURL* new_search_provider,
79 TemplateURL* backup_search_provider);
80
81 // BaseSettingChange overrides:
82 virtual bool Init(Profile* profile) OVERRIDE;
83 virtual void InitWhenDisabled(Profile* profile) OVERRIDE;
84 virtual void Apply(Browser* browser) OVERRIDE;
85 virtual void Discard(Browser* browser) OVERRIDE;
86 virtual void Timeout() OVERRIDE;
87 virtual int GetBadgeIconID() const OVERRIDE;
88 virtual int GetMenuItemIconID() const OVERRIDE;
89 virtual int GetBubbleIconID() const OVERRIDE;
90 virtual string16 GetBubbleTitle() const OVERRIDE;
91 virtual string16 GetBubbleMessage() const OVERRIDE;
92 virtual string16 GetApplyButtonText() const OVERRIDE;
93 virtual string16 GetDiscardButtonText() const OVERRIDE;
94 virtual DisplayName GetApplyDisplayName() const OVERRIDE;
95 virtual GURL GetNewSettingURL() const OVERRIDE;
96
97 private:
98 virtual ~DefaultSearchProviderChange();
99
100 // TemplateURLServiceObserver overrides:
101 virtual void OnTemplateURLServiceChanged() OVERRIDE;
102
103 // content::NotificationObserver overrides:
104 virtual void Observe(int type,
105 const content::NotificationSource& source,
106 const content::NotificationDetails& details) OVERRIDE;
107
108 // Sets the default search provider to |*search_provider|. If a matching
109 // TemplateURL already exists, it is reused and |*search_provider| is reset.
110 // Otherwise, adds |*search_provider| to keywords and releases it.
111 // In both cases, |*search_provider| is NULL after this call.
112 // Returns the new default search provider (either |*search_provider| or the
113 // reused TemplateURL).
114 const TemplateURL* SetDefaultSearchProvider(
115 scoped_ptr<TemplateURL>* search_provider);
116
117 // Returns true if |new_search_provider_| can be used as the default search
118 // provider.
119 bool NewSearchProviderValid() const;
120
121 // Opens the Search engine settings page in a new tab.
122 void OpenSearchEngineSettings(Browser* browser);
123
124 // Returns the TemplateURLService instance for the Profile this change is
125 // related to.
126 TemplateURLService* GetTemplateURLService();
127
128 // Histogram ID of the new search provider.
129 int new_histogram_id_;
130 // Indicates that the default search was restored to the prepopulated default
131 // search engines.
132 bool is_fallback_;
133 // Indicates that the the prepopulated default search is the same as
134 // |new_search_provider_|.
135 bool fallback_is_new_;
136 // ID of |new_search_provider_|.
137 TemplateURLID new_id_;
138 // The default search at the moment the change was detected. Will be used to
139 // restore the new default search back if Apply is called. Will be set to
140 // |NULL| if removed from the TemplateURLService.
141 TemplateURL* new_search_provider_;
142 // Default search provider set by Init for the period until user makes a
143 // choice and either Apply or Discard is performed. Never is |NULL| during
144 // that period since the change will dismiss itself if this provider gets
145 // deleted or stops being the default.
146 const TemplateURL* default_search_provider_;
147 // Stores backup of the default search until it becomes owned by the
148 // TemplateURLService or deleted.
149 scoped_ptr<TemplateURL> backup_search_provider_;
150 content::NotificationRegistrar registrar_;
151
152 DISALLOW_COPY_AND_ASSIGN(DefaultSearchProviderChange);
153 };
154
155 DefaultSearchProviderChange::DefaultSearchProviderChange(
156 TemplateURL* new_search_provider,
157 TemplateURL* backup_search_provider)
158 : new_histogram_id_(GetSearchProviderHistogramID(new_search_provider)),
159 is_fallback_(false),
160 fallback_is_new_(false),
161 new_search_provider_(new_search_provider),
162 default_search_provider_(NULL),
163 backup_search_provider_(backup_search_provider) {
164 if (backup_search_provider) {
165 UMA_HISTOGRAM_ENUMERATION(
166 kProtectorHistogramSearchProviderHijacked,
167 new_histogram_id_,
168 kProtectorMaxSearchProviderID);
169 } else {
170 UMA_HISTOGRAM_ENUMERATION(
171 kProtectorHistogramSearchProviderCorrupt,
172 new_histogram_id_,
173 kProtectorMaxSearchProviderID);
174 }
175 }
176
177 DefaultSearchProviderChange::~DefaultSearchProviderChange() {
178 if (profile())
179 GetTemplateURLService()->RemoveObserver(this);
180 }
181
182 bool DefaultSearchProviderChange::Init(Profile* profile) {
183 if (!BaseSettingChange::Init(profile))
184 return false;
185
186 if (!backup_search_provider_.get() ||
187 !backup_search_provider_->SupportsReplacement()) {
188 // Fallback to a prepopulated default search provider, ignoring any
189 // overrides in Prefs.
190 backup_search_provider_.reset(
191 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
192 is_fallback_ = true;
193 VLOG(1) << "Fallback search provider: "
194 << backup_search_provider_->short_name();
195 }
196
197 default_search_provider_ = SetDefaultSearchProvider(&backup_search_provider_);
198 DCHECK(default_search_provider_);
199 // |backup_search_provider_| should be |NULL| since now.
200 DCHECK(!backup_search_provider_.get());
201 if (is_fallback_ && default_search_provider_ == new_search_provider_)
202 fallback_is_new_ = true;
203
204 int restored_histogram_id =
205 GetSearchProviderHistogramID(default_search_provider_);
206 UMA_HISTOGRAM_ENUMERATION(
207 kProtectorHistogramSearchProviderRestored,
208 restored_histogram_id,
209 kProtectorMaxSearchProviderID);
210
211 if (is_fallback_) {
212 VLOG(1) << "Fallback to search provider: "
213 << default_search_provider_->short_name();
214 UMA_HISTOGRAM_ENUMERATION(
215 kProtectorHistogramSearchProviderFallback,
216 restored_histogram_id,
217 kProtectorMaxSearchProviderID);
218 }
219
220 // Listen for the default search provider changes.
221 GetTemplateURLService()->AddObserver(this);
222
223 if (new_search_provider_) {
224 // Listen for removal of |new_search_provider_|.
225 new_id_ = new_search_provider_->id();
226 registrar_.Add(
227 this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED,
228 content::Source<Profile>(profile->GetOriginalProfile()));
229 }
230
231 return true;
232 }
233
234 void DefaultSearchProviderChange::InitWhenDisabled(Profile* profile) {
235 // The --no-protector case is handled in TemplateURLService internals.
236 // TODO(ivankr): move it here.
237 NOTREACHED();
238 }
239
240 void DefaultSearchProviderChange::Apply(Browser* browser) {
241 UMA_HISTOGRAM_ENUMERATION(
242 kProtectorHistogramSearchProviderApplied,
243 new_histogram_id_,
244 kProtectorMaxSearchProviderID);
245
246 GetTemplateURLService()->RemoveObserver(this);
247 if (NewSearchProviderValid()) {
248 GetTemplateURLService()->SetDefaultSearchProvider(new_search_provider_);
249 } else {
250 // Open settings page in case the new setting is invalid.
251 OpenSearchEngineSettings(browser);
252 }
253 }
254
255 void DefaultSearchProviderChange::Discard(Browser* browser) {
256 UMA_HISTOGRAM_ENUMERATION(
257 kProtectorHistogramSearchProviderDiscarded,
258 new_histogram_id_,
259 kProtectorMaxSearchProviderID);
260
261 GetTemplateURLService()->RemoveObserver(this);
262 if (is_fallback_) {
263 // Open settings page in case the old setting is invalid.
264 OpenSearchEngineSettings(browser);
265 }
266 // Nothing to do otherwise since we have already set the search engine
267 // to |old_id_| in |Init|.
268 }
269
270 void DefaultSearchProviderChange::Timeout() {
271 UMA_HISTOGRAM_ENUMERATION(
272 kProtectorHistogramSearchProviderTimeout,
273 new_histogram_id_,
274 kProtectorMaxSearchProviderID);
275 }
276
277 int DefaultSearchProviderChange::GetBadgeIconID() const {
278 return IDR_SEARCH_ENGINE_CHANGE_BADGE;
279 }
280
281 int DefaultSearchProviderChange::GetMenuItemIconID() const {
282 return IDR_SEARCH_ENGINE_CHANGE_MENU;
283 }
284
285 int DefaultSearchProviderChange::GetBubbleIconID() const {
286 return IDR_SEARCH_ENGINE_CHANGE_ALERT;
287 }
288
289 string16 DefaultSearchProviderChange::GetBubbleTitle() const {
290 return l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_CHANGE_TITLE);
291 }
292
293 string16 DefaultSearchProviderChange::GetBubbleMessage() const {
294 if (is_fallback_) {
295 return l10n_util::GetStringFUTF16(
296 IDS_SEARCH_ENGINE_CHANGE_NO_BACKUP_MESSAGE,
297 default_search_provider_->short_name());
298 }
299 return l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_CHANGE_MESSAGE);
300 }
301
302 string16 DefaultSearchProviderChange::GetApplyButtonText() const {
303 if (NewSearchProviderValid()) {
304 // If backup search engine is lost and fallback was made to the current
305 // search provider then there is no need to show this button.
306 if (fallback_is_new_)
307 return string16();
308 string16 name = new_search_provider_->short_name();
309 return (name.length() > kMaxDisplayedNameLength) ?
310 l10n_util::GetStringUTF16(IDS_CHANGE_SEARCH_ENGINE_NO_NAME) :
311 l10n_util::GetStringFUTF16(IDS_CHANGE_SEARCH_ENGINE, name);
312 }
313 if (is_fallback_) {
314 // Both settings are lost: don't show this button.
315 return string16();
316 }
317 // New setting is lost, offer to go to settings.
318 return l10n_util::GetStringUTF16(IDS_SELECT_SEARCH_ENGINE);
319 }
320
321 string16 DefaultSearchProviderChange::GetDiscardButtonText() const {
322 if (!is_fallback_) {
323 string16 name = default_search_provider_->short_name();
324 return (name.length() > kMaxDisplayedNameLength) ?
325 l10n_util::GetStringUTF16(IDS_KEEP_SETTING) :
326 l10n_util::GetStringFUTF16(IDS_KEEP_SEARCH_ENGINE, name);
327 }
328 // Old setting is lost, offer to go to settings.
329 return l10n_util::GetStringUTF16(IDS_SELECT_SEARCH_ENGINE);
330 }
331
332 BaseSettingChange::DisplayName
333 DefaultSearchProviderChange::GetApplyDisplayName() const {
334 if (NewSearchProviderValid() &&
335 new_search_provider_->short_name().length() <= kMaxDisplayedNameLength) {
336 return DisplayName(kDefaultSearchProviderChangeNamePriority,
337 new_search_provider_->short_name());
338 }
339 // Return the default empty name.
340 return BaseSettingChange::GetApplyDisplayName();
341 }
342
343 GURL DefaultSearchProviderChange::GetNewSettingURL() const {
344 if (is_fallback_) {
345 // Do not collide this change when fallback was made, since the message
346 // and Discard behaviour is pretty different.
347 return GURL();
348 }
349 if (!NewSearchProviderValid())
350 return GURL();
351 return TemplateURLService::GenerateSearchURL(new_search_provider_);
352 }
353
354 void DefaultSearchProviderChange::OnTemplateURLServiceChanged() {
355 TemplateURLService* url_service = GetTemplateURLService();
356 if (url_service->GetDefaultSearchProvider() != default_search_provider_) {
357 VLOG(1) << "Default search provider has been changed by user";
358 default_search_provider_ = NULL;
359 url_service->RemoveObserver(this);
360 // Will delete this DefaultSearchProviderChange instance.
361 ProtectorServiceFactory::GetForProfile(profile())->DismissChange(this);
362 }
363 }
364
365 void DefaultSearchProviderChange::Observe(
366 int type,
367 const content::NotificationSource& source,
368 const content::NotificationDetails& details) {
369 DCHECK(type == chrome::NOTIFICATION_TEMPLATE_URL_REMOVED);
370 TemplateURLID id = *content::Details<TemplateURLID>(details).ptr();
371 if (id == new_id_)
372 new_search_provider_ = NULL;
373 registrar_.Remove(this, type, source);
374 // TODO(ivankr): should the change be dismissed as well? Probably not,
375 // since this may happend due to Sync or whatever. In that case, if user
376 // clicks on 'Change to...', the Search engine settings page will be opened.
377 }
378
379 const TemplateURL* DefaultSearchProviderChange::SetDefaultSearchProvider(
380 scoped_ptr<TemplateURL>* search_provider) {
381 TemplateURLService* url_service = GetTemplateURLService();
382 TemplateURLService::TemplateURLVector urls = url_service->GetTemplateURLs();
383 TemplateURL* new_default_provider = NULL;
384
385 // Check if this provider already exists and add it otherwise.
386 TemplateURLService::TemplateURLVector::const_iterator i =
387 std::find_if(urls.begin(), urls.end(),
388 TemplateURLIsSame(search_provider->get()));
389 if (i != urls.end()) {
390 VLOG(1) << "Provider already exists";
391 new_default_provider = *i;
392 search_provider->reset();
393 } else {
394 VLOG(1) << "No match, adding new provider";
395 new_default_provider = search_provider->get();
396 url_service->Add(search_provider->release());
397 UMA_HISTOGRAM_ENUMERATION(
398 kProtectorHistogramSearchProviderMissing,
399 GetSearchProviderHistogramID(new_default_provider),
400 kProtectorMaxSearchProviderID);
401 }
402
403 // TODO(ivankr): handle keyword conflicts with existing providers.
404 DCHECK(new_default_provider);
405 VLOG(1) << "Default search provider set to: "
406 << new_default_provider->short_name();
407 url_service->SetDefaultSearchProvider(new_default_provider);
408 return new_default_provider;
409 }
410
411 bool DefaultSearchProviderChange::NewSearchProviderValid() const {
412 return new_search_provider_ && new_search_provider_->SupportsReplacement();
413 }
414
415 void DefaultSearchProviderChange::OpenSearchEngineSettings(Browser* browser) {
416 ProtectorServiceFactory::GetForProfile(profile())->OpenTab(
417 GURL(std::string(chrome::kChromeUISettingsURL) +
418 chrome::kSearchEnginesSubPage), browser);
419 }
420
421 TemplateURLService* DefaultSearchProviderChange::GetTemplateURLService() {
422 TemplateURLService* url_service =
423 TemplateURLServiceFactory::GetForProfile(profile());
424 DCHECK(url_service);
425 return url_service;
426 }
427
428 BaseSettingChange* CreateDefaultSearchProviderChange(TemplateURL* actual,
429 TemplateURL* backup) {
430 return new DefaultSearchProviderChange(actual, backup);
431 }
432
433 } // namespace protector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698