diff options
Diffstat (limited to 'chrome/browser')
4 files changed, 193 insertions, 21 deletions
diff --git a/chrome/browser/search_engines/search_provider_install_data.cc b/chrome/browser/search_engines/search_provider_install_data.cc index 10ac1c2..132ffc2 100644 --- a/chrome/browser/search_engines/search_provider_install_data.cc +++ b/chrome/browser/search_engines/search_provider_install_data.cc @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "base/ref_counted.h" #include "base/task.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/search_engines/search_host_to_urls_map.h" @@ -16,6 +17,11 @@ #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/search_engines/util.h" #include "chrome/browser/webdata/web_data_service.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; @@ -24,7 +30,7 @@ namespace { // Implementation of SearchTermsData that may be used on the I/O thread. class IOThreadSearchTermsData : public SearchTermsData { public: - IOThreadSearchTermsData() {} + explicit IOThreadSearchTermsData(std::string google_base_url); // Implementation of SearchTermsData. virtual std::string GoogleBaseURLValue() const; @@ -37,13 +43,17 @@ class IOThreadSearchTermsData : public SearchTermsData { #endif private: + std::string google_base_url_; DISALLOW_COPY_AND_ASSIGN(IOThreadSearchTermsData); }; +IOThreadSearchTermsData::IOThreadSearchTermsData(std::string google_base_url) + : google_base_url_(google_base_url) { +} + std::string IOThreadSearchTermsData::GoogleBaseURLValue() const { - // TODO(levin): fix this. - return "http://FIXME.FIXME/"; + return google_base_url_; } std::string IOThreadSearchTermsData::GetApplicationLocale() const { @@ -51,6 +61,87 @@ std::string IOThreadSearchTermsData::GetApplicationLocale() const { return "yy"; } +// Handles telling SearchProviderInstallData about changes to the google base +// url. +class GoogleURLChangeNotifier + : public base::RefCountedThreadSafe<GoogleURLChangeNotifier> { + public: + explicit GoogleURLChangeNotifier( + const base::WeakPtr<SearchProviderInstallData>& install_data); + + // Called on the I/O thread with the Google base URL whenever the value + // changes. + void OnChange(const std::string& google_base_url); + + private: + friend class base::RefCountedThreadSafe<GoogleURLChangeNotifier>; + ~GoogleURLChangeNotifier() {} + + base::WeakPtr<SearchProviderInstallData> install_data_; + + DISALLOW_COPY_AND_ASSIGN(GoogleURLChangeNotifier); +}; + +GoogleURLChangeNotifier::GoogleURLChangeNotifier( + const base::WeakPtr<SearchProviderInstallData>& install_data) + : install_data_(install_data) { +} + +void GoogleURLChangeNotifier::OnChange(const std::string& google_base_url) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (install_data_) + install_data_->OnGoogleURLChange(google_base_url); +} + +// Notices changes in the Google base URL and sends them along +// to the SearchProviderInstallData on the I/O thread. +class GoogleURLObserver : public NotificationObserver { + public: + GoogleURLObserver( + GoogleURLChangeNotifier* change_notifier, + NotificationType ui_death_notification, + const NotificationSource& ui_death_source); + + // Implementation of NotificationObserver. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + private: + virtual ~GoogleURLObserver() {} + + scoped_refptr<GoogleURLChangeNotifier> change_notifier_; + NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(GoogleURLObserver); +}; + +GoogleURLObserver::GoogleURLObserver( + GoogleURLChangeNotifier* change_notifier, + NotificationType ui_death_notification, + const NotificationSource& ui_death_source) + : change_notifier_(change_notifier) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + registrar_.Add(this, NotificationType::GOOGLE_URL_UPDATED, + NotificationService::AllSources()); + registrar_.Add(this, ui_death_notification, ui_death_source); +} + +void GoogleURLObserver::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::GOOGLE_URL_UPDATED) { + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, + NewRunnableMethod( + change_notifier_.get(), + &GoogleURLChangeNotifier::OnChange, + UIThreadSearchTermsData().GoogleBaseURLValue())); + } else { + // This must be the death notification. + delete this; + } +} + // Indicates if the two inputs have the same security origin. // |requested_origin| should only be a security origin (no path, etc.). // It is ok if |template_url| is NULL. @@ -67,9 +158,16 @@ static bool IsSameOrigin(const GURL& requested_origin, } // namespace SearchProviderInstallData::SearchProviderInstallData( - WebDataService* web_service) + WebDataService* web_service, + NotificationType ui_death_notification, + const NotificationSource& ui_death_source) : web_service_(web_service), - load_handle_(0) { + load_handle_(0), + google_base_url_(UIThreadSearchTermsData().GoogleBaseURLValue()) { + // GoogleURLObserver is responsible for killing itself when + // the given notification occurs. + new GoogleURLObserver(new GoogleURLChangeNotifier(AsWeakPtr()), + ui_death_notification, ui_death_source); } SearchProviderInstallData::~SearchProviderInstallData() { @@ -115,7 +213,7 @@ SearchProviderInstallData::State SearchProviderInstallData::GetInstallState( if (!urls) return NOT_INSTALLED; - IOThreadSearchTermsData search_terms_data; + IOThreadSearchTermsData search_terms_data(google_base_url_); for (TemplateURLSet::const_iterator i = urls->begin(); i != urls->end(); ++i) { const TemplateURL* template_url = *i; @@ -125,6 +223,11 @@ SearchProviderInstallData::State SearchProviderInstallData::GetInstallState( return NOT_INSTALLED; } +void SearchProviderInstallData::OnGoogleURLChange( + const std::string& google_base_url) { + google_base_url_ = google_base_url; +} + void SearchProviderInstallData::OnWebDataServiceRequestDone( WebDataService::Handle h, const WDTypedResult* result) { @@ -153,7 +256,7 @@ void SearchProviderInstallData::OnWebDataServiceRequestDone( template_urls_.get().insert(template_urls_.get().begin(), extracted_template_urls.begin(), extracted_template_urls.end()); - IOThreadSearchTermsData search_terms_data; + IOThreadSearchTermsData search_terms_data(google_base_url_); provider_map_.reset(new SearchHostToURLsMap()); provider_map_->Init(template_urls_.get(), search_terms_data); SetDefault(default_search_provider); @@ -168,7 +271,7 @@ void SearchProviderInstallData::SetDefault(const TemplateURL* template_url) { return; } - IOThreadSearchTermsData search_terms_data; + IOThreadSearchTermsData search_terms_data(google_base_url_); const GURL url(TemplateURLModel::GenerateSearchURLUsingTermsData( template_url, search_terms_data)); if (!url.is_valid() || !url.has_host()) { @@ -182,7 +285,7 @@ void SearchProviderInstallData::OnLoadFailed() { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); provider_map_.reset(new SearchHostToURLsMap()); - IOThreadSearchTermsData search_terms_data; + IOThreadSearchTermsData search_terms_data(google_base_url_); provider_map_->Init(template_urls_.get(), search_terms_data); SetDefault(NULL); NotifyLoaded(); diff --git a/chrome/browser/search_engines/search_provider_install_data.h b/chrome/browser/search_engines/search_provider_install_data.h index f6fbf3b..3a7d525 100644 --- a/chrome/browser/search_engines/search_provider_install_data.h +++ b/chrome/browser/search_engines/search_provider_install_data.h @@ -13,9 +13,12 @@ #include "base/scoped_ptr.h" #include "base/scoped_vector.h" #include "base/task_queue.h" +#include "base/weak_ptr.h" #include "chrome/browser/webdata/web_data_service.h" class GURL; +class NotificationSource; +class NotificationType; class SearchHostToURLsMap; class Task; class TemplateURL; @@ -24,7 +27,8 @@ class TemplateURL; // loading the data on demand (when CallWhenLoaded is called) and then throwing // away the results after the callbacks are done, so the results are always up // to date with what is in the database. -class SearchProviderInstallData : public WebDataServiceConsumer { +class SearchProviderInstallData : public WebDataServiceConsumer, + public base::SupportsWeakPtr<SearchProviderInstallData> { public: enum State { // The search provider is not installed. @@ -37,20 +41,28 @@ class SearchProviderInstallData : public WebDataServiceConsumer { INSTALLED_AS_DEFAULT = 2 }; - explicit SearchProviderInstallData(WebDataService* web_service); - ~SearchProviderInstallData(); - - // Use to determine when the search provider information is loaded. - // The callback may happen synchronously or asynchronously. This - // takes ownership of |task|. There is no need to do anything special - // to make it function (as it just relies on the normal I/O thread message - // loop). + // |ui_death_notification| and |ui_death_source| indentify a notification that + // may be observed on the UI thread to know when this class no longer needs to + // be kept up to date. (Note that this class may be deleted before or after + // that notification occurs. It doesn't matter.) + SearchProviderInstallData(WebDataService* web_service, + NotificationType ui_death_notification, + const NotificationSource& ui_death_source); + virtual ~SearchProviderInstallData(); + + // Use to determine when the search provider information is loaded. The + // callback may happen synchronously or asynchronously. This takes ownership + // of |task|. There is no need to do anything special to make it function + // (as it just relies on the normal I/O thread message loop). void CallWhenLoaded(Task* task); // Returns the search provider install state for the given origin. // This should only be called while a task is called back from CallWhenLoaded. State GetInstallState(const GURL& requested_origin); + // Called when the google base url has changed. + void OnGoogleURLChange(const std::string& google_base_url); + private: // WebDataServiceConsumer // Notification that the keywords have been loaded. @@ -88,6 +100,9 @@ class SearchProviderInstallData : public WebDataServiceConsumer { // The security origin for the default search provider. std::string default_search_origin_; + // The google base url. + std::string google_base_url_; + DISALLOW_COPY_AND_ASSIGN(SearchProviderInstallData); }; diff --git a/chrome/browser/search_engines/search_provider_install_data_unittest.cc b/chrome/browser/search_engines/search_provider_install_data_unittest.cc index f64f671..9cdfa82 100644 --- a/chrome/browser/search_engines/search_provider_install_data_unittest.cc +++ b/chrome/browser/search_engines/search_provider_install_data_unittest.cc @@ -13,6 +13,9 @@ #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/search_engines/template_url_model_test_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" #include "testing/gtest/include/gtest/gtest.h" // Create a TemplateURL. The caller owns the returned TemplateURL*. @@ -157,7 +160,10 @@ class SearchProviderInstallDataTest : public testing::Test { virtual void SetUp() { testing::Test::SetUp(); util_.SetUp(); - install_data_ = new SearchProviderInstallData(util_.GetWebDataService()); + install_data_ = new SearchProviderInstallData( + util_.GetWebDataService(), + NotificationType::RENDERER_PROCESS_TERMINATED, + Source<SearchProviderInstallDataTest>(this)); io_thread_.reset(new ChromeThread(ChromeThread::IO)); io_thread_->Start(); } @@ -170,6 +176,14 @@ class SearchProviderInstallDataTest : public testing::Test { util_.BlockTillIOThreadProcessesRequests(); io_thread_->Stop(); io_thread_.reset(); + + // Make sure that the install data class on the UI thread gets cleaned up. + // It doesn't matter that this happens after install_data_ is deleted. + NotificationService::current()->Notify( + NotificationType::RENDERER_PROCESS_TERMINATED, + Source<SearchProviderInstallDataTest>(this), + NotificationService::NoDetails()); + util_.TearDown(); testing::Test::TearDown(); } @@ -211,3 +225,41 @@ TEST_F(SearchProviderInstallDataTest, GetInstallState) { test_get_install_state->set_default_search_provider_host(default_host); EXPECT_TRUE(test_get_install_state->RunTests(*io_thread_.get())); } + + +TEST_F(SearchProviderInstallDataTest, GoogleBaseUrlChange) { + scoped_refptr<TestGetInstallState> test_get_install_state( + new TestGetInstallState(install_data_)); + + // Set up the database. + util_.ChangeModelToLoadState(); + std::string google_host = "w.com"; + util_.SetGoogleBaseURL("http://" + google_host + "/"); + // Wait for the I/O thread to process the update notification. + util_.BlockTillIOThreadProcessesRequests(); + + TemplateURL* t_url = CreateTemplateURL("{google:baseURL}?q={searchTerms}", + L"t"); + util_.model()->Add(t_url); + TemplateURL* default_url = CreateTemplateURL("http://d.com/", + L"d"); + util_.model()->Add(default_url); + util_.model()->SetDefaultSearchProvider(default_url); + + // Wait for the changes to be saved. + util_.BlockTillServiceProcessesRequests(); + + // Verify the search providers install state (with no default set). + test_get_install_state->set_search_provider_host(google_host); + EXPECT_TRUE(test_get_install_state->RunTests(*io_thread_.get())); + + // Change the Google base url. + google_host = "foo.com"; + util_.SetGoogleBaseURL("http://" + google_host + "/"); + // Wait for the I/O thread to process the update notification. + util_.BlockTillIOThreadProcessesRequests(); + + // Verify that the change got picked up. + test_get_install_state->set_search_provider_host(google_host); + EXPECT_TRUE(test_get_install_state->RunTests(*io_thread_.get())); +} diff --git a/chrome/browser/search_engines/template_url_model_test_util.h b/chrome/browser/search_engines/template_url_model_test_util.h index cdcafa9..109e2cc 100644 --- a/chrome/browser/search_engines/template_url_model_test_util.h +++ b/chrome/browser/search_engines/template_url_model_test_util.h @@ -6,6 +6,8 @@ #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_MODEL_TEST_UTIL_H_ #pragma once +#include <string> + #include "base/basictypes.h" #include "base/message_loop.h" #include "base/ref_counted.h" @@ -13,14 +15,14 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/search_engines/template_url_model_observer.h" -#include <string> - class TemplateURLModel; class TemplateURLModelTestingProfile; class TestingTemplateURLModel; class TestingProfile; class WebDataService; +// Implements functionality to make it easier to test TemplateURLModel and +// make changes to it. class TemplateURLModelTestUtil : public TemplateURLModelObserver { public: TemplateURLModelTestUtil(); |