172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_model.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/environment.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_split.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/google/google_url_tracker.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_notifications.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_fixer_upper.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/prefs/pref_set_observer.h" 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/rlz/rlz.h" 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/search_host_to_urls_map.h" 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/search_terms_data.h" 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/template_url.h" 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/template_url_model_observer.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_prepopulate_data.h" 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/util.h" 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h" 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/env_vars.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricktypedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// String in the URL that is replaced by the search term. 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kSearchTermParameter[] = "{searchTerms}"; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// String in Initializer that is replaced with kSearchTermParameter. 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kTemplateParameter[] = "%s"; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Term used when generating a search url. Use something obscure so that on 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the rare case the term replaces the URL it's unlikely another keyword would 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// have the same url. 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const char kReplacementTerm[] = "blah.blah.blah.blah.blah"; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Removes from the vector any template URL that was created because of 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// policy. These TemplateURLs are freed. 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Sets default_search_provider to NULL if it was one of them. 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic void RemoveProvidersCreatedByPolicy( 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<TemplateURL*>* template_urls, 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL** default_search_provider) { 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(template_urls); 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(default_search_provider); 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (std::vector<TemplateURL*>::iterator i = template_urls->begin(); 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick i != template_urls->end(); ) { 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURL* template_url = *i; 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (template_url->created_by_policy()) { 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (*default_search_provider && 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*default_search_provider)->id() == template_url->id()) 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *default_search_provider = NULL; 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick i = template_urls->erase(i); 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick delete template_url; 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ++i; 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TemplateURLModel::LessWithPrefix { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We want to find the set of keywords that begin with a prefix. The STL 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // algorithms will return the set of elements that are "equal to" the 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cmp() is the typical std::less<>, this results in lexicographic equality; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we need to extend this to mark a prefix as "not less than" a keyword it 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // begins, which will cause the desired elements to be considered "equal to" 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the prefix. Note: this is still a strict weak ordering, as required by 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // equal_range() (though I will not prove that here). 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Unfortunately the calling convention is not "prefix and element" but 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // rather "two elements", so we pass the prefix as a fake "element" which has 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a NULL KeywordDataElement pointer. 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool operator()(const KeywordToTemplateMap::value_type& elem1, 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const KeywordToTemplateMap::value_type& elem2) const { 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (elem1.second == NULL) ? 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (elem1.first < elem2.first); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLModel::TemplateURLModel(Profile* profile) 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loaded_(false), 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_failed_(false), 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_handle_(0), 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default_search_provider_(NULL), 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_(false), 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_id_(1) { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Init(NULL, 0); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLModel::TemplateURLModel(const Initializer* initializers, 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int count) 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(NULL), 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick loaded_(false), 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_failed_(false), 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_handle_(0), 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch service_(NULL), 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default_search_provider_(NULL), 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_(false), 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_id_(1) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Init(initializers, count); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLModel::~TemplateURLModel() { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (load_handle_) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(service_.get()); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch service_->CancelRequest(load_handle_); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&template_urls_); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURLModel::GenerateKeyword(const GURL& url, 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool autodetected) { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't autogenerate keywords for referrers that are the result of a form 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // submission (TODO: right now we approximate this by checking for the URL 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // having a query, but we should replace this with a call to WebCore to see if 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the originating page was actually a form submission), anything other than 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http, or referrers with a path. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we relax the path constraint, we need to be sure to sanitize the path 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // elements and update AutocompletePopup to look for keywords using the path. 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See http://b/issue?id=863583. 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid() || 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (autodetected && (url.has_query() || !url.SchemeIs(chrome::kHttpScheme) || 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ((url.path() != "") && (url.path() != "/"))))) 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return string16(); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Strip "www." off the front of the keyword; otherwise the keyword won't work 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return net::StripWWW(UTF8ToUTF16(url.host())); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURLModel::CleanUserInputKeyword(const string16& keyword) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove the scheme. 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 result(l10n_util::ToLower(keyword)); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_parse::Component scheme_component; 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (url_parse::ExtractScheme(UTF16ToUTF8(keyword).c_str(), 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(keyword.length()), 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &scheme_component)) { 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If the scheme isn't "http" or "https", bail. The user isn't trying to 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // type a web address, but rather an FTP, file:, or other scheme URL, or a 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // search query with some sort of initial operator (e.g. "site:"). 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (result.compare(0, scheme_component.end(), 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(chrome::kHttpScheme)) && 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result.compare(0, scheme_component.end(), 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(chrome::kHttpsScheme))) 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return string16(); 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Include trailing ':'. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.erase(0, scheme_component.end() + 1); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Many schemes usually have "//" after them, so strip it too. 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16 after_scheme(ASCIIToUTF16("//")); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result.compare(0, after_scheme.length(), after_scheme) == 0) 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.erase(0, after_scheme.length()); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove leading "www.". 17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = net::StripWWW(result); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove trailing "/". 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return (result.length() > 0 && result[result.length() - 1] == '/') ? 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.substr(0, result.length() - 1) : result; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL TemplateURLModel::GenerateSearchURL(const TemplateURL* t_url) { 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(t_url); 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return GenerateSearchURLUsingTermsData(t_url, search_terms_data); 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickGURL TemplateURLModel::GenerateSearchURLUsingTermsData( 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* t_url, 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) { 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(t_url); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURLRef* search_ref = t_url->url(); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Extension keywords don't have host-based search URLs. 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!search_ref || !search_ref->IsValidUsingTermsData(search_terms_data) || 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick t_url->IsExtensionKeyword()) 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!search_ref->SupportsReplacementUsingTermsData(search_terms_data)) 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(search_ref->url()); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return GURL(search_ref->ReplaceSearchTermsUsingTermsData( 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *t_url, ASCIIToUTF16(kReplacementTerm), 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16(), search_terms_data)); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLModel::CanReplaceKeyword( 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword, 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL** template_url_to_replace) { 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!keyword.empty()); // This should only be called for non-empty 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // keywords. If we need to support empty kewords 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the code needs to change slightly. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL* existing_url = GetTemplateURLForKeyword(keyword); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (existing_url) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We already have a TemplateURL for this keyword. Only allow it to be 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // replaced if the TemplateURL can be replaced. 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (template_url_to_replace) 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *template_url_to_replace = existing_url; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CanReplace(existing_url); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't have a TemplateURL with keyword. Only allow a new one if there 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // isn't a TemplateURL for the specified host, or there is one but it can 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be replaced. We do this to ensure that if the user assigns a different 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // keyword to a generated TemplateURL, we won't regenerate another keyword for 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the same host. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid() && !url.host().empty()) 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CanReplaceKeywordForHost(url.host(), template_url_to_replace); 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::FindMatchingKeywords( 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& prefix, 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool support_replacement_only, 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<string16>* matches) const { 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check args. 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (prefix.empty()) 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(matches != NULL); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(matches->empty()); // The code for exact matches assumes this. 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Visual Studio 2010 has problems converting NULL to the null pointer for 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // std::pair. See http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // It will work if we pass nullptr. 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(_MSC_VER) && _MSC_VER >= 1600 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const TemplateURL* null_url = nullptr; 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#else 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const TemplateURL* null_url = NULL; 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find matching keyword range. Searches the element map for keywords 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // beginning with |prefix| and stores the endpoints of the resulting set in 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |match_range|. 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::pair<KeywordToTemplateMap::const_iterator, 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeywordToTemplateMap::const_iterator> match_range( 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::equal_range( 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_to_template_map_.begin(), keyword_to_template_map_.end(), 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen KeywordToTemplateMap::value_type(prefix, null_url), 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LessWithPrefix())); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return vector of matching keywords. 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (KeywordToTemplateMap::const_iterator i(match_range.first); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != match_range.second; ++i) { 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(i->second->url()); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!support_replacement_only || i->second->url()->SupportsReplacement()) 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch matches->push_back(i->first); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst TemplateURL* TemplateURLModel::GetTemplateURLForKeyword( 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword) const { 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeywordToTemplateMap::const_iterator elem( 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_to_template_map_.find(keyword)); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (elem == keyword_to_template_map_.end()) ? NULL : elem->second; 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst TemplateURL* TemplateURLModel::GetTemplateURLForHost( 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& host) const { 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return provider_map_.GetTemplateURLForHost(host); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::Add(TemplateURL* template_url) { 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(template_url); 291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::Remove(const TemplateURL* template_url) { 295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveNoNotify(template_url); 296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::RemoveAutoGeneratedBetween(Time created_after, 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time created_before) { 301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool should_notify = false; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < template_urls_.size();) { 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (template_urls_[i]->date_created() >= created_after && 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (created_before.is_null() || 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template_urls_[i]->date_created() < created_before) && 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CanReplace(template_urls_[i])) { 307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveNoNotify(template_urls_[i]); 308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick should_notify = true; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++i; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (should_notify) 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::RemoveAutoGeneratedSince(Time created_after) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RemoveAutoGeneratedBetween(created_after, Time()); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 321513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TemplateURLModel::RegisterExtensionKeyword(const Extension* extension) { 3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(mpcomplete): disable the keyword when the extension is disabled. 3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (extension->omnibox_keyword().empty()) 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Load(); 3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!loaded_) { 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick pending_extension_ids_.push_back(extension->id()); 3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* existing_url = GetTemplateURLForExtension(extension); 33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 keyword = UTF8ToUTF16(extension->omnibox_keyword()); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<TemplateURL> template_url(new TemplateURL); 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template_url->set_short_name(UTF8ToUTF16(extension->name())); 3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_url->set_keyword(keyword); 3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This URL is not actually used for navigation. It holds the extension's 3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // ID, as well as forcing the TemplateURL to be treated as a search keyword. 3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_url->SetURL( 3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string(chrome::kExtensionScheme) + "://" + 3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension->id() + "/?q={searchTerms}", 0, 0); 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_url->set_safe_for_autoreplace(false); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (existing_url) { 3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(mpcomplete): only replace if the user hasn't changed the keyword. 3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // (We don't have UI for that yet). 348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdateNoNotify(existing_url, *template_url); 3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(template_url.release()); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TemplateURLModel::UnregisterExtensionKeyword(const Extension* extension) { 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* url = GetTemplateURLForExtension(extension); 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (url) 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Remove(url); 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst TemplateURL* TemplateURLModel::GetTemplateURLForExtension( 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* extension) const { 3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (TemplateURLVector::const_iterator i = template_urls_.begin(); 3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != template_urls_.end(); ++i) { 3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if ((*i)->IsExtensionKeyword() && (*i)->url()->GetHost() == extension->id()) 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return *i; 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<const TemplateURL*> TemplateURLModel::GetTemplateURLs() const { 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return template_urls_; 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::IncrementUsageCount(const TemplateURL* url) { 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(url && find(template_urls_.begin(), template_urls_.end(), url) != 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template_urls_.end()); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<TemplateURL*>(url)->set_usage_count(url->usage_count() + 1); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (service_.get()) 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch service_.get()->UpdateKeyword(*url); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::ResetTemplateURL(const TemplateURL* url, 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& title, 38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& search_url) { 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TemplateURL new_url(*url); 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_url.set_short_name(title); 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_url.set_keyword(keyword); 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if ((new_url.url() && search_url.empty()) || 3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (!new_url.url() && !search_url.empty()) || 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (new_url.url() && new_url.url()->url() != search_url)) { 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The urls have changed, reset the favicon url. 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_url.SetFaviconURL(GURL()); 3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_url.SetURL(search_url, 0, 0); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_url.set_safe_for_autoreplace(false); 399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdateNoNotify(url, new_url); 400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool TemplateURLModel::CanMakeDefault(const TemplateURL* url) { 404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return url != GetDefaultSearchProvider() && 405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url->url() && 406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url->url()->SupportsReplacement() && 407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !is_default_search_managed(); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::SetDefaultSearchProvider(const TemplateURL* url) { 411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_default_search_managed_) { 412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NOTREACHED(); 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_search_provider_ == url) 416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(url); 418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst TemplateURL* TemplateURLModel::GetDefaultSearchProvider() { 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (loaded_ && !load_failed_) 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return default_search_provider_; 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // We're not loaded, rely on the default search provider stored in prefs. 426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return initial_default_search_provider_.get(); 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::AddObserver(TemplateURLModelObserver* observer) { 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_observers_.AddObserver(observer); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::RemoveObserver(TemplateURLModelObserver* observer) { 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_observers_.RemoveObserver(observer); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::Load() { 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (loaded_ || load_handle_) 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!service_.get()) 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch service_ = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (service_.get()) { 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_handle_ = service_->GetKeywords(this); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ChangeToLoadedState(); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyLoaded(); 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::OnWebDataServiceRequestDone( 4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WebDataService::Handle h, 4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const WDTypedResult* result) { 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the load_handle so that we don't try and cancel the load in 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the destructor. 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_handle_ = 0; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!result) { 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Results are null if the database went away or (most likely) wasn't 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // loaded. 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_failed_ = true; 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ChangeToLoadedState(); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyLoaded(); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // initial_default_search_provider_ is only needed before we've finished 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // loading. Now that we've loaded we can nuke it. 470731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick initial_default_search_provider_.reset(); 471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_ = false; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<TemplateURL*> template_urls; 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* default_search_provider = NULL; 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int new_resource_keyword_version = 0; 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetSearchProvidersUsingKeywordResult(*result, 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick service_.get(), 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetPrefs(), 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &template_urls, 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &default_search_provider, 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &new_resource_keyword_version); 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool database_specified_a_default = NULL != default_search_provider; 484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Remove entries that were created because of policy as they may have 486731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // changed since the database was saved. 487731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveProvidersCreatedByPolicy(&template_urls, &default_search_provider); 488731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 489731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Check if default search provider is now managed. 490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURL> default_from_prefs; 491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LoadDefaultSearchProviderFromPrefs(&default_from_prefs, 492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &is_default_search_managed_); 493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_default_search_managed_) { 495731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetTemplateURLs(template_urls); 496731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Set the default. AddNoNotify will take ownership of default_from_prefs 497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // so it is safe to release. If it's null, there's no ownership to worry 498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // about :-) 499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURL* managed_default = default_from_prefs.release(); 500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (managed_default) { 501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick managed_default->set_created_by_policy(true); 502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick managed_default->set_id(0); 503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(managed_default); 504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Note that this saves the default search provider to prefs. 506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(managed_default); 5073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If we had a managed default, replace it with the first provider of 509731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the list. 510731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (database_specified_a_default && 511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL == default_search_provider && 512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !template_urls.empty()) 513731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider = template_urls[0]; 514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 515731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If the default search provider existed previously, then just 516731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // set the member variable. Otherwise, we'll set it using the method 517731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // to ensure that it is saved properly after its id is set. 518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_search_provider && default_search_provider->id() != 0) { 519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider_ = default_search_provider; 520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider = NULL; 521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetTemplateURLs(template_urls); 523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_search_provider) { 525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Note that this saves the default search provider to prefs. 526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProvider(default_search_provider); 527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Always save the default search provider to prefs. That way we don't 529731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // have to worry about it being out of sync. 530731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_search_provider_) 531731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SaveDefaultSearchProviderToPrefs(default_search_provider_); 532731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This initializes provider_map_ which should be done before 5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // calling UpdateKeywordSearchTermsForURL. 5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ChangeToLoadedState(); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Index any visits that occurred before we finished loading. 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < visits_to_add_.size(); ++i) 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateKeywordSearchTermsForURL(visits_to_add_[i]); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visits_to_add_.clear(); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (new_resource_keyword_version && service_.get()) 5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick service_->SetBuiltinKeywordVersion(new_resource_keyword_version); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 547731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyLoaded(); 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURLModel::GetKeywordShortName(const string16& keyword, 55272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool* is_extension_keyword) { 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(sky): Once LocationBarView adds a listener to the TemplateURLModel 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to track changes to the model, this should become a DCHECK. 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (template_url) { 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *is_extension_keyword = template_url->IsExtensionKeyword(); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return template_url->AdjustedShortNameForLocaleDirection(); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *is_extension_keyword = false; 56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return string16(); 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::Observe(NotificationType type, 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == NotificationType::HISTORY_URL_VISITED) { 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<history::URLVisitedDetails> visit_details(details); 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!loaded()) 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visits_to_add_.push_back(*visit_details.ptr()); 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateKeywordSearchTermsForURL(*visit_details.ptr()); 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (type == NotificationType::GOOGLE_URL_UPDATED) { 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (loaded_) 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GoogleBaseURLChanged(); 577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (type == NotificationType::PREF_CHANGED) { 578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string* pref_name = Details<std::string>(details).ptr(); 579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!pref_name || default_search_prefs_->IsObserved(*pref_name)) { 580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // A preference related to default search engine has changed. 581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Update the model if needed. 582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdateDefaultSearch(); 583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// static 590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::RegisterUserPrefs(PrefService* prefs) { 591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterBooleanPref( 592731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderEnabled, true); 593731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 594731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderName, std::string()); 595731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderID, std::string()); 597731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderPrepopulateID, std::string()); 599731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 600731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderSuggestURL, std::string()); 601731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 602731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderSearchURL, std::string()); 603731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 604731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderInstantURL, std::string()); 605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderKeyword, std::string()); 607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderIconURL, std::string()); 609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->RegisterStringPref( 610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs::kDefaultSearchProviderEncodings, std::string()); 611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 6133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::SetKeywordSearchTermsForURL(const TemplateURL* t_url, 6143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL& url, 61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& term) { 6163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HistoryService* history = profile_ ? 6173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick profile_->GetHistoryService(Profile::EXPLICIT_ACCESS) : NULL; 6183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!history) 6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen history->SetKeywordSearchTermsForURL(url, t_url->id(), term); 6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::Init(const Initializer* initializers, 6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int num_initializers) { 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Register for notifications. 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (profile_) { 6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(sky): bug 1166191. The keywords should be moved into the history 6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // db, which will mean we no longer need this notification and the history 6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // backend can handle automatically adding the search terms as the user 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // navigates. 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick registrar_.Add(this, NotificationType::HISTORY_URL_VISITED, 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Source<Profile>(profile_->GetOriginalProfile())); 633731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PrefService* prefs = GetPrefs(); 634731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_prefs_.reset( 635731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PrefSetObserver::CreateDefaultSearchPrefSetObserver(prefs, this)); 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick registrar_.Add(this, NotificationType::GOOGLE_URL_UPDATED, 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::AllSources()); 6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (num_initializers > 0) { 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This path is only hit by test code and is used to simulate a loaded 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TemplateURLModel. 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ChangeToLoadedState(); 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Add specific initializers, if any. 6463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i(0); i < num_initializers; ++i) { 6473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(initializers[i].keyword); 6483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(initializers[i].url); 6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(initializers[i].content); 6503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t template_position = 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string(initializers[i].url).find(kTemplateParameter); 65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(template_position != std::string::npos); 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string osd_url(initializers[i].url); 6553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick osd_url.replace(template_position, arraysize(kTemplateParameter) - 1, 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kSearchTermParameter); 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TemplateURLModel ends up owning the TemplateURL, don't try and free it. 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TemplateURL* template_url = new TemplateURL(); 66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template_url->set_keyword(UTF8ToUTF16(initializers[i].keyword)); 66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template_url->set_short_name(UTF8ToUTF16(initializers[i].content)); 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_url->SetURL(osd_url, 0, 0); 663731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(template_url); 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 667731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Initialize default search. 668731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdateDefaultSearch(); 669731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 670731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Request a server check for the correct Google URL if Google is the 671731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // default search engine, not in headless mode and not in Chrome Frame. 672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (initial_default_search_provider_.get()) { 673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURLRef* default_provider_ref = 674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick initial_default_search_provider_->url(); 675731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_provider_ref && default_provider_ref->HasGoogleBaseURLs()) { 676731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<base::Environment> env(base::Environment::Create()); 677731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!env->HasVar(env_vars::kHeadless) && 678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) 679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GoogleURLTracker::RequestServerCheck(); 680731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 6813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::RemoveFromMaps(const TemplateURL* template_url) { 6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!template_url->keyword().empty()) 6863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_.erase(template_url->keyword()); 6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (loaded_) 6883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.Remove(template_url); 6893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::RemoveFromKeywordMapByPointer( 6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* template_url) { 6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(template_url); 6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); 6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != keyword_to_template_map_.end(); ++i) { 6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i->second == template_url) { 6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_.erase(i); 6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // A given TemplateURL only occurs once in the map. As soon as we find the 6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // entry, stop. 7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::AddToMaps(const TemplateURL* template_url) { 7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!template_url->keyword().empty()) 7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_[template_url->keyword()] = template_url; 7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (loaded_) { 7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.Add(template_url, search_terms_data); 7113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::SetTemplateURLs(const std::vector<TemplateURL*>& urls) { 7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Add mappings for the new items. 7163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First, add the items that already have id's, so that the next_id_ 7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // gets properly set. 7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (std::vector<TemplateURL*>::const_iterator i = urls.begin(); 7203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != urls.end(); 7213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++i) { 7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if ((*i)->id() == 0) 7233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 7243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick next_id_ = std::max(next_id_, (*i)->id()); 7253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddToMaps(*i); 7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_urls_.push_back(*i); 7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Next add the new items that don't have id's. 7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (std::vector<TemplateURL*>::const_iterator i = urls.begin(); 7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != urls.end(); 7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++i) { 7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if ((*i)->id() != 0) 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 735731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(*i); 7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLModel::ChangeToLoadedState() { 7403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!loaded_); 7413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 7433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.Init(template_urls_, search_terms_data); 7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick loaded_ = true; 7453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::NotifyLoaded() { 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::TEMPLATE_URL_MODEL_LOADED, 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<TemplateURLModel>(this), 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < pending_extension_ids_.size(); ++i) { 75421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const Extension* extension = profile_->GetExtensionService()-> 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetExtensionById(pending_extension_ids_[i], true); 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension) 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RegisterExtensionKeyword(extension); 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_extension_ids_.clear(); 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::SaveDefaultSearchProviderToPrefs( 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL* t_url) { 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = GetPrefs(); 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!prefs) 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool enabled = false; 769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string search_url; 770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string suggest_url; 771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string instant_url; 772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string icon_url; 773731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string encodings; 774731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string short_name; 775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string keyword; 776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string id_string; 777731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string prepopulate_id; 778731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (t_url) { 779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick enabled = true; 780731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (t_url->url()) 781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick search_url = t_url->url()->url(); 782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (t_url->suggestions_url()) 783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick suggest_url = t_url->suggestions_url()->url(); 784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (t_url->instant_url()) 785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick instant_url = t_url->instant_url()->url(); 786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL icon_gurl = t_url->GetFaviconURL(); 787731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!icon_gurl.is_empty()) 788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick icon_url = icon_gurl.spec(); 789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick encodings = JoinString(t_url->input_encodings(), ';'); 79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen short_name = UTF16ToUTF8(t_url->short_name()); 79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen keyword = UTF16ToUTF8(t_url->keyword()); 792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick id_string = base::Int64ToString(t_url->id()); 793731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prepopulate_id = base::Int64ToString(t_url->prepopulate_id()); 794731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 795731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, enabled); 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetString(prefs::kDefaultSearchProviderSearchURL, search_url); 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, suggest_url); 798731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetString(prefs::kDefaultSearchProviderInstantURL, instant_url); 799731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetString(prefs::kDefaultSearchProviderIconURL, icon_url); 800731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings); 801731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetString(prefs::kDefaultSearchProviderName, short_name); 802731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword); 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetString(prefs::kDefaultSearchProviderID, id_string); 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id); 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->ScheduleSavePersistentPrefs(); 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLModel::LoadDefaultSearchProviderFromPrefs( 810731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURL>* default_provider, 811731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool* is_managed) { 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = GetPrefs(); 813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL)) 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const PrefService::Preference* pref = 817731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL); 818731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *is_managed = pref && pref->IsManaged(); 819731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 820731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool enabled = 821731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled); 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string suggest_url = 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->GetString(prefs::kDefaultSearchProviderSuggestURL); 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string search_url = 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->GetString(prefs::kDefaultSearchProviderSearchURL); 826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string instant_url = 827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->GetString(prefs::kDefaultSearchProviderInstantURL); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!enabled || (suggest_url.empty() && search_url.empty())) { 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user doesn't want a default search provider. 831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_provider->reset(NULL); 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 name = 83672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName)); 83772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 keyword = 83872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword)); 839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string icon_url = 840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->GetString(prefs::kDefaultSearchProviderIconURL); 841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string encodings = 842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick prefs->GetString(prefs::kDefaultSearchProviderEncodings); 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string id_string = prefs->GetString(prefs::kDefaultSearchProviderID); 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string prepopulate_id = 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->GetString(prefs::kDefaultSearchProviderPrepopulateID); 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_provider->reset(new TemplateURL()); 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*default_provider)->set_short_name(name); 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*default_provider)->SetURL(search_url, 0, 0); 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*default_provider)->SetSuggestionsURL(suggest_url, 0, 0); 851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*default_provider)->SetInstantURL(instant_url, 0, 0); 852731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*default_provider)->set_keyword(keyword); 853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (*default_provider)->SetFaviconURL(GURL(icon_url)); 854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string> encodings_vector; 855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(encodings, ';', &encodings_vector); 856731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*default_provider)->set_input_encodings(encodings_vector); 85721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!id_string.empty() && !*is_managed) { 8583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int64 value; 8593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringToInt64(id_string, &value); 8603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (*default_provider)->set_id(value); 8613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 86221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!prepopulate_id.empty() && !*is_managed) { 8633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int value; 8643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringToInt(prepopulate_id, &value); 8653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (*default_provider)->set_prepopulate_id(value); 8663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*default_provider)->set_show_in_default_list(true); 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic bool TemplateURLsHaveSamePrefs(const TemplateURL* url1, 872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* url2) { 873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (url1 == url2) 874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL != url1 && 876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL != url2 && 877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url1->short_name() == url2->short_name() && 878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url1->keyword() == url2->keyword() && 879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLRef::SameUrlRefs(url1->url(), url2->url()) && 880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLRef::SameUrlRefs(url1->suggestions_url(), 881731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url2->suggestions_url()) && 882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url1->GetFaviconURL() == url2->GetFaviconURL() && 883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url1->safe_for_autoreplace() == url2->safe_for_autoreplace() && 884731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url1->show_in_default_list() == url2->show_in_default_list() && 885731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url1->input_encodings() == url2->input_encodings(); 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 888731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLModel::CanReplaceKeywordForHost( 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& host, 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL** to_replace) { 8923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURLSet* urls = provider_map_.GetURLsForHost(host); 8933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (urls) { 8943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (TemplateURLSet::const_iterator i = urls->begin(); 8953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != urls->end(); ++i) { 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL* url = *i; 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (CanReplace(url)) { 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (to_replace) 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *to_replace = url; 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (to_replace) 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *to_replace = NULL; 9073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return !urls; 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLModel::CanReplace(const TemplateURL* t_url) { 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (t_url != default_search_provider_ && !t_url->show_in_default_list() && 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch t_url->safe_for_autoreplace()); 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 915731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::UpdateNoNotify(const TemplateURL* existing_turl, 916731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL& new_values) { 9173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(loaded_); 9183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(existing_turl); 9193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(find(template_urls_.begin(), template_urls_.end(), existing_turl) != 9203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template_urls_.end()); 9213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!existing_turl->keyword().empty()) 9233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_.erase(existing_turl->keyword()); 9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This call handles copying over the values (while retaining the id). 9263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 9273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.Update(existing_turl, new_values, search_terms_data); 9283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!existing_turl->keyword().empty()) 9303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_[existing_turl->keyword()] = existing_turl; 9313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (service_.get()) 9333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick service_->UpdateKeyword(*existing_turl); 9343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 935731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (default_search_provider_ == existing_turl) 936731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(existing_turl); 9373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPrefService* TemplateURLModel::GetPrefs() { 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return profile_ ? profile_->GetPrefs() : NULL; 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::UpdateKeywordSearchTermsForURL( 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLVisitedDetails& details) { 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLRow& row = details.row; 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!row.url().is_valid() || 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !row.url().parsed_for_possibly_invalid_spec().query.is_nonempty()) { 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURLSet* urls_for_host = 9523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.GetURLsForHost(row.url().host()); 9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!urls_for_host) 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryTerms query_terms; 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool built_terms = false; // Most URLs won't match a TemplateURLs host; 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // so we lazily build the query_terms. 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string path = row.url().path(); 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (TemplateURLSet::const_iterator i = urls_for_host->begin(); 9623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != urls_for_host->end(); ++i) { 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURLRef* search_ref = (*i)->url(); 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Count the URL against a TemplateURL if the host and path of the 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // visited URL match that of the TemplateURL as well as the search term's 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // key of the TemplateURL occurring in the visited url. 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: Even though we're iterating over TemplateURLs indexed by the host 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of the URL we still need to call GetHost on the search_ref. In 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // particular, GetHost returns an empty string if search_ref doesn't support 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // replacement or isn't valid for use in keyword search terms. 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (search_ref && search_ref->GetHost() == row.url().host() && 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch search_ref->GetPath() == path) { 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!built_terms && !BuildQueryTerms(row.url(), &query_terms)) { 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No query terms. No need to continue with the rest of the 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TemplateURLs. 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch built_terms = true; 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (PageTransition::StripQualifier(details.transition) == 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageTransition::KEYWORD) { 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The visit is the result of the user entering a keyword, generate a 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // KEYWORD_GENERATED visit for the KEYWORD so that the keyword typed 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // count is boosted. 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTabToSearchVisit(**i); 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryTerms::iterator terms_iterator = 992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch query_terms.find(search_ref->GetSearchTermKey()); 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (terms_iterator != query_terms.end() && 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !terms_iterator->second.empty()) { 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetKeywordSearchTermsForURL( 99672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *i, row.url(), search_ref->SearchTermToString16(*(*i), 997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch terms_iterator->second)); 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::AddTabToSearchVisit(const TemplateURL& t_url) { 1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only add visits for entries the user hasn't modified. If the user modified 1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the entry the keyword may no longer correspond to the host name. It may be 1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // possible to do something more sophisticated here, but it's so rare as to 1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not be worth it. 1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!t_url.safe_for_autoreplace()) 1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!profile_) 1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* history = 1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!history) 1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(t_url.keyword()), 102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string())); 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid()) 1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Synthesize a visit for the keyword. This ensures the url for the keyword is 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // autocompleted even if the user doesn't type the url in directly. 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history->AddPage(url, NULL, 0, GURL(), 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageTransition::KEYWORD_GENERATED, 10283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick history::RedirectList(), history::SOURCE_BROWSED, false); 1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLModel::BuildQueryTerms(const GURL& url, 1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryTerms* query_terms) { 1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_parse::Component query = url.parsed_for_possibly_invalid_spec().query; 1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_parse::Component key, value; 1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t valid_term_count = 0; 1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key, 1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value)) { 1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (key.is_nonempty() && value.is_nonempty()) { 1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string key_string = url.spec().substr(key.begin, key.len); 1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value_string = url.spec().substr(value.begin, value.len); 1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryTerms::iterator query_terms_iterator = 1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch query_terms->find(key_string); 1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (query_terms_iterator != query_terms->end()) { 1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!query_terms_iterator->second.empty() && 1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch query_terms_iterator->second != value_string) { 1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The term occurs in multiple places with different values. Treat 1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // this as if the term doesn't occur by setting the value to an empty 1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // string. 1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*query_terms)[key_string] = std::string(); 1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(valid_term_count > 0); 1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch valid_term_count--; 1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch valid_term_count++; 1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*query_terms)[key_string] = value_string; 1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (valid_term_count > 0); 1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLModel::GoogleBaseURLChanged() { 1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool something_changed = false; 1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < template_urls_.size(); ++i) { 1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL* t_url = template_urls_[i]; 1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((t_url->url() && t_url->url()->HasGoogleBaseURLs()) || 1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (t_url->suggestions_url() && 1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch t_url->suggestions_url()->HasGoogleBaseURLs())) { 10703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RemoveFromKeywordMapByPointer(t_url); 1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch t_url->InvalidateCachedValues(); 10723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!t_url->keyword().empty()) 10733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_to_template_map_[t_url->keyword()] = t_url; 1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch something_changed = true; 1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (something_changed && loaded_) { 10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 10803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick provider_map_.UpdateGoogleBaseURLs(search_terms_data); 1081731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 1082731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1083731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1084731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1085731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::UpdateDefaultSearch() { 1086731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!loaded_) { 1087731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Set |initial_default_search_provider_| from the preferences. We use this 1088731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // value for default search provider until the database has been loaded. 1089731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!LoadDefaultSearchProviderFromPrefs(&initial_default_search_provider_, 1090731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &is_default_search_managed_)) { 1091731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Prefs does not specify, so rely on the prepopulated engines. This 1092731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // should happen only the first time Chrome is started. 1093731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick initial_default_search_provider_.reset( 1094731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs())); 1095731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_ = false; 1096731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1097731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1098731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1099731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Load the default search specified in prefs. 1100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURL> new_default_from_prefs; 1101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool new_is_default_managed = false; 1102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Load the default from prefs. It's possible that it won't succeed 1103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // because we are in the middle of doing SaveDefaultSearchProviderToPrefs() 1104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // and all the preference items have not been saved. In that case, we 1105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // don't have yet a default. It would be much better if we could save 1106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // preferences in batches and trigger notifications at the end. 1107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LoadDefaultSearchProviderFromPrefs(&new_default_from_prefs, 1108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &new_is_default_managed); 1109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!is_default_search_managed_ && !new_is_default_managed) { 1110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // We're not interested in cases where the default was and remains 1111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // unmanaged. In that case, preferences have no impact on the default. 1112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_default_search_managed_ && new_is_default_managed) { 1115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The default was managed and remains managed. Update the default only 1116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // if it has changed; we don't want to respond to changes triggered by 1117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // SaveDefaultSearchProviderToPrefs. 1118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (TemplateURLsHaveSamePrefs(default_search_provider_, 1119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_default_from_prefs.get())) 1120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (new_default_from_prefs.get() == NULL) { 1122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // default_search_provider_ can't be NULL otherwise 1123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TemplateURLsHaveSamePrefs would have returned true. Remove this now 1124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // invalid value. 1125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* old_default = default_search_provider_; 1126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(NULL); 1127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveNoNotify(old_default); 1128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (default_search_provider_) { 1129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_default_from_prefs->set_created_by_policy(true); 1130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdateNoNotify(default_search_provider_, *new_default_from_prefs.get()); 1131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 1132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // AddNoNotify will take ownership of new_template, so it's safe to 1133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // release. 1134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURL* new_template = new_default_from_prefs.release(); 1135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (new_template) { 1136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_template->set_created_by_policy(true); 1137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(new_template); 1138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(new_template); 1140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (!is_default_search_managed_ && new_is_default_managed) { 1142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The default used to be unmanaged and is now managed. Add the new 1143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // managed default to the list of URLs and set it as default. 1144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_ = new_is_default_managed; 1145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // AddNoNotify will take ownership of new_template, so it's safe to 1146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // release. 1147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURL* new_template = new_default_from_prefs.release(); 1148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (new_template) { 1149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_template->set_created_by_policy(true); 1150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddNoNotify(new_template); 1151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(new_template); 1153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 1154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The default was managed and is no longer. 1155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(is_default_search_managed_ && !new_is_default_managed); 1156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_default_search_managed_ = new_is_default_managed; 1157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If we had a default, delete the previous default if created by policy 1158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // and set a likely default. 1159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (NULL != default_search_provider_ && 1160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider_->created_by_policy()) { 1161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* old_default = default_search_provider_; 1162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider_ = NULL; 1163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveNoNotify(old_default); 1164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); 1166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotifyObservers(); 1168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst TemplateURL* TemplateURLModel::FindNewDefaultSearchProvider() { 1171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // See if the prepoluated default still exists. 1172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURL> prepopulated_default( 1173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs())); 1174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (TemplateURLVector::iterator i = template_urls_.begin(); 1175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick i != template_urls_.end(); ) { 1176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id()) 1177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return *i; 1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If not, use the first of the templates. 1180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!template_urls_.empty()) { 1181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return template_urls_[0]; 1182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::SetDefaultSearchProviderNoNotify( 1187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* url) { 1188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!url || find(template_urls_.begin(), template_urls_.end(), url) != 1189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_urls_.end()); 1190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_search_provider_ = url; 1191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (url) { 1193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURL* modifiable_url = const_cast<TemplateURL*>(url); 1194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Don't mark the url as edited, otherwise we won't be able to rev the 1195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // template urls we ship with. 1196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick modifiable_url->set_show_in_default_list(true); 1197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (service_.get()) 1198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick service_.get()->UpdateKeyword(*url); 1199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURLRef* url_ref = url->url(); 1201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (url_ref && url_ref->HasGoogleBaseURLs()) { 1202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GoogleURLTracker::RequestServerCheck(); 1203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) 1204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RLZTracker::RecordProductEvent(rlz_lib::CHROME, 1205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rlz_lib::CHROME_OMNIBOX, 1206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rlz_lib::SET_TO_GOOGLE); 1207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif 1208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!is_default_search_managed_) 1212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SaveDefaultSearchProviderToPrefs(url); 1213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (service_.get()) 1215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick service_->SetDefaultSearchProvider(url); 1216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::AddNoNotify(TemplateURL* template_url) { 1219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(template_url); 1220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(template_url->id() == 0); 1221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(find(template_urls_.begin(), template_urls_.end(), template_url) == 1222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_urls_.end()); 1223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url->set_id(++next_id_); 1224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_urls_.push_back(template_url); 1225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddToMaps(template_url); 1226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (service_.get()) 1228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick service_->AddKeyword(*template_url); 1229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::RemoveNoNotify(const TemplateURL* template_url) { 1232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLVector::iterator i = find(template_urls_.begin(), 1233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_urls_.end(), 1234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url); 1235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (i == template_urls_.end()) 1236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (template_url == default_search_provider_) { 1239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Should never delete the default search provider. 1240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NOTREACHED(); 1241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RemoveFromMaps(template_url); 1245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Remove it from the vector containing all TemplateURLs. 1247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_urls_.erase(i); 1248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (service_.get()) 1250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick service_->RemoveKeyword(*template_url); 1251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (profile_) { 1253513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Source<Profile> source(profile_); 1254513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TemplateURLID id = template_url->id(); 1255513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationService::current()->Notify( 1256513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationType::TEMPLATE_URL_REMOVED, 1257513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch source, 1258513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Details<TemplateURLID>(&id)); 1259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // We own the TemplateURL and need to delete it. 1262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick delete template_url; 1263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLModel::NotifyObservers() { 1266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!loaded_) 1267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 1268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FOR_EACH_OBSERVER(TemplateURLModelObserver, model_observers_, 1270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick OnTemplateURLModelChanged()); 1271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1272