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 "build/build_config.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_fetcher.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_number_conversions.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h" 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url.h" 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/search_engines/template_url_fetcher_callbacks.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_model.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_parser.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_status.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RequestDelegate ------------------------------------------------------------ 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TemplateURLFetcher::RequestDelegate : public URLFetcher::Delegate, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public NotificationObserver { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Takes ownership of |callbacks|. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestDelegate(TemplateURLFetcher* fetcher, 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword, 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& osdd_url, 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& favicon_url, 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLFetcherCallbacks* callbacks, 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProviderType provider_type); 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // NotificationObserver: 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void Observe(NotificationType type, 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationSource& source, 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationDetails& details); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URLFetcher::Delegate: 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If data contains a valid OSDD, a TemplateURL is created and added to 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the TemplateURLModel. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnURLFetchComplete(const URLFetcher* source, 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus& status, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResponseCookies& cookies, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URL of the OSDD. 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GURL url() const { return osdd_url_; } 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Keyword to use. 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 keyword() const { return keyword_; } 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The type of search provider being fetched. 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProviderType provider_type() const { return provider_type_; } 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void AddSearchProvider(); 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher url_fetcher_; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TemplateURLFetcher* fetcher_; 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURL> template_url_; 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 keyword_; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL osdd_url_; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL favicon_url_; 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ProviderType provider_type_; 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURLFetcherCallbacks> callbacks_; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handles registering for our notifications. 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationRegistrar registrar_; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(RequestDelegate); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTemplateURLFetcher::RequestDelegate::RequestDelegate( 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLFetcher* fetcher, 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword, 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& osdd_url, 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& favicon_url, 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLFetcherCallbacks* callbacks, 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProviderType provider_type) 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : ALLOW_THIS_IN_INITIALIZER_LIST(url_fetcher_(osdd_url, 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick URLFetcher::GET, this)), 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick fetcher_(fetcher), 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick keyword_(keyword), 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick osdd_url_(osdd_url), 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick favicon_url_(favicon_url), 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick provider_type_(provider_type), 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick callbacks_(callbacks) { 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLModel* model = fetcher_->profile()->GetTemplateURLModel(); 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(model); // TemplateURLFetcher::ScheduleDownload verifies this. 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!model->loaded()) { 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Start the model load and set-up waiting for it. 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick registrar_.Add(this, 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotificationType::TEMPLATE_URL_MODEL_LOADED, 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Source<TemplateURLModel>(model)); 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick model->Load(); 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_.set_request_context(fetcher->profile()->GetRequestContext()); 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_.Start(); 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLFetcher::RequestDelegate::Observe( 108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotificationType type, 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationSource& source, 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationDetails& details) { 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(type == NotificationType::TEMPLATE_URL_MODEL_LOADED); 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!template_url_.get()) 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddSearchProvider(); 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // WARNING: AddSearchProvider deletes us. 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLFetcher::RequestDelegate::OnURLFetchComplete( 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const URLFetcher* source, 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus& status, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResponseCookies& cookies, 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data) { 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url_.reset(new TemplateURL()); 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Validation checks. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we can still replace the keyword, i.e. the fetch was successful. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the OSDD file was loaded HTTP, we also have to check the response_code. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For other schemes, e.g. when the OSDD file is bundled with an extension, 132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the response_code is not applicable and should be -1. Also, ensure that 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the returned information results in a valid search URL. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!status.is_success() || 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ((response_code != -1) && (response_code != 200)) || 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !TemplateURLParser::Parse( 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick reinterpret_cast<const unsigned char*>(data.c_str()), 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick data.length(), 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL, 140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url_.get()) || 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !template_url_->url() || !template_url_->url()->SupportsReplacement()) { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher_->RequestCompleted(this); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WARNING: RequestCompleted deletes us. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Wait for the model to be loaded before adding the provider. 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLModel* model = fetcher_->profile()->GetTemplateURLModel(); 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!model->loaded()) 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddSearchProvider(); 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // WARNING: AddSearchProvider deletes us. 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLFetcher::RequestDelegate::AddSearchProvider() { 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(template_url_.get()); 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (provider_type_ != AUTODETECTED_PROVIDER || keyword_.empty()) { 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Generate new keyword from URL in OSDD for none autodetected case. 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Previous keyword was generated from URL where OSDD was placed and 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // it gives wrong result when OSDD is located on third party site that 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // has nothing in common with search engine in OSDD. 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL keyword_url(template_url_->url()->url()); 16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 new_keyword = TemplateURLModel::GenerateKeyword( 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick keyword_url, false); 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!new_keyword.empty()) 166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick keyword_ = new_keyword; 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLModel* model = fetcher_->profile()->GetTemplateURLModel(); 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* existing_url; 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (keyword_.empty() || 171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !model || !model->loaded() || 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !model->CanReplaceKeyword(keyword_, GURL(template_url_->url()->url()), 173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &existing_url)) { 174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (provider_type_ == AUTODETECTED_PROVIDER || !model || !model->loaded()) { 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick fetcher_->RequestCompleted(this); 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // WARNING: RequestCompleted deletes us. 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick existing_url = NULL; 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Try to generate a keyword automatically when we are setting the default 183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // provider. The keyword isn't as important in this case. 184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (provider_type_ == EXPLICIT_DEFAULT_PROVIDER) { 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The loop numbers are arbitrary and are simply a strong effort. 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 new_keyword; 187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (int i = 0; i < 100; ++i) { 188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Concatenate a number at end of the keyword and try that. 189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_keyword = keyword_; 190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Try the keyword alone the first time 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (i > 0) 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new_keyword.append(base::IntToString16(i)); 193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!model->GetTemplateURLForKeyword(new_keyword) || 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick model->CanReplaceKeyword(new_keyword, 195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL(template_url_->url()->url()), 196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &existing_url)) { 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_keyword.clear(); 200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick existing_url = NULL; 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (new_keyword.empty()) { 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // A keyword could not be found. This user must have a lot of numerical 205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // keywords built up. 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher_->RequestCompleted(this); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WARNING: RequestCompleted deletes us. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick keyword_ = new_keyword; 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we're coming from JS (neither autodetected nor failure to load the 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // template URL model) and this URL already exists in the model, we bring 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // up the EditKeywordController to edit it. This is helpful feedback in 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the case of clicking a button twice, and annoying in the case of a 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // page that calls AddSearchProvider() in JS without a user action. 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_.clear(); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (existing_url) 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick model->Remove(existing_url); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The short name is what is shown to the user. We preserve original names 225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // since it is better when generated keyword in many cases. 226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url_->set_keyword(keyword_); 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url_->set_originating_url(osdd_url_); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The page may have specified a URL to use for favicons, if not, set it. 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!template_url_->GetFaviconURL().is_valid()) 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen template_url_->SetFaviconURL(favicon_url_); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick switch (provider_type_) { 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case AUTODETECTED_PROVIDER: 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Mark the keyword as replaceable so it can be removed if necessary. 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url_->set_safe_for_autoreplace(true); 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick model->Add(template_url_.release()); 238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case EXPLICIT_PROVIDER: 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Confirm addition and allow user to edit default choices. It's ironic 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that only *non*-autodetected additions get confirmed, but the user 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // expects feedback that his action did something. 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The source TabContents' delegate takes care of adding the URL to the 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // model, which takes ownership, or of deleting it if the add is 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cancelled. 247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick callbacks_->ConfirmAddSearchProvider(template_url_.release(), 248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick fetcher_->profile()); 249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case EXPLICIT_DEFAULT_PROVIDER: 252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick callbacks_->ConfirmSetDefaultSearchProvider(template_url_.release(), 253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick model); 254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher_->RequestCompleted(this); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WARNING: RequestCompleted deletes us. 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TemplateURLFetcher --------------------------------------------------------- 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLFetcher::TemplateURLFetcher(Profile* profile) : profile_(profile) { 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLFetcher::~TemplateURLFetcher() { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURLFetcher::ScheduleDownload( 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& keyword, 272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& osdd_url, 273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& favicon_url, 274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLFetcherCallbacks* callbacks, 275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProviderType provider_type) { 276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(osdd_url.is_valid()); 277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<TemplateURLFetcherCallbacks> owned_callbacks(callbacks); 278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // For JS added OSDD empty keyword is OK because we will generate keyword 280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // later from OSDD content. 281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (provider_type == TemplateURLFetcher::AUTODETECTED_PROVIDER && 282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick keyword.empty()) 283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TemplateURLModel* url_model = profile()->GetTemplateURLModel(); 285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!url_model) 286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Avoid certain checks for the default provider because we'll do the load 289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // and try to brute force a unique keyword for it. 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (provider_type != TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER) { 291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!url_model->loaded()) { 292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_model->Load(); 293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURL* template_url = 296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_model->GetTemplateURLForKeyword(keyword); 297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (template_url && (!template_url->safe_for_autoreplace() || 298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick template_url->originating_url() == osdd_url)) { 299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Either there is a user created TemplateURL for this keyword, or the 300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // keyword has the same OSDD url and we've parsed it. 301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we aren't already downloading this request. 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<RequestDelegate*>::iterator i = requests_->begin(); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != requests_->end(); ++i) { 308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool keyword_or_osdd_match = (*i)->url() == osdd_url || 309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*i)->keyword() == keyword; 310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool same_type_or_neither_is_default = 311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (*i)->provider_type() == provider_type || 312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ((*i)->provider_type() != EXPLICIT_DEFAULT_PROVIDER && 313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick provider_type != EXPLICIT_DEFAULT_PROVIDER); 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (keyword_or_osdd_match && same_type_or_neither_is_default) 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requests_->push_back( 319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new RequestDelegate(this, keyword, osdd_url, favicon_url, 320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick owned_callbacks.release(), provider_type)); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLFetcher::RequestCompleted(RequestDelegate* request) { 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(find(requests_->begin(), requests_->end(), request) != 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requests_->end()); 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requests_->erase(find(requests_->begin(), requests_->end(), request)); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete request; 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 329