diff options
author | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-11 22:58:20 +0000 |
---|---|---|
committer | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-11 22:58:20 +0000 |
commit | 2de7e004b9e0cede80a1955d99d01a1e484182d9 (patch) | |
tree | b557dd9dec9b168190d96521c8e5d028f576b0b6 | |
parent | 13287f25a7562744b3570c2bc6ab9f329f35e239 (diff) | |
download | chromium_src-2de7e004b9e0cede80a1955d99d01a1e484182d9.zip chromium_src-2de7e004b9e0cede80a1955d99d01a1e484182d9.tar.gz chromium_src-2de7e004b9e0cede80a1955d99d01a1e484182d9.tar.bz2 |
Wire up InstallSearchProvider to allow setting the default search provider.
Depends on http://codereview.chromium.org/3673002/show.
BUG=38475
TEST=Next patch changes the callback mechanism TemplateURLFetcher to make it much more testable and adds tests. (I kept it out of this one to make this more focused.)
Review URL: http://codereview.chromium.org/3652003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62204 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 304 insertions, 78 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 708e77a..70eb5c9 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1504,9 +1504,11 @@ void RenderViewHost::OnTakeFocus(bool reverse) { view->TakeFocus(reverse); } -void RenderViewHost::OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, - bool autodetected) { - delegate_->PageHasOSDD(this, page_id, doc_url, autodetected); +void RenderViewHost::OnMsgPageHasOSDD( + int32 page_id, + const GURL& doc_url, + const ViewHostMsg_PageHasOSDD_Type& provider_type) { + delegate_->PageHasOSDD(this, page_id, doc_url, provider_type); } void RenderViewHost::OnDidGetPrintedPagesCount(int cookie, int number_pages) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index b83ccce..c750b0f 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -40,6 +40,7 @@ struct ThumbnailScore; struct ViewHostMsg_AccessibilityNotification_Params; struct ViewHostMsg_DidPrintPage_Params; struct ViewHostMsg_DomMessage_Params; +struct ViewHostMsg_PageHasOSDD_Type; struct ViewHostMsg_RunFileChooser_Params; struct ViewHostMsg_ShowNotification_Params; struct ViewMsg_Navigate_Params; @@ -612,7 +613,9 @@ class RenderViewHost : public RenderWidgetHost { const gfx::Point& image_offset); void OnUpdateDragCursor(WebKit::WebDragOperation drag_operation); void OnTakeFocus(bool reverse); - void OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, bool autodetected); + void OnMsgPageHasOSDD(int32 page_id, + const GURL& doc_url, + const ViewHostMsg_PageHasOSDD_Type& provider_type); void OnDidGetPrintedPagesCount(int cookie, int number_pages); void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params); void OnAddMessageToConsole(const std::wstring& message, diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 358d8fd..64022e3 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -47,6 +47,7 @@ struct ThumbnailScore; struct ViewHostMsg_DidPrintPage_Params; struct ViewHostMsg_DomMessage_Params; struct ViewHostMsg_FrameNavigate_Params; +struct ViewHostMsg_PageHasOSDD_Type; struct ViewHostMsg_RunFileChooser_Params; struct WebDropData; class WebKeyboardEvent; @@ -790,7 +791,7 @@ class RenderViewHostDelegate { // Notification that the page has an OpenSearch description document. virtual void PageHasOSDD(RenderViewHost* render_view_host, int32 page_id, const GURL& doc_url, - bool autodetected) {} + const ViewHostMsg_PageHasOSDD_Type& provider_type) {} // |url| is assigned to a server that can provide alternate error pages. If // the returned URL is empty, the default error page built into WebKit will diff --git a/chrome/browser/search_engines/keyword_editor_controller.cc b/chrome/browser/search_engines/keyword_editor_controller.cc index ac7d636..4755bc9 100644 --- a/chrome/browser/search_engines/keyword_editor_controller.cc +++ b/chrome/browser/search_engines/keyword_editor_controller.cc @@ -84,10 +84,7 @@ bool KeywordEditorController::CanEdit(const TemplateURL* url) const { } bool KeywordEditorController::CanMakeDefault(const TemplateURL* url) const { - return (url != url_model()->GetDefaultSearchProvider() && - url->url() && - url->url()->SupportsReplacement() && - !url_model()->is_default_search_managed()); + return url_model()->CanMakeDefault(url); } bool KeywordEditorController::CanRemove(const TemplateURL* url) const { diff --git a/chrome/browser/search_engines/template_url_fetcher.cc b/chrome/browser/search_engines/template_url_fetcher.cc index e6ab568..0a7f352 100644 --- a/chrome/browser/search_engines/template_url_fetcher.cc +++ b/chrome/browser/search_engines/template_url_fetcher.cc @@ -27,14 +27,14 @@ class TemplateURLFetcher::RequestDelegate : public URLFetcher::Delegate, const GURL& osdd_url, const GURL& favicon_url, TabContents* source, - bool autodetected) + ProviderType provider_type) : ALLOW_THIS_IN_INITIALIZER_LIST(url_fetcher_(osdd_url, URLFetcher::GET, this)), fetcher_(fetcher), keyword_(keyword), osdd_url_(osdd_url), favicon_url_(favicon_url), - autodetected_(autodetected), + provider_type_(provider_type), source_(source) { url_fetcher_.set_request_context(fetcher->profile()->GetRequestContext()); url_fetcher_.Start(); @@ -68,6 +68,9 @@ class TemplateURLFetcher::RequestDelegate : public URLFetcher::Delegate, // Keyword to use. const std::wstring keyword() const { return keyword_; } + // The type of search provider being fetched. + ProviderType provider_type() const { return provider_type_; } + private: void AddSearchProvider(); @@ -77,7 +80,7 @@ class TemplateURLFetcher::RequestDelegate : public URLFetcher::Delegate, std::wstring keyword_; const GURL osdd_url_; const GURL favicon_url_; - bool autodetected_; + const ProviderType provider_type_; // The TabContents where this request originated. Can be NULL if the // originating tab is closed. If NULL, the engine is not added. @@ -123,7 +126,7 @@ void TemplateURLFetcher::RequestDelegate::OnURLFetchComplete( void TemplateURLFetcher::RequestDelegate::AddSearchProvider() { DCHECK(template_url_.get()); - if (!autodetected_ || keyword_.empty()) { + if (provider_type_ != AUTODETECTED_PROVIDER || keyword_.empty()) { // Generate new keyword from URL in OSDD for none autodetected case. // Previous keyword was generated from URL where OSDD was placed and // it gives wrong result when OSDD is located on third party site that @@ -140,7 +143,7 @@ void TemplateURLFetcher::RequestDelegate::AddSearchProvider() { !model || !model->loaded() || !model->CanReplaceKeyword(keyword_, GURL(template_url_->url()->url()), &existing_url)) { - if (autodetected_ || !model || !model->loaded()) { + if (provider_type_ == AUTODETECTED_PROVIDER || !model || !model->loaded()) { fetcher_->RequestCompleted(this); // WARNING: RequestCompleted deletes us. return; @@ -166,20 +169,34 @@ void TemplateURLFetcher::RequestDelegate::AddSearchProvider() { if (!template_url_->GetFavIconURL().is_valid()) template_url_->SetFavIconURL(favicon_url_); - if (autodetected_) { - // Mark the keyword as replaceable so it can be removed if necessary. - template_url_->set_safe_for_autoreplace(true); - model->Add(template_url_.release()); - } else if (source_ && source_->delegate()) { - // Confirm addition and allow user to edit default choices. It's ironic - // that only *non*-autodetected additions get confirmed, but the user - // expects feedback that his action did something. - // The source TabContents' delegate takes care of adding the URL to the - // model, which takes ownership, or of deleting it if the add is - // cancelled. - source_->delegate()->ConfirmAddSearchProvider(template_url_.release(), - fetcher_->profile()); + switch (provider_type_) { + case AUTODETECTED_PROVIDER: + // Mark the keyword as replaceable so it can be removed if necessary. + template_url_->set_safe_for_autoreplace(true); + model->Add(template_url_.release()); + break; + + case EXPLICIT_PROVIDER: + if (source_ && source_->delegate()) { + // Confirm addition and allow user to edit default choices. It's ironic + // that only *non*-autodetected additions get confirmed, but the user + // expects feedback that his action did something. + // The source TabContents' delegate takes care of adding the URL to the + // model, which takes ownership, or of deleting it if the add is + // cancelled. + source_->delegate()->ConfirmAddSearchProvider(template_url_.release(), + fetcher_->profile()); + } + break; + + case EXPLICIT_DEFAULT_PROVIDER: + source_->delegate()->ConfirmSetDefaultSearchProvider( + source_, + template_url_.release(), + model); + break; } + fetcher_->RequestCompleted(this); // WARNING: RequestCompleted deletes us. } @@ -197,18 +214,25 @@ void TemplateURLFetcher::ScheduleDownload(const std::wstring& keyword, const GURL& osdd_url, const GURL& favicon_url, TabContents* source, - bool autodetected) { + ProviderType provider_type) { DCHECK(!keyword.empty() && osdd_url.is_valid()); + // Make sure we aren't already downloading this request. for (std::vector<RequestDelegate*>::iterator i = requests_->begin(); i != requests_->end(); ++i) { - if ((*i)->url() == osdd_url || (*i)->keyword() == keyword) + bool keyword_or_osdd_match = (*i)->url() == osdd_url || + (*i)->keyword() == keyword; + bool same_type_or_neither_is_default = + (*i)->provider_type() == provider_type || + ((*i)->provider_type() != EXPLICIT_DEFAULT_PROVIDER && + provider_type != EXPLICIT_DEFAULT_PROVIDER); + if (keyword_or_osdd_match && same_type_or_neither_is_default) return; } requests_->push_back( new RequestDelegate(this, keyword, osdd_url, favicon_url, source, - autodetected)); + provider_type)); } void TemplateURLFetcher::RequestCompleted(RequestDelegate* request) { diff --git a/chrome/browser/search_engines/template_url_fetcher.h b/chrome/browser/search_engines/template_url_fetcher.h index e773890..c254946 100644 --- a/chrome/browser/search_engines/template_url_fetcher.h +++ b/chrome/browser/search_engines/template_url_fetcher.h @@ -20,6 +20,12 @@ class TabContents; // class TemplateURLFetcher { public: + enum ProviderType { + AUTODETECTED_PROVIDER, + EXPLICIT_PROVIDER, // Supplied by Javascript. + EXPLICIT_DEFAULT_PROVIDER // Supplied by Javascript as default provider. + }; + // Creates a TemplateURLFetcher with the specified Profile. explicit TemplateURLFetcher(Profile* profile); ~TemplateURLFetcher(); @@ -31,7 +37,10 @@ class TemplateURLFetcher { const GURL& osdd_url, const GURL& favicon_url, TabContents* source, - bool autodetected); + ProviderType provider_type); + + // The current number of outstanding requests. + int requests_count() const { return requests_->size(); } private: friend class RequestDelegate; diff --git a/chrome/browser/search_engines/template_url_fetcher_unittest.cc b/chrome/browser/search_engines/template_url_fetcher_unittest.cc index 2b4d38eb..57bb88c 100644 --- a/chrome/browser/search_engines/template_url_fetcher_unittest.cc +++ b/chrome/browser/search_engines/template_url_fetcher_unittest.cc @@ -65,6 +65,15 @@ class TemplateURLFetcherTest : public testing::Test { } protected: + // Schedules the download of the url. + void StartDownload(const std::wstring& keyword, + const std::string& osdd_file_name, + TemplateURLFetcher::ProviderType provider_type, + bool check_that_file_exists); + + // Waits for any downloads to finish. + void WaitForDownloadToFinish(); + TemplateURLModelTestUtil test_util_; net::TestServer test_server_; @@ -77,6 +86,33 @@ TemplateURLFetcherTest::TemplateURLFetcherTest() FilePath(FILE_PATH_LITERAL("chrome/test/data"))) { } +void TemplateURLFetcherTest::StartDownload( + const std::wstring& keyword, + const std::string& osdd_file_name, + TemplateURLFetcher::ProviderType provider_type, + bool check_that_file_exists) { + + if (check_that_file_exists) { + FilePath osdd_full_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path)); + osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name); + ASSERT_TRUE(file_util::PathExists(osdd_full_path)); + ASSERT_FALSE(file_util::DirectoryExists(osdd_full_path)); + } + + // Start the fetch. + GURL osdd_url = test_server_.GetURL("files/" + osdd_file_name); + GURL favicon_url; + test_util_.profile()->GetTemplateURLFetcher()->ScheduleDownload( + keyword, osdd_url, favicon_url, NULL, provider_type); + ASSERT_EQ(1, test_util_.profile()->GetTemplateURLFetcher()->requests_count()); +} + +void TemplateURLFetcherTest::WaitForDownloadToFinish() { + QuitOnChangedObserver quit_on_changed_observer(test_util_.model()); + MessageLoop::current()->Run(); +} + TEST_F(TemplateURLFetcherTest, BasicTest) { std::wstring keyword(L"test"); @@ -85,24 +121,9 @@ TEST_F(TemplateURLFetcherTest, BasicTest) { ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); - - // Verify that the file exists. - FilePath osdd_full_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path)); - osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name); - ASSERT_TRUE(file_util::PathExists(osdd_full_path)); - ASSERT_FALSE(file_util::DirectoryExists(osdd_full_path)); - - // Start the fetch. - GURL osdd_url = test_server_.GetURL("files/" + osdd_file_name); - GURL favicon_url; - test_util_.profile()->GetTemplateURLFetcher()->ScheduleDownload( - keyword, osdd_url, favicon_url, NULL, true); - - { // Wait for the url to be downloaded. - QuitOnChangedObserver quit_on_changed_observer(test_util_.model()); - MessageLoop::current()->Run(); - } + StartDownload(keyword, osdd_file_name, + TemplateURLFetcher::AUTODETECTED_PROVIDER, true); + WaitForDownloadToFinish(); const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword( keyword); @@ -112,3 +133,41 @@ TEST_F(TemplateURLFetcherTest, BasicTest) { EXPECT_EQ(true, t_url->safe_for_autoreplace()); } +TEST_F(TemplateURLFetcherTest, DuplicateThrownAway) { + std::wstring keyword(L"test"); + + test_util_.ChangeModelToLoadState(); + test_util_.ResetObserverCount(); + ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); + + std::string osdd_file_name("simple_open_search.xml"); + StartDownload(keyword, osdd_file_name, + TemplateURLFetcher::AUTODETECTED_PROVIDER, true); + + struct { + std::string description; + std::string osdd_file_name; + std::wstring keyword; + TemplateURLFetcher::ProviderType provider_type; + } test_cases[] = { + { "Duplicate keyword and osdd url with autodetected provider.", + osdd_file_name, keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER }, + { "Duplicate keyword and osdd url with explicit provider.", + osdd_file_name, keyword, TemplateURLFetcher::EXPLICIT_PROVIDER }, + { "Duplicate osdd url with explicit provider.", + osdd_file_name, keyword + L"1", TemplateURLFetcher::EXPLICIT_PROVIDER }, + { "Duplicate keyword with explicit provider.", + osdd_file_name + "1", keyword, TemplateURLFetcher::EXPLICIT_PROVIDER } + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { + StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name, + test_cases[i].provider_type, false); + ASSERT_EQ( + 1, + test_util_.profile()->GetTemplateURLFetcher()->requests_count()) << + test_cases[i].description; + } + + WaitForDownloadToFinish(); +} diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc index 043633c..aa543fb 100644 --- a/chrome/browser/search_engines/template_url_model.cc +++ b/chrome/browser/search_engines/template_url_model.cc @@ -390,6 +390,13 @@ void TemplateURLModel::ResetTemplateURL(const TemplateURL* url, NotifyObservers(); } +bool TemplateURLModel::CanMakeDefault(const TemplateURL* url) { + return url != GetDefaultSearchProvider() && + url->url() && + url->url()->SupportsReplacement() && + !is_default_search_managed(); +} + void TemplateURLModel::SetDefaultSearchProvider(const TemplateURL* url) { if (is_default_search_managed_) { NOTREACHED(); diff --git a/chrome/browser/search_engines/template_url_model.h b/chrome/browser/search_engines/template_url_model.h index 81cc3bb..ce9a874 100644 --- a/chrome/browser/search_engines/template_url_model.h +++ b/chrome/browser/search_engines/template_url_model.h @@ -171,9 +171,7 @@ class TemplateURLModel : public WebDataServiceConsumer, const std::string& search_url); // Return true if the given |url| can be made the default. - // TODO(levin): Fill in. This is just a placeholder to make the dialog change - // more independent from other changes. - bool CanMakeDefault(const TemplateURL* url) const { return true; } + bool CanMakeDefault(const TemplateURL* url); // Set the default search provider. |url| may be null. // This will assert if the default search is managed; the UI should not be diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 2a7bbd0..7ee3427 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -2758,9 +2758,11 @@ void TabContents::PasswordFormsVisible( // Checks to see if we should generate a keyword based on the OSDD, and if // necessary uses TemplateURLFetcher to download the OSDD and create a keyword. -void TabContents::PageHasOSDD(RenderViewHost* render_view_host, - int32 page_id, const GURL& url, - bool autodetected) { +void TabContents::PageHasOSDD( + RenderViewHost* render_view_host, + int32 page_id, + const GURL& url, + const ViewHostMsg_PageHasOSDD_Type& msg_provider_type) { // Make sure page_id is the current page, and the TemplateURLModel is loaded. DCHECK(url.is_valid()); if (!IsActiveEntry(page_id)) @@ -2778,6 +2780,25 @@ void TabContents::PageHasOSDD(RenderViewHost* render_view_host, if (profile()->IsOffTheRecord()) return; + TemplateURLFetcher::ProviderType provider_type; + switch (msg_provider_type.type) { + case ViewHostMsg_PageHasOSDD_Type::AUTODETECTED_PROVIDER: + provider_type = TemplateURLFetcher::AUTODETECTED_PROVIDER; + break; + + case ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER: + provider_type = TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER; + break; + + case ViewHostMsg_PageHasOSDD_Type::EXPLICIT_PROVIDER: + provider_type = TemplateURLFetcher::EXPLICIT_PROVIDER; + break; + + default: + NOTREACHED(); + return; + } + const NavigationEntry* entry = controller_.GetLastCommittedEntry(); DCHECK(entry); @@ -2802,6 +2823,9 @@ void TabContents::PageHasOSDD(RenderViewHost* render_view_host, base_entry->user_typed_url() : base_entry->url(); if (!keyword_url.is_valid()) return; + + bool autodetected = + provider_type == TemplateURLFetcher::AUTODETECTED_PROVIDER; std::wstring keyword = TemplateURLModel::GenerateKeyword(keyword_url, autodetected); @@ -2825,7 +2849,7 @@ void TabContents::PageHasOSDD(RenderViewHost* render_view_host, url, base_entry->favicon().url(), this, - autodetected); + provider_type); } GURL TabContents::GetAlternateErrorPageURL() const { diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index f770c42..8abf45e 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -968,7 +968,9 @@ class TabContents : public PageNavigator, virtual void PasswordFormsVisible( const std::vector<webkit_glue::PasswordForm>& visible_forms); virtual void PageHasOSDD(RenderViewHost* render_view_host, - int32 page_id, const GURL& url, bool autodetected); + int32 page_id, + const GURL& url, + const ViewHostMsg_PageHasOSDD_Type& provider_type); virtual GURL GetAlternateErrorPageURL() const; virtual RendererPreferences GetRendererPrefs(Profile* profile) const; virtual WebPreferences GetWebkitPrefs(); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index ea5d47c..29d50e0 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -83,6 +83,7 @@ struct ViewMsg_Navigate_Params; struct ViewMsg_AudioStreamState_Params; struct ViewMsg_StopFinding_Params; struct ViewHostMsg_GetSearchProviderInstallState_Params; +struct ViewHostMsg_PageHasOSDD_Type; struct ViewHostMsg_FrameNavigate_Params; struct ViewHostMsg_UpdateRect_Params; struct ViewMsg_ClosePage_Params; diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index ae93fe4..b30be05 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1690,7 +1690,7 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_ROUTED3(ViewHostMsg_PageHasOSDD, int32 /* page_id */, GURL /* url of OS description document */, - bool /* autodetected */) + ViewHostMsg_PageHasOSDD_Type) // Find out if the given url's security origin is installed as a search // provider. diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc index b9435b6..6729ee2 100644 --- a/chrome/common/render_messages_params.cc +++ b/chrome/common/render_messages_params.cc @@ -672,6 +672,41 @@ void ParamTraits<ViewMsg_StopFinding_Params>::Log(const param_type& p, LogParam(action, l); } +void ParamTraits<ViewHostMsg_PageHasOSDD_Type>::Write(Message* m, + const param_type& p) { + m->WriteInt(p.type); +} + +bool ParamTraits<ViewHostMsg_PageHasOSDD_Type>::Read(const Message* m, + void** iter, + param_type* p) { + int type; + if (!m->ReadInt(iter, &type)) + return false; + p->type = static_cast<param_type::Type>(type); + return true; +} + +void ParamTraits<ViewHostMsg_PageHasOSDD_Type>::Log(const param_type& p, + std::string* l) { + std::string type; + switch (p.type) { + case ViewHostMsg_PageHasOSDD_Type::AUTODETECTED_PROVIDER: + type = "ViewHostMsg_PageHasOSDD_Type::AUTODETECTED_PROVIDER"; + break; + case ViewHostMsg_PageHasOSDD_Type::EXPLICIT_PROVIDER: + type = "ViewHostMsg_PageHasOSDD_Type::EXPLICIT_PROVIDER"; + break; + case ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER: + type = "ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER"; + break; + default: + type = "UNKNOWN"; + break; + } + LogParam(type, l); +} + void ParamTraits<ViewHostMsg_GetSearchProviderInstallState_Params>::Write( Message* m, const param_type& p) { m->WriteInt(p.state); diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h index a64d5fa..bb3ab81f 100644 --- a/chrome/common/render_messages_params.h +++ b/chrome/common/render_messages_params.h @@ -144,6 +144,42 @@ struct ViewMsg_StopFinding_Params { Action action; }; +// The type of OSDD that the renderer is giving to the browser. +struct ViewHostMsg_PageHasOSDD_Type { + enum Type { + // The Open Search Description URL was detected automatically. + AUTODETECTED_PROVIDER, + + // The Open Search Description URL was given by Javascript. + EXPLICIT_PROVIDER, + + // The Open Search Description URL was given by Javascript to be the new + // default search engine. + EXPLICIT_DEFAULT_PROVIDER + }; + + Type type; + + ViewHostMsg_PageHasOSDD_Type() : type(AUTODETECTED_PROVIDER) { + } + + explicit ViewHostMsg_PageHasOSDD_Type(Type t) + : type(t) { + } + + static ViewHostMsg_PageHasOSDD_Type Autodetected() { + return ViewHostMsg_PageHasOSDD_Type(AUTODETECTED_PROVIDER); + } + + static ViewHostMsg_PageHasOSDD_Type Explicit() { + return ViewHostMsg_PageHasOSDD_Type(EXPLICIT_PROVIDER); + } + + static ViewHostMsg_PageHasOSDD_Type ExplicitDefault() { + return ViewHostMsg_PageHasOSDD_Type(EXPLICIT_DEFAULT_PROVIDER); + } +}; + // The install state of the search provider (not installed, installed, default). struct ViewHostMsg_GetSearchProviderInstallState_Params { enum State { @@ -1036,6 +1072,14 @@ struct ParamTraits<ViewMsg_StopFinding_Params> { }; template <> +struct ParamTraits<ViewHostMsg_PageHasOSDD_Type> { + typedef ViewHostMsg_PageHasOSDD_Type param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> struct ParamTraits<ViewHostMsg_GetSearchProviderInstallState_Params> { typedef ViewHostMsg_GetSearchProviderInstallState_Params param_type; static void Write(Message* m, const param_type& p); diff --git a/chrome/renderer/external_extension.cc b/chrome/renderer/external_extension.cc index f2c3246..a34b6a4 100644 --- a/chrome/renderer/external_extension.cc +++ b/chrome/renderer/external_extension.cc @@ -16,18 +16,23 @@ using WebKit::WebView; namespace extensions_v8 { -#define SEARCH_PROVIDER_API_V1 \ - "var external;" \ - "if (!external)" \ - " external = {};" \ - "external.AddSearchProvider = function(name) {" \ - " native function NativeAddSearchProvider();" \ - " NativeAddSearchProvider(name);" \ - "};" - -static const char* const kSearchProviderApiV1 = SEARCH_PROVIDER_API_V1; +static const char* const kSearchProviderApiV1 = + "var external;" + "if (!external)" + " external = {};" + "external.AddSearchProvider = function(name) {" + " native function NativeAddSearchProvider();" + " NativeAddSearchProvider(name);" + "};"; + static const char* const kSearchProviderApiV2 = - SEARCH_PROVIDER_API_V1 + "var external;" + "if (!external)" + " external = {};" + "external.AddSearchProvider = function(name, default_provider) {" + " native function NativeAddSearchProvider();" + " NativeAddSearchProvider(name, default_provider);" + "};" "external.IsSearchProviderInstalled = function(name) {" " native function NativeIsSearchProviderInstalled();" " return NativeIsSearchProviderInstalled(name);" @@ -107,10 +112,15 @@ v8::Handle<v8::Value> ExternalExtensionWrapper::AddSearchProvider( std::string name = std::string(*v8::String::Utf8Value(args[0])); if (!name.length()) return v8::Undefined(); + ViewHostMsg_PageHasOSDD_Type provider_type = + ((args.Length() < 2) || !args[1]->BooleanValue()) ? + ViewHostMsg_PageHasOSDD_Type::Explicit() : + ViewHostMsg_PageHasOSDD_Type::ExplicitDefault(); + RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); - render_view->AddSearchProvider(name); + render_view->AddSearchProvider(name, provider_type); return v8::Undefined(); } diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 0d9c1bf..2673947 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -1616,10 +1616,12 @@ bool RenderView::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) { return Send(message); } -void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) { +void RenderView::AddGURLSearchProvider( + const GURL& osd_url, + const ViewHostMsg_PageHasOSDD_Type& provider_type) { if (!osd_url.is_empty()) Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url, - autodetected)); + provider_type)); } void RenderView::OnAutoFillSuggestionsReturned( @@ -1647,9 +1649,15 @@ uint32 RenderView::GetCPBrowsingContext() { return context; } -void RenderView::AddSearchProvider(const std::string& url) { - AddGURLSearchProvider(GURL(url), - false); // not autodetected +void RenderView::AddSearchProvider( + const std::string& url, + const ViewHostMsg_PageHasOSDD_Type& provider_type) { + if (provider_type.type == + ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER && + !webview()->mainFrame()->isProcessingUserGesture()) + return; + + AddGURLSearchProvider(GURL(url), provider_type); } ViewHostMsg_GetSearchProviderInstallState_Params @@ -1839,7 +1847,7 @@ void RenderView::didStopLoading() { Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url)); AddGURLSearchProvider(webview()->mainFrame()->openSearchDescriptionURL(), - true); // autodetected + ViewHostMsg_PageHasOSDD_Type::Autodetected()); Send(new ViewHostMsg_DidStopLoading(routing_id_)); diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index a7de84b..3124c98 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -221,7 +221,8 @@ class RenderView : public RenderWidget, // Called from JavaScript window.external.AddSearchProvider() to add a // keyword for a provider described in the given OpenSearch document. - void AddSearchProvider(const std::string& url); + void AddSearchProvider(const std::string& url, + const ViewHostMsg_PageHasOSDD_Type& provider_type); // Returns the install state for the given search provider url. ViewHostMsg_GetSearchProviderInstallState_Params @@ -724,7 +725,8 @@ class RenderView : public RenderWidget, // Adds search provider from the given OpenSearch description URL as a // keyword search. - void AddGURLSearchProvider(const GURL& osd_url, bool autodetected); + void AddGURLSearchProvider(const GURL& osd_url, + const ViewHostMsg_PageHasOSDD_Type& provider_type); // Called in a posted task by textFieldDidChange() to work-around a WebKit bug // http://bugs.webkit.org/show_bug.cgi?id=16976 |