summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/search_engines/search_provider_install_data.cc121
-rw-r--r--chrome/browser/search_engines/search_provider_install_data.h33
-rw-r--r--chrome/browser/search_engines/search_provider_install_data_unittest.cc54
-rw-r--r--chrome/browser/search_engines/template_url_model_test_util.h6
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();